vivo大规模 Kubernetes 集群自动化运维实践
作者 | 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等集群部署任务。
主要流程如下:
上面看到是集群一键部署关键流程。当在多个数据中心部署完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-lintshellcheckyamllintsyntax-checkpep8
(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】: