基于OpenStack和Docker设计的CI/CD

2019-04-12 17:13:44 浏览数 (1)

题图摄于深圳湾

编者:本文描述了在OpenStack的环境中使用Docker等技术实现CI/CD(持续集成/交付)的流程,以及使用开源镜像仓库Harbor的复制功能,实现流程各阶段的镜像管理的方法。本文选自徐超所著的新书《OpenStack最佳实践——测试与CI/CD》,编者对原文做了部分修改和调整。

徐超,中电科华云公司云开发工程师,从2014年起一直从事企业云计算产品自动化部署开发、QA测试和 CI/CD等相关工作,研究领域包括Kolla容器化OpenStack应用及部署等。

目前,在Docker容器中部署和运行OpenStack云计算服务,已成为主流趋势之一。基于这样的背景,设计和实现OpenStack Docker环境下的CI/CD应用便成为了必然,其核心是在OpenStack IaaS云计算平台上创建虚拟机,实现基于OpenStack的产品的CI/CD服务。

这里涉及三个重要组成部分:一是基于原生OpenStack研发的云计算产品,以及基于OpenStack基础设施平台构建的CI/CD服务;二是包括诸如Jenkins、GitLab、Gerrit、Harbor等系统在内的CI/CD应用;三是将OpenStack每个服务容器化,并使用Kolla方式部署。

基于云服务的CI/CD服务,可以实现弹性伸缩和横向扩展等。本节将以案例方式进行实践,如下图所示。

首先在物理服务器上搭建好OpenStack IaaS云平台,以及创建数台可用的虚拟机等,以备后续使用。所用到的持续集成和持续交付平台如下所示。

基于Docker的软件持续集成和持续交付

目前,Docker容器已经在IT软件生产的各个环节中得到了大量的推广和使用,如从软件开发,到持续集成和持续交付,再到生产环境上的微服务应用等。在基于容器的持续交付实现当中,以镜像为内容传递的单元,通过CI(持续集成)的测试以及验证,完成镜像从开发、测试到可发布的状态转变和软件的交付流程,如图所示。

持续集成和持续交付(CI/CD)流水线的建立,主要包括开发流水线、测试流水线和生产运维流水线3种:

(1)开发流水线

开发人员:频繁提交代码,通过持续地编译、打包、测试、镜像构建和自动化测试等环节,产生可测试的候选镜像列表(如0.1-dev)。开发流水线可以帮助团队频繁地进行代码集成并通过单元测试、代码静态分析、自动化测试等,有效帮助开发人员及时发现和解决问题,最终输出待测试的镜像列表。

(2)测试流水线

测试人员:从候选测试镜像列表中选择需要测试的目标镜像,标记为测试版本(如将0.1-dev标记为0.1-test),并且将待测试镜像自动部署到验收测试环境中进行测试,对于测试通过的镜像标记为预发布版本(如将0.1-test 标记为 0.1-beta)。

对于测试人员而言,流水线的起点则变为待测试的镜像列表,基于Jenkins创建类似的流水线,可以支持测试人员快速创建测试环境,并且运行相关的自动化测试脚本,同时满足手动探索性测试的需求。

(3)生产运维流水线

运维人员:从预发布镜像列表中选择镜像部署到预发布环境中,在验证通过后标记为release版本(如将0.1-beta 标记为 0.1-release),最后发布到生产环境中。

与自动化测试流水线相同,运维人员可以建立独立的部署流水线,从待发布的镜像列表中选择镜像发布到生产环境Registry中,并且设置流水线的自动或者手动触发,实现预生产环境的一键部署。

镜像仓库管理系统(Harbor)

在上述3个流水线中,无论是开发人员或CI系统发布镜像,还是测试人员或运维人员下载镜像,都要通过镜像仓库来完成。本节以Harbor Registry为例,介绍使用多个Registry实现区分不同的用途和边界控制要求。

Harbor是由VMware中国研发团队开发的开源企业级Docker镜像仓库管理系统,它对原有的Docker Registry服务进行了扩展,添加了更多的企业用户所需要的功能。Harbor被设计为用于部署企业内部使用的私有镜像仓库环境,这种私有服务对于非常关心安全的企业来说是十分重要的。另外,私有仓库服务通过避免从外网下载镜像节省了大量时间。

Harbor提供了Registry之间的镜像自动同步和复制功能,通过配置复制策略,自动化管理镜像传输流程。Harbor的复制策略启动之后,会比较远端Registry和本地端Registry在镜像上的差异,并把远端Registry缺少的镜像从本地端推送过去,使得两个Registry实例的镜像完全一致。后续推送到源实例上的镜像,会以增量的方式同步到远端实例上。当在源实例上删除镜像时,对端实例上的镜像也会被删除。

通过Harbor的复制机制,可以在CI/CD流程中实现多个Registry实例之间的镜像同步,参考流程如下图所示。

  • 开发环境的Registry:主要由开发人员使用,镜像变化频繁,同一个镜像可以存在多个版本(tag)。当开发完成后,通过CI系统生成相对稳定的镜像,并同步到测试环境的Registry。
  • 测试环境的Registry:主要由测试人员使用,当该Registry中的镜像测试通过后,推送到生产环境的Registry。
  • 生产环境的Registry:主要由运维人员使用,用于存放发布的镜像,从生产环境的Registry中输出的产物就是产品。

可以看到,在从开发到生产的整个过程中,符合要求的镜像会逐步进入下一阶段的Registry,最后到达生产系统,从而实现镜像的全生命周期管理。

基于OpenStack Docker的CI/CD流程设计

构建基于OpenStack Docker云平台研发测试用的CI/CD系统,其核心组件包括:Jenkins持续集成系统、GitLab代码仓库管理系统、Harbor私有镜像仓库管理系统、Gerrit代码评审系统等。

基于OpenStack Docker的CI/CD任务分解和流程设计步骤如下图所示。

① 开发者准备好一个单节点环境,将开发工具链接到远程开发目录,并使用Git将代码提交到代码评审系统Gerrit中,目的是通过协作发现一些明显的问题,减少把Bug带到软件中的概率。

② 当Jenkins持续集成系统检测到Gerrit系统的代码提交事件后,触发相关的Job任务,自动化执行代码编译、打包、构建、部署和测试等工作流。相应地,会执行如下任务:

  • 执行源码编译、打包,如RPM、WAR包等。
  • 构建Docker镜像。
  • 部署环境,如使用Kolla自动化部署OpenStack。
  • 自动化运行测试,如单元测试、集成测试等。测试结果有两种,一种是测试失败,流程返回到步骤1;一种是测试成功,流程继续。

③ 根据测试结果和其他信息综合决定此次开发人员提交的代码是否合并,这样保证只有通过了测试和审核的代码才能合并到GitLab仓库中。

④ GitLab的Webhooks会触发Jenkins系统中的两个构建任务,一个是源码编译、打包任务;一个是源码打包后的Docker镜像构建任务。Docker镜像构建后,Jenkins系统会自动将镜像推送到私有Registry仓库中。整个流程如下图所示。

很多企业内部都有一套标准化规范,在这套规范中定义了开发所使用的语言、框架、软件包版本及依赖环境等,这样做可以统一开发环境并解决因差异化带来的其他问题。基于此,我们可以根据不同的服务进行逻辑或物理上的分组,如下图所示。

在上图中,把Docker镜像分为了三层:基础镜像层、服务镜像层和应用镜像层。上层镜像的构建依赖于下层镜像,越下层的镜像越稳定,也越不会经常变更。

  • 基础镜像层:负责安装最基本的、所有镜像都需要的软件及环境,例如操作系统等。
  • 服务镜像层:负责构建符合企业标准化规范的镜像,这一层很像SaaS,例如Python环境、某个项目的公共软件包等。
  • 应用镜像层:负责部署和运行应用程序,这个阶段是CI的产出物,例如rpm包、Python源文件等。

分层后,由于下层镜像已经提供了应用所需要的全部依赖环境,因此可以显著加快应用镜像层构建的速度。对于容器而言,它只操作变更的部分,已经存在且没变化的内容则不做任何操作。

小结

对于竞争激烈的互联网企业而言,持续创新及快速交付服务是其打造产品核心竞争力的重要因素之一。真正给产品开发带来价值的,是如何完成产品的敏捷创新、降低风险,并根据市场反馈及时变更产品等。在这方面,OpenStack社区的做法是成功的。我们可以借鉴其优势,将其引入到自己的业务环境中。在开发阶段,通过CI达到控制代码质量和提升开发效率的目的。在交付阶段,利用CD帮助在短周期内产生有价值的产品,并且保证能够在任何时间进行发布。

0 人点赞