当前位置: 首页 > 科技观察

多云容器编排Karmada-Operator实践

时间:2023-03-18 21:53:13 科技观察

作者|vivoInternetServerTeam-ZhangRongKarmada作为一个开源的云原生多云容器编排项目,吸引了众多企业参与项目开发并在生产环境运行。同时,多云逐渐成为数据中心建设的基础设施。多区域容灾和多活、大规模多集群管理、跨云弹性和迁移等场景推动了云原生多云相关技术的快速发展。一、背景随着vivo业务不断向k8s迁移,集群规模和集群数量快速增长,运维难度也急剧增加。为了搭建多集群技术,我们也自己开发了多集群管理,但是我们遇到的问题并不能解决更多。后来我们开始对社区相关的项目做详细的调研和测试,最终选择了Karmada。主要原因有:具备多套K8s集群的统一管理能力,业务通过服务维度管理资源,降低容器平台的管理难度。跨集群的弹性伸缩和调度能力,可以合理利用跨集群的资源,从而提高资源利用率,节约成本。Karmada完全使用K8s原生API,改造成本低。容灾,Karmada控制平面与成员集群解耦,支持集群异常时资源重新分配。可扩展性,比如添加自研调度插件和添加自研Openkruise解释器插件等。我们在探索如何使用Karmada的同时,也遇到了Karmada自身运维的问题。社区部署工具有很多,需要用户自己选择。目前用户部署方式如下:hack目录下的KarmadactlKarmadacharts二进制部署脚本针对以上工具,在Karmada社区进行了问卷调查,并生成了统计报告。主要总结如下:社区部署工具较多,需要用户自行选择。部署脚本也有缺陷,需要用户自行解决。github上有很多这方面的问题。黑屏操作,没有提供k8sapi操作,用户难以产品化。我们主要是希望对接我们的容器平台,实现可视化安装。缺少CI测试和部署工具的发布计划。etcd集群缺乏生产环境的关键功能点,如etcd的高可用、定期备份和恢复等。需要安装很多依赖插件,涉及到Karmada控制面、Karmada的宿主机集群和成员集群。缺少一键部署、繁琐配置等痛点。针对以上问题,本文将分享Karmada-Operator的vivo实践,包括Operator的方案选择、API、架构设计、CI构建。2.Karmada-Operator的实现2.1OperatorSDK简介OperatorFramework是一个开源工具包,用于以有效、自动化和可扩展的方式管理Kubernetes原生应用程序,即Operators。Operator利用Kubernetes的可扩展性来提供云服务的自动化优势,例如供应、扩展、备份和恢复,同时能够在Kubernetes可以运行的任何地方运行。Operator有助于简化Kubernetes上复杂的有状态应用程序的管理。然而,今天编写Operators并不容易,面临着使用低级API、编写样板文件和缺乏模块化(这会导致重复工作)等挑战。OperatorSDK是一个框架,它通过提供以下内容来降低编写Operator的难度:用于更直观地编写操作逻辑脚手架的高级API和抽象,以及用于快速引导新项目扩展并涵盖常见Operator使用的代码生成工具,例如,作为如上图所示,operatorsdk可以基于helm、ansilbe、go构建operator,我们需要根据当前情况选择适合自己的operator框架。2.2方案选择方案一:Golang开发Operator方案二:Ansible开发Operator方案三:Golang和ansible混合开发Operator根据Karmada实际生产部署研究情况和vivo自身实践,可以归纳为:支持K8s集群,不支持依赖K8s集群二进制部署。支持外部独立etcd集群部署或与现有etcd集群对接。Karmada集群具有迁移能力,如机房注销、机器故障等,要求etcd集群管理具有备份恢复能力,如根据etcd备份数据快速恢复其他机房的集群。需要支持第三方VIP为Karmada-apiserver提供负载均衡。目前vivo是基于外部VIP,提供域名。K8s服务不用于为Karmada-apiserver提供负载均衡。一键部署Karmada控制面,自动注册和注销成员集群。还需要获取成员集群的kubeconfig,pull模式也需要在成员集群中部署Karmada-agent。Karmada集群中安装addons,如istio、anp、第三方crd等,需要在Karmada控制平面、host主机集群,甚至member集群上进行配置。提供API能力,实现可视化部署。Karmada各个组件的单独升级和全面升级。支持离线和离线模式。面对Karmada如此复杂的条件和局限性,我们来分析一下以上三种方案,究竟哪种更适合。方案一,基于go开发的operator更适合基于k8s集群的有状态服务管理,如etcd、数据库等,etcd-Operator更成熟。Karmada不依赖K8s集群二进制部署,外置etcd,成员集群注册、注销、插件安装,无法很好支持或需要加大开发量。方案二,基于ansible开发的Operator不仅可以管理基于K8s集群的状态服务,还可以独立于K8s集群进行二进制部署、外部etcd、成员集群注册、注销、插件安装等。这主要是通过ansible的ssh登录能力和K8s模块管理。通过研究,我们也发现90%以上的用户都可以提供ssh登录。方案三是基于go+ansible的混合Operator。读者可以阅读vivo基于此方案开发的Kubernetes-Operator。方案三具备方案二的所有能力,因为底层是通过ansible执行的。首先我们排除了方案一,方案二和方案三我也纠结了很久,最后我们选择了方案二。主要原因如下:OperatorSDKansible和OperatorSDKgo具有相同的能力,并提供K8s、K8s_status模块和类似的webhook函数来管理k8s资源和对账能力。满足了Karmada实际生产部署的需要。简单易学,只要知道ansbile的jinja模板和和K8s一样的yaml文件就可以了。你只需要编写ansible任务,开箱即用,对账由OperatorSDK解决。对经常使用ansible的人比较友好,不需要写golang代码。扩展性强,用户可以自定义插件。管理终端还支持本地、ssh和zeromq连接。local模式可以直接连接K8s接口,ssh模式可以登录并执行脚本。可以很好的搭配使用,解决我们目前的需求。Karmada的运维比K8s更简单,不需要复杂的crd定义。Ansible需要解析少量变量来执行剧本。golang+ansible模式更适合CRD定义复杂、业务逻辑复杂的系统。2.3API设计如上图所示,我们只需要执行Operator-SDKcreateapi命令创建KarmadaDeployment的CRD,然后定义KarmadaDeployment的API即可。在watches.yaml中实现Reconcile的业务逻辑。这里主要定义了KarmadaDeployment、EtcdBackup和EtcdRestore资源,分别用于Karmada部署和etcd数据备份恢复。AnsibleOperator将根据规范中的定义被解析为ansiblevars。状态将由ansiblerunner输出为用户定义的状态。KarmadaDeployment的状态也可以通过ansible的k8s_status来更新。目前主要考虑是在K8s上运行Karmada,后面会加入二进制部署方式,目前CR没有涉及。2.4架构设计如图所示,KarmadaOperator提供了容器化和二进制集群部署设计。Karmada的容器化部署无需进行ssh登录,仅通过k8s和k8s_status即可完成对Karmada控制面的管控。Karmada的二进制部署主要通过ssh登录完成对Karmada控制面的管理和控制。成员集群的加入和退出需要提前提供成员集群的kubeconfig文件,也可以设置成员的登录权限操作。您需要在CR中定义成员集群的用户和密钥。执行流程如下。用户通过KarmadaDeployment定义Karmada操作。KarmadaOperator感知到KarmadaDeployment的CR变化,开始进入controller逻辑。根据用户定义,选择容器化部署或二进制部署,开始进行安装、扩容、备份等操作,并进行join/unjoin操作。将成员集群注册到Karmada集群或注销成员集群2.5Karmada控制面管理如上图所示,主要是Karmada控制面的生命周期管理。对比目前社区部署工具,我们优化如下:标准化证书管理,主要使用openssl生成证书。其中etcd和Karmada证书是分开维护的,和k8s集群证书同名,方便我们监控访问。Karmada-apiserver支持外部负载均衡,不局限于当前k8s服务提供的负载均衡。更灵活的升级策略,支持单个组件升级和全量升级。更丰富的全局变量定义,计划支持组件配置变更等。2.6etcd集群管理etcd集群是Karmada的元数据集群,在生产中需要保证etcd集群的高可用和故障恢复。上图展示了etcd集群必要的生产要素,如etcd集群的自动扩缩容、升级、备份、故障恢复等。自研基于ansible的插件库,实现etcd集群管理功能,具体如下:向现有etcd集群添加成员。etcd集群删除该成员。etcd集群的备份,比如支持cephfs的数据备份。etcd集群故障恢复。查询etcd集群的健康状态。etcdBackup和etcdRestore的CR在这里定义,它们没有合并到KarmadaDeployment中。主要考虑了etcd集群本身的安全性,简化了KarmadaDeployment的ansible任务。其中,etcdRestore函数可以根据etcd集群的备份数据,将数据导入到一个新的etcd集群中,从而恢复Karmada集群的所有业务状态。目前主要场景如下:Karmada集群所在机房被撤销,需要备份etcd数据,迁移到新的Karmada集群。希望通过Karmada-Operator管理Karmada集群,只需要备份etcd数据,实现etcdRestore功能即可。如果Karmada集群出现故障,可以使用etcd备份数据,结合etcdRestroe实现故障恢复。2.7成员集群管理成员集群的生命周期管理主要包括注册和注销。上图展示了执行过程。为了处理成员集群的注册和注销,这里会动态生成清单。AnsibleInventory由静态Inventory和动态Inventory组成。静态清单是指文件中指定的主机和组。DynamicInventory是指通过外部脚本获取主机列表,并以ansible要求的格式返回给ansilbe命令。这里Karmada-Operator基于k8sCR实现动态库存插件,主要是通过解析KarmadaDeployment的members定义来动态生成库存。这里添加两个角色add-member和del-member。add-member中的集群会注册到Karmada控制面,del-member中的集群会从Karmada控制面注销,这样可以同时进行多次注册和注销。成员集群。同时也可以提供ssh登录方式,方便后期扩展。3.Karmada-OperatorCI介绍为了更好的提升开发者的体验,拟提供Karmada-Operator的CI构建能力。这里在K8s集群中部署了github自托管的Runner和kubevirt。用户在github上提交PR,触发githubActions。我们在自托管中定义的进程执行语法和单元测试。通过kubevirt创建一个虚拟机。在多个虚拟机中部署1个主机和2个成员集群。部署Karmada并添加成员集群以执行Karmada。e2e和bookfinfo案例测试计划中增加的CI矩阵测试如下:语法测试:ansible-lintshellcheckyamllintsyntax-checkpep8集群部署测试:Karmadactl、charts、yaml和二进制部署及所有配置项安装测试join/unjoinmemberclusterupgradeKarmadaetcd集群备份恢复功能测试:Karmadae2e测试创建bookinfo案例性能测试:我们主要通过kubemark组件模拟多个2000节点的成员集群进行性能测试。其中一个测试用例是集群故障转移。结论是40000个无状态pod可以运行15分钟完成故障迁移,有机会分享我们的性能测试。4.总结通过社区的研究和vivo的实践,最终确定了Karmada-Operator方案的设计。Karmada-Operator具有扩展性高、可靠性高、操作逻辑编写更直观、开箱即用等特点。我们相信,通过这个高度可扩展、声明式、自我修复的云原生系统来管理Karmada将为我们全面切换到Karmada来管理您的业务提供强有力和可靠的保证。基于Ansible的算子也有以下缺点。第一点没有提供webhook的能力,需要自己添加或者在ansible任务中添加相关验证;第二点是自动生成了一个通用的CRD模板,目前还没有详细可定义的自动生成CRD的脚手架工具。目前Karmada-operator还处于起步阶段,提供解决方案和一些实践,具体功能还需要不断完善和完善。详情可以查看vivo的Karmada-Operator仓库,欢迎大家试用并提出建议。当前代码提供的能力矩阵可以查看项目规划。