作者:vivo 互联网服务器团队-Zhang Rong
一、背景
随着vivo业务迁徙到K8s的增长,咱们须要将K8s部署到多个数据中心。如何高效、牢靠的在数据中心治理多个大规模的K8s集群是咱们面临的要害挑战。kubernetes的节点须要对OS、Docker、etcd、K8s、CNI和网络插件的装置和配置,保护这些依赖关系繁琐又容易出错。
以前集群的部署和扩缩容次要通过ansible编排工作,黑屏化操作、配置集群的inventory和vars执行ansible playbook。集群运维的次要艰难点如下:
- 须要人工黑屏化集群运维操作,存在操作失误和集群配置差别。
- 部署脚本工具没有具体的版本控制,不利于集群的降级和配置变更。
- 部署脚本上线须要破费大量的工夫验证,没有具体的测试用例和CI验证。
- ansible工作没有拆分为模块化装置,应该化整为零。具体到K8s、etcd、addons的等角色的模块化治理,能够独自执行ansible工作。
- 次要是通过二进制部署,须要本人保护一套集群管理体系。部署流程繁琐,效率较低。
- 组件的参数治理比拟凌乱,通过命令行指定参数。K8s的组件最多有100以上的参数配置。每个大版本的迭代都在变动。
本文将分享咱们开发的Kubernetes-Operator,采纳K8s的申明式API设计,能够让集群管理员和Kubernetes-Operator的CR资源进行交互,以简化、升高工作风险性。只须要一个集群管理员就能够保护成千上万个K8s节点。
二、集群部署实际
2.1 集群部署介绍
次要基于ansible定义的OS、Docker、etcd、k8s和addons等集群部署工作。
次要流程如下:
- Bootstrap OS
- Preinstall step
- Install Docker
- Install etcd
- Install Kubernetes Master
- Install Kubernetes node
- Configure network plugin
- Install Addons
- Postinstall setup
下面看到是集群一键部署要害流程。当在多个数据中心部署完K8s集群后,比方集群组件的安全漏洞、新性能的上线、组件的降级等对线上集群进行变更时,须要小心谨慎的去解决。咱们做到了化整为零,对单个模块去解决。防止全量的去执行ansible脚本,减少保护的难度。针对如Docker、etcd、K8s、network-plugin和addons的模块化治理和运维,需提供独自的ansible脚本入口,更加精密的运维操作,笼罩到集群大部分的生命周期治理。同时kubernetes-operator的api设计的时候能够不便抉择对应操作yml去执行操作。
集群部署优化操作如下:
(1)K8s的组件参数治理通过ConmponentConfig[1]提供的API去标识配置文件。
- 【可维护性】当组件参数超过50个以上时配置变得难以治理。
- 【可降级性】对于降级,版本化配置的参数更容易治理。因为社区一个大版本的参数没有变动。
- 【可编程性】能够对组件(JSON/YAML)对象的模板进行修补。如果你启用动静kubelet配置选项,批改参数会主动失效,不须要重启服务。
- 【可配置性】许多类型的配置不能示意为key-value模式。
(2)打算切换到kubeadm部署
- 应用kubeadm对K8s集群的生命周期治理,缩小本身保护集群的老本。
- 应用kubeadm的证书治理,如证书上传到secret里缩小证书在主机拷贝的工夫耗费和从新生成证书性能等。
- 应用kubeadm的kubeconfig生成admin kubeconfig文件。
- kubeadm其它性能如image治理、配置核心upload-config、主动给管制节点打标签和污点等。
- 装置coredns和kube-proxy addons。
(3)ansible应用标准
- 应用ansible自带模块解决部署逻辑。
- 防止应用hostvars。
- 防止应用delegate_to。
- 启用–limit 模式。
- 等等。
2.2 CI 矩阵测试
部署进去的集群,须要进行大量的场景测试和模仿。保障线上环境变更的可靠性和稳定性。
CI矩阵局部测试案例如下。
(1)语法测试:
- ansible-lint
- shellcheck
- yamllint
- syntax-check
- pep8
(2)集群部署测试:
- 部署集群
- 扩缩容管制节点、计算节点、etcd
- 降级集群
- etcd、Docker、K8s和addons参数变更等
(3)性能和功能测试:
- 查看kube-apiserver是否失常工作
- 查看节点之间网络是否失常
- 查看计算节点是否失常
- K8s e2e测试
- K8s conformance 测试
- 其余测试
这里利用了GitLab、gitlab-runner[2]、ansible和kubevirt[3]等开源软件构建了CI流程。
具体的部署步骤如下:
- 在K8s集群部署gitlab-runner,并对接GitLab仓库。
- 在K8s集群部署Containerized-Data-Importer (CDI)[4]组件,用于创立pvc的存储虚拟机的映像文件。
- 在K8s集群部署kubevirt,用于创立虚拟机。
- 在代码仓库编写gitlab-ci.yaml[5], 布局集群测试矩阵。
如上图所示,当开发人员在GitLab提交PR时会触发一系列操作。这里次要展现了创立虚拟机和集群部署。其实在咱们的集群还部署了语法检查和性能测试gitlab-runner,通过这些gitlab-runner创立CI的job去执行CI流程。
具体CI流程如下:
- 开发人员提交PR。
- 触发CI主动进行ansible语法查看。
- 执行ansible脚本去创立namespace,pvc和kubevirt的虚拟机模板,最终虚拟机在K8s上运行。这里次要用到ansible的K8s模块[6]去治理这些资源的创立和销毁。
- 调用ansible脚本去部署K8s集群。
- 集群部署完进行性能验证和性能测试等。
- 销毁kubevirt、pvc等资源。即删除虚拟机,开释资源。
如上图所示,当开发人员提交多个PR时,会在K8s集群中创立多个job,每个job都会执行上述的CI测试,相互不会产生影响。这种次要应用kubevirt的能力,实现了K8s on K8s的架构。
kubevirt次要能力如下:
- 提供规范的K8s API,通过ansible的K8s模块就能够治理这些资源的生命周期。
- 复用了K8s的调度能力,对资源进行了管控。
- 复用了K8s的网络能力,以namespace隔离,每个集群网络相互不影响。
三、Kubernetes-Operator 实际
3.1 Operator 介绍
Operator是一种用于特定利用的控制器,能够扩大 K8s API的性能,来代表K8s的用户创立、配置和治理简单利用的实例。基于K8s的资源和控制器概念构建,又涵盖了特定畛域或利用自身的常识。用于实现其所治理的利用生命周期的自动化。
总结 Operator性能如下:
- kubernetes controller
- 部署或者治理一个利用,如数据库、etcd等
- 用户自定义的利用生命周期治理
- 部署
- 降级
- 扩缩容
- 备份
- 自我修复
- 等等
3.2 Kubernetes-Operator CR 介绍
kubernetes-operator的应用很多自定义的CR资源和控制器,这里简略的介绍性能和作用。
【ClusterDeployment】: 管理员配置的惟一的CR,其中MachineSet、Machine和Cluster它的子资源或者关联资源。ClusterDeployment是所有的配置参数入口,定义了如etcd、K8s、lb、集群版本、网路和addons等所有配置。
【MachineSet】:集群角色的汇合包含管制节点、计算节点和etcd的配置和执行状态。
【Machine】:每台机器的具体信息,包含所属的角色、节点自身信息和执行的状态。
【Cluster】:和ClusterDeployment对应,它的status定义为subresource,缩小
clusterDeployment的触发压力。次要用于存储ansible执行器执行脚本的状态。
【ansible执行器】:次要包含K8s本身的job、configMap、Secret和自研的job控制器。其中job次要用来执行ansible的脚本,因为K8s的job的状态有胜利和失败,这样job 控制器很好察看到ansible执行的胜利或者失败,同时也能够通过job对应pod日志去查看ansible的执行具体流程。configmap次要用于存储ansible执行时依赖的inventory和变量,挂在到job上。secret次要存储登陆主机的密钥,也是挂载到job上。
【扩大控制器】:次要用于扩大集群治理的性能的附加控制器,在部署kubernetes-operator咱们做了定制,能够抉择本人须要的扩大控制器。比方addons控制器次要负责addon插件的装置和治理。clusterinstall次要生成ansible执行器。remoteMachineSet用于多集群治理,同步元数据集群和业务集群的machine状态。还有其它的如对接私有云、dns、lb等控制器。
3.3 Kubernetes-Operator 架构
vivo的利用散布在数据中心的多个K8s集群上,提供了具备集中式多云治理、对立调度、高可用性、故障复原等要害个性。次要搭建了一个元数据集群的pass平台去治理多个业务K8s集群。在泛滥要害组件中,其中kubernetes-operator就部署在元数据集群中,同时独自运行了machine控制器去治理物理资源。
上面举例局部场景如下:
场景一:
当大量利用迁徙到kubernets上,管理员评估须要扩容集群。首先须要审批物理资源并通过pass平台生成对应machine的CR资源,此时的物理机处于备机池里,machine CR的状态为闲暇状态。当管理员创立ClusterDeploment时所属的MachineSet会去关联闲暇状态的machine,拿到闲暇的machine资源,咱们就能够观测到以后须要操作机器的IP地址生成对应的inventory和变量,并创立configmap并挂载给job。执行扩容的ansible脚本,如果job胜利执行完会去更新machine的状态为deployed。同时跨集群同步node的控制器会查看以后的扩容的node是否为ready,如果为ready,会更新以后的machine为Ready状态,才实现整个扩容流程。
场景二:
当其中一个业务集群呈现故障,无奈提供服务,触发故障复原流程,走对立资源调度。同时业务的策略是调配在多个业务集群,同时配置了一个备用集群,并没有在备用集群上调配实例,备用集群并不理论存在。
有如下2种状况:
- 其它的业务集群能够承载故障集群的业务,kubernetes-operator不须要执行任何操作。
- 如果其余业务集群不能承载故障集群的业务。容器平台开始预估资源,调用kubernetes-operator创立集群,即创立clusterDeployment从备机池里抉择物理机器,观测到以后须要操作机器的IP地址生成对应的inventory和变量,创立configmap并挂载给job。执行集群装置的ansible脚本, 集群失常部署实现后开始业务的迁徙。
3.4 Kubernetes-Operator 执行流程
- 集群管理员或者容器平台触发创立ClusterDeployment的CR,去定义以后集群的操作。
- ClusterDeployment控制器感知到变动进入控制器。
- 开始创立machineSet和关联machine 资源。
- ClusterInstall 控制器感知ClusterDeployment和Machineset的变动,开始统计machine资源,创立configmap和job,参数指定操作的ansible yml入口,执行扩缩容、降级和装置等操作。
- 调度器感知到job创立的pod资源,进行调度。
- 调度器调用K8s客户端更新pod的binding资源。
- kubelet感知到pod的调度后果,创立pod开始执行ansible playbook。
- job controller感知job的执行状态,更新ClusterDeployment状态。个别策略下job controller会去清理configmap和job资源。
- NodeHealthy感知K8s的node是否为ready,并同步machine的状态。
- addons 控制器感知集群是否ready,如果为ready去执行相干的addons插件的装置和降级。
四、总结
vivo大规模的K8s集群运维实际中,从底层的集群部署工具的优化,到大量的CI矩阵测试保障了咱们线上集群运维的平安和稳定性。采纳了K8s托管K8s的形式来自动化治理集群(K8s as a service),当operator检测以后的集群状态,判断是否与指标统一,呈现不统一时,operator会发动具体的操作流程,驱动整个集群达到目标状态。
以后vivo的利用次要散布在自建的数据中心的多个K8s集群中,随着利用的一直的增长和简单的业务场景,须要提供跨自建机房和云的多个K8s集群去运行原云生的应用程序。就须要Kubernetes-Operator提供对接私有云基础设施、apiserver的负载平衡、网络、dns和Cloud Provider 等。须要后续不断完善,升高K8s集群的运维难度。