随着互联网规模的不断扩大, 越来越多的公司逐渐将业务的重点放在了互联网业务上, 如何合理的开发和管理海量的互联网业务成了当前的热点. 云计算的概念是2006年8月份由Google的CEO在搜索引擎大会上提出, 旨在为个人或组织提供虚拟化计算资源, 使得公司可以将自己的互联网业务托管于云服务商, 而不用构建自己的基础设施[1].
因为云的便利和业务量的上升, 越来越多的公司开始采用微服务的架构, 如B站推出了自己的微服务框架Kratos, 阿里巴巴的Spring Cloud Alibaba等. 因为在早期传统的单体架构应用中, 往往各个应用之间具有高耦合度、扩展能力弱. 微服务的提出很好地解决了这一痛点[2]. 相比较传统的架构, 微服务架构能够更好地帮助企业将新的功能点快速的迭代插入到现有的生产环境中去, 它减少了开发的复杂性以及部署的复杂性. 同时, 架构本身也降低了资源的消耗[3]. 表1是传统单体架构与微服务架构的对比. 微服务因为其拆分的原则, 往往一个业务会被拆分成多个微服务, 无论是开发或是部署都是非常的繁琐. Kubernetes是一款分布式容器编排引擎[4], 它能够很好的管理各个服务, 可以自动实现容器伸缩, 方便运维人员对容器的管理, 是一个得到生产实践证明的容器编排管理系统. 本文就将基于Kubernetes, 研究在其上构建持续集成持续部署的自动化流水线平台的最佳实践.
1 Kubernetes架构
在研究基于Kubernetes的CI/CD平台之前, 我们有必要先了解下它的整体架构及运作方式, 以便于我们更好的针对其架构特点设计出更符合其特性的CI/CD流水线. Kubernetes(简称k8s)是Google使用go语言开发的一个自动化容器操作的开源平台. 使用Kubernetes可以:
(1)自动化弹性构建容器;
(2)自动管理容器;
(3)提供容器之间的负载均衡;
(4)方便对容器版本回滚更新;
(5)易于扩容.
1.1 Kubernetes组件Kubernetes的集群主要由若干个Master节点和Node节点构成. Master节点在其上运行相应的Master组件和Node组件, Node节点运行Node组件, 图1是Kubernetes集群的架构图.
Master组件是集群的管理控制中心[4], 如下是Master组件:
(1) Kube-Apiserver[5]: 提供Restful风格的API接口, 通过它我们可以对k8s的资源对象进行增删改查, 同样apiserver也是k8s集群的数据总线和数据中心.
(2) Kube-Scheduler: 负责分配调度Pod到集群内的节点上, 它监听Kube-Apiserver, 查询还未分配Node的Pod, 然后根据调度策略为这些Pod分配节点.
(3) ETCD: 是一个高可用的分布式键值数据库, Kubernetes集群使用其作为它的数据后端.
(4) Kube-Controller-Manager: 集群内部的管理控制中心, 它会及时发现并执行自动化修复流程, 确保集群始终处于预期的工作状态.
Node组件在每个节点上运行, 维护运行的Pod并提供Kubernetes运行时环境.
(1) Kubelet: 是主要的节点代理, 它监测已分配给其节点的Pod.
(2) Kube-Proxy: 在每个节点上运行网络代理, 并反映每个节点上Kubernetes API中定义的服务.
在该分布式系统中, 各个服务运行在node节点上, 由master节点自动管理. 所以考量将CI/CD服务放置集群中运行, 方便自动化运维, 镜像仓库因需要频繁读写操作, 可放置于集群外进行管理, 减少对Kubernetes集群的压力. Kubernetes使用docker来进行容器的管理和云上的自动运维, 减少了相应的成本, 也不会再生产相应的环境冲突了, 总而言之是一种非常便利的工具[6].
2 CI/CD平台设计CI即持续集成是指开发将代码提交到GIT服务器上, 会触发一次集成服务器的相关功能, 比如编译、测试、输出结果等, 往往一天内会有多次的集成, 确保新增代码能与原先代码正确集成, 这样有利于及时检查代码的缺陷. CD即持续部署是指通过自动化部署的手段将软件功能频繁的进行交付, 加快了代码的上线速度.
2.1 CI工具选型往往持续集成持续部署是相继进行的CI的常用工具有Jenkins、Circle CI、Codeship等, Jenkins因其开源和完善的社区丰富的插件被广大公司所采用, 因此本文选型CI工具为Jenkins.
2.2 版本控制在持续集成中, 版本控制是不可或缺的一部分. 若部署时, 代码发生灾难性缺陷, 通过使用版本控制可及时回溯至上个正常的代码版本. 在常用的版本控制中, GIT含有的是分布式代码库与文件快照的设计思想, 相对于传统CVS、SVN等集中式、文件差异式版本控制工具是一种挑战与颠覆[7]. 所以本文采用GIT作为版本控制器, 在实验中将把代码托管给Github.
2.3 集成测试在持续集成中, 测试是必不可少的部分, 若未经过测试直接集成于生产环境, 会有重大的隐患. 在构建过程中考虑从仓库下拉代码完毕后执行开发写完的单元测试用例, 并生成XML格式的测试报告给Jenkins识别. 测试成功则继续后续的构建步骤, 若失败则退出构建.
2.4 CI/CD应用与Kubernetes关键点Jenkins集群为Master和Agent节点, 在Kubernetes中, 所有服务均为容器化构建并由Kubernetes管理, 所以采用容器化搭建Jenkins Master和Agent服务, 并托管与Kubernetes中. 当用户触发一次CI时, Jenkins Master节点会向Agent节点派送相应的CI任务. 考虑到在空闲时, Agent节点并无用处, 故采用动态构建Agent节点, 在有CI任务时由Jenkins Master向Kubernetes Apiserver发出构建请求, 可由Jenkins中Kubernetes该插件完成.
2.5 构建具体流程我们将CI/CD的步骤可分为如下几步[4], 流程如图2所示.
(1) 开发将代码提交至GIT仓库.
(2)代码发生变化后触发GIT HOOK, Jenkins Master节点请求Kubernetes Apiserver生成新的Jenkins Agent Pod.
(3) Jenkins Slave Pod生成后开始构建Jenkins Master节点下发的任务, 从GIT仓库中拉取代码.
(4) 代码拉取成功后, 开始执行单元测试, 单元测试成功则继续执行, 失败则退出构建任务.
(5) CI服务器根据预先定义的Pipeline文件, 将代码进行编译.
(6) 编译完成后, 打包成镜像将镜像推送至镜像仓库, 并打上最新标签.
(7) CI调用Kubernetes Cli, 将预先设定好的Deployment中的镜像更改为刚刚构建已推送至私用仓库的镜像, 从而完成部署.
3 实验测试
实验环境为3台已组成Kubernetes集群的虚拟机. 系统为Ubuntu19.04并对外暴露集群IP为192.168.11.31. 已将第一版本的代码, 使用Flask框架编写的后端打包部署至该集群lab的命名空间里, 并通过NodePort的方式对外暴露服务, 端口为30010, 模拟生产环境的后端接口. 此时我们使用curl 192.168.11.31:30010命令, 可返回预先设置好的字符串“This is first version code!”
(1)修改代码, 设置返回字符串为“This is second version code!”
(2)提交代码并推送至GIT仓库.
(3)发现Jenkins Slave Pod已经自动生成并开始构建任务.
(4)稍等片刻, Jenkins Slave Pod显示终止中, 查看Jenkins console output, 发现已成功完成构建任务.
(5)再次尝试curl 192.168.11.31:30010, 返回的字符串是“This is second version code!”, 即服务端代码已成功更新.
实验测试过程如图3所示.
4 结论与展望
本文通过实践可以发现, 比起传统的需要人力去打包并手动部署到服务器上从而需要大量的人力物力, 该CI/CD流水线仅需开发人员上传代码后即能自动打包部署至相应的环境中, 展现了符合期望的基于Kubernetes的CI/CD自动化流水线, 可大大提升开发到交付的效率, 并且可实现高并发弹性构自动化建流水线. 对于拥有多个在Kubernetes集群中的服务、需要快速迭代频繁修改代码并部署的项目具有省时省力且不容易出错的优势.
[1] |
Kovács J, Kacsuk P, Emődi M. Deploying Docker Swarm cluster on hybrid clouds using Occopus. Advances in Engineering Software, 2018, 125: 136-145. DOI:10.1016/j.advengsoft.2018.08.001 |
[2] |
Taherizadeh S, Grobelnik M. Key influencing factors of the Kubernetes auto-scaler for computing-intensive microservice-native cloud-based applications. Advances in Engineering Software, 2020, 140: 102734. DOI:10.1016/j.advengsoft.2019.102734 |
[3] |
苏瑾, 田建斌. 云环境中Web应用的微服务架构. 电子技术与软件工程, 2019(15): 131-132. |
[4] |
朱小亮. 基于容器引擎的云平台设计与实现[硕士学位论文]. 北京: 北京工业大学, 2019.
|
[5] |
王伟军. 基于Kubernetes的容器云平台建设. 电脑知识与技术, 2019, 15(36): 47-48. |
[6] |
陈春辉. 基于Kubernetes实现云上自动化运维. 科学大众, 2018(11): 12. |
[7] |
杨振华. 软件持续交付平台的研究与实践[硕士学位论文]. 北京: 北京邮电大学, 2016.
|