
中间件是解决共性问题的标准化工具,是一种支撑技术,不可或缺。但因其种类多,数量大的特性,给运维管理带来了很高的难度。本次分享将介绍基于 Kubernetes 构建的云原生中间件平台架构,介绍 kubebuilder 的脚手架构建流程,以及 Operator 的工作原理.并以数据库为例,介绍在实际推进的场景中遇到的问题与解决方案,同时也分享云原生中间件面临的挑战的思考与对未来的展望。
分享主要分为四个部分展开:第一部分中间件管理现状;第二部分借助云原⽣优势,提供更好的管理;第三部分云中间件管理平台架构之路;第四部分未来展望。
本文整理自金蝶云苍穹云原生部门高级研发李仲玄、金蝶云苍穹云原生部门产品经理徐瑛在DIVE全球基础软件创新大会2022的演讲分享,主题为“金蝶云苍穹云中间件管理架构实践”。
以下为整理内容:
中间件管理现状
中间件是为了解决复杂问题的支撑技术,在一般的软件架构中是不可或缺的一部分。它是研发利器,其定义非常广泛,包含非常多种类型,常见的包括像数据库中间件、消息队列中间件,还有微服务组件中间件,可见中间件的特征是种类非常的多,涵盖范围非常广,数量也非常大,这就给我们的管理上增加了难度。
中间件常用的管理方式主要有四种,分别是混合云、公有云、私有云和本地管理。这四种管理方式各有优劣,像本地安装包管理方式,它可以使用本地物理资源降低成本,但运维都是纯人工的,通常都是直接使用运维脚本,运维门槛就比较高,并且人工出错的概率比较大,整体运维效率会比较低。
第二种私有云方式是建设一朵私有云,把整个中间件的资源和运维都给管理起来,其劣势在于,需要专项投入建设。
第三种公有云方式是把需要的资源和运维能力完全托管到公有云厂商,我们可以减少运维和资源管理这部分的麻烦,但是会和公有云厂商深入绑定,整个运维状况不是很透明,不是很了解底层到底是怎么样的运维状态。
第四种是混合云方式,目的是希望能够将资源分布在多种云上,以降低整体的风险,其劣势在于统一管理比较难。
上述四种管理方式共同的担忧主要分为两大类,一类是运维管理,一类是成本控制。运维管理主要围绕着可用性、可靠性、性能优化这几类问题。而资源缺乏、人员配备的问题,都属于成本控制类的问题。
解决这些担忧的最终目的是要降本增效,我们认为可以有以下四点去达到这个目的:
第一点是拒绝资源绑定,采用松耦合的架构去屏蔽底层资源差异,从而降低成本,分担风险;
第二点是资源池能够弹性扩缩,根据不同时期的业务需求进行整体的扩缩容,去满足我们的业务需求;
第三点是运维操作要简单,做到可视化的部署、容灾、监控分析、告警全生命周期的运维管理;
第四点是高可用、高可靠的保障。


上述说的这几点,我们运用云原生都能很好地解决。
第一点松耦合,它刚好与容器契合,将中间件本身、应用和它的配置打包成镜像,能在不同的资源池上进行,不同的环境上部署,通过容器编排工具可以根据申请的资源在资源池中选择合适的节点调度、部署,轻松实现多实例面向混合资源池的部署。
第二点弹性扩缩,它主要分为两类,一类是资源池的弹性扩缩,另一类是中间件自身利用的弹性扩缩。基于资源池的弹性扩缩,使用计算存储分离架构,我们可以去实现计算资源和存储资源独立灵活的扩缩容,去满足我们实际的业务需求。基于中间件应用,也可按需实现中间件规格的扩缩容。这两种弹性扩缩,我们都可以通过容器编排工具实现。
第三点是运维操作简单,需要具备快速发布部署、中间件的管理、异地容灾整个生命周期的可视化界面管理。基于容器中间件,自身就具有快速部署和发布的能力,能够自动隔离故障结点,将应用迁移至健康的结点,让整个应用系统具有比较强的资源能力,简化运维管理的复杂度。
最后一点是可观测性,它不仅是中间件运维平台能力,还是所有运维平台都需要的能力,它就包含监控、日志、告警等等一系列的内容。云原生本身就有比较成熟的可观测服务工具。

中间件本身是一个比较复杂的系统,运维也比较烦琐,部署、故障恢复、监控、报警、测试都需要比较专业的运维人员手动完成,不仅成本比较高,而且也可能会出现手工失误。将中间件做成云服务的优势是运维简单容易上手,能够高效实现大批量实例的自动化运维。我们主要是一个三到六台的小规模的 K8S 集群,主要分为 Master 节点跟 Node 节点,Master 节点是集群的控制节点,负责整个集群的管理和控制,基本上所有的控制指令都是发给 Master,并且由他来调度 Node 具体的执行命令。Node 节点是工作负载节点,主要负责拉取容器。
我们使用的是声明式 API,只给出最终的状态,通过状态机去协调,目标系统就会对资源进行操作以达到要求,调用者不需任何干预。其优势是让分布式系统之间的交付变得简单,不需要关心任何过程细节,这种方式也大大减少了使用者的工作量,极大地提升开发效率。

Kubernetes 现在已经是比较流行的云原生分布式操作系统,其最大的优势就在于拓展性,比如计算、存储、网络都可以根据使用者的需求进行拓展,另一个重要的拓展是 CRD 特性,通过 Custom Resource Definition 开发者可以定义自己的资源,对应的 Operator 来实现自身的控制逻辑。CRD 本质就是一个 YAML 文件,需要我们自己去写,写完之后再通过 Operator 去控制,Operator 也需要我们自己去写,将我们对中间件的理解、实践全部结合在一起,实现自动化的、可自我恢复的、可自我调节的功能。CR 是该 CRD 定义的一个具体实际对象,根据我们自己的资源需求去实现。

以前开发 Operator 需要开发者实现对资源的监听,对资源事件的队列化,以及后面整套控制逻辑,比较繁琐。正因为如此,市面上出现了多款的开发 Operator 的脚手架,比较常见的有 Operator SDK 和 Kubebuilder。Kubebuilder 是 Kubernetes SIG 官方团队原生打造的,它相对使用起来会比较简单,按如图步骤即可实现整个生命周期。

如图是 Operator 的主要架构,我们只要实现 Reconciler 这个函数,Kubebuilder 帮助我们实现了大部分的功能。它遵从声明式编程理念,对象定义、控制器部署、Kubebuilder 生成的代码、自动生成的 Scheme、Kubernetes 原生资源都会储存到我们自定义的 CRD。GVK 是资源种类的描述,一个 JKV 只会存在一个对应的 Share informer,主要监听对应资源的创建、仓储、更新操作,通知所有 Watch,Controller 将对应的资源对象都添加到一个队列里面,最终触发到开发者的调和程序,即 Reconcile 函数,里面主要是我们要做的运维。这里需要遵守很多 Kubernetes 规范,比如针对 Kubernetes 标准的 Resource 使用编排,统一叫声明式调度,不需要自己操作,让 Kubernetes 帮你去部署。
我们在实际使用中会出现了一些问题,我们总结了四个问题:
第一个是过于自动化,比如自动主动切换类型,导致他们自己都无法感知到,害怕主从切换过程中会丢失数据;
第二个是持久化存储的选择,之前我们优先考虑使用分布式存储,因为可以比较灵活,但是经过测试发现速度没办法达到预期,所以最终选择本地存储;
第三个是需要更快的启动,比如需要快速测试;
第四个是可以恢复数据、备份数据。
下面介绍我们的五个功能实践。
第一个是添加手动主从切换,一开始使用自动化的主从切换,但是自动化主从切换有些弊端,因为基于异步复制,自动切换可能在主机宕机的时候会丢失数据,所以增加了一个手动主从切换的特性,让用户更安心。
第二个是纳管物理机数据库,为什么我们要使用纳管物理机?因为大部分老客户都是用物理机来部署 MySQL 的,直接让他们使用容器化,他们会有所顾虑,为了打消他们的顾虑,我们认为需要提供一种过度性的方案,让他们既能尝试又不影响现在的服务。
第三个是兼容带数据的镜像,有一个测试平台想通过镜像的方式快速启动。我们在容器创建之前加入了一个 init 程序,通过这个 init 程序将镜像里面的数据拷贝到持久化存储 PV,当 MySQL 容器真正启动的时候自动挂载到 PV,它就会有镜像里面的数据从而不会被覆盖掉。
第四个是针对于用户在使用过程中需要修改密码,我们中间添加了一个 MySQL 的 User CRD,等于 root 这个账户由 Operator 统一使用,用户用自己定义的账户,当 MySQL User 创建完后,就会产生一个对象,Operator 检测到,把这个 User 里的账户密码插入到数据库里,这样对多个用户的 User 进行管理,也可以做用户的级别分级,回收了 root 账户的功能。
第五个是定时备份数据,我们一开始使用的是全量备份,但定时做全量备份花费的时间会比较长,并且占用的空间也比较浪费。于是我们增加了增量的数据恢复,这需要先有个全量的数据,基于它绑定增量备份时间点和增量数据的位置,要恢复某个时间点的时候,就先去恢复全量的数据,通过时间绑定的位置恢复增量数据。
我们后续还会迎接一些挑战,这些挑战主要集中在以下四个方面:
容器稳定性
客户信任度
兼容更轻量的容器编排引擎
更完善的监控系统
未来展望
云计算是一个发展方向,是将业务无关的管理功能和运维功能尽量下沉到基础设施,应用可以聚焦在业务能力的开发、运营。这个趋势演化过程也影响了云计算的发展方向。从一开始的虚拟化到 IaaS 跟 PaaS,到应用系统的部分管理职责交给平台的运维过程,我们应该重视软件开发人员和运维人员的沟通合作,通过自动化流程使软件构建、测试、发布更加迅速,并且可靠。云原生技术也是目前技术阶段、企业 IT、系统的最佳模式的集合,企业通过遵循云原生技术和设计模式,可以充分发挥云计算平台优势,同时也可以最大限度地减少对开发效率的影响,实现稳定高效的系统。
技术是一个不断发展的一个过程,云计算技术也是一个不断的迭代的过程,相应的开发习惯和方法也会试着改变。
好文推荐:
GitHub 爆赞的 RocketMQ 分布式中间件学习手册,竟一夜下载量破 10W+
一发一存一消费,跟着 p8 大佬深入学习 Java 中间件技术及其应用开发
深度解读|NebulaGraph x 阿里云计算巢,云上构建超大规模图数据库
评论