Kubernetes如何加速UCloud内部代码部署的CI/CD流程

UCloud内部长期使用 Gitlab 来管理代码。虽然Gitlab做为一套开源平台已很优秀,但咱们对于其能为CI/CD提供的敏捷性并不十分满意,内部实践中的代码发布周期仍需按天计算。为此,咱们打造了一个基于Kubernetes的内部容器服务平台(名为KUN),用于托管内部服务,并将Gitlab对接到KUN平台,从而借助Kubernetes的云原生优点,得到更好的CI/CD效果。这套系统运行一年内,Gitlab的Pipeline一共触发了994次,执行了约20000+次Job,在测试环境和正式环境一共进行了7000+次部署,即天天部署约20次。如下是该项目的一些实践经验。git

咱们对CI/CD的目标github

CI即Continuous Integration(持续集成),指代码集成到主干以前必须经过自动化测试,只要有一个测试用例失败,就不能集成。目的是让产品快速迭代的同时还能保持高质量。docker

CD有两种意思:后端

Continuous Delivery,持续交付,指的是任何的修改都通过验证,能够随时实施部署到生产环境。 Continuous Deployment,持续部署,是持续交付的更高阶段,指的是任何修改后的内容都通过验证,自动化的部署到生产环境。 二者的区别,在因而否自动部署到生产环境。对UCloud而言,确定要之后者,也就是持续部署为目标。安全

Gitlab分支管理编辑器

咱们采用的Gitlab分支管理模型在接入KUN平台先后并未发生变化,故简述以下:工具

master:主分支,代码通过验证。从 master 建立 tag 进行 Release。 dev:研发主分支,用于合入特性分支和补丁分支,在此分支。单元测试

临时分支: 特性分支:用于开发某个特性; 补丁分支:用于修复线上 bug。 下面以一个实例来介绍CI/CD开发流程。StepFlow是UCloud新近推出的一款可视化工做流产品,经过StepFlow用户能够灵活便捷地定义本身的工做流,快速实现业务功能。整套StepFlow系统由多个模块组成,并所有部署在Kubernetes集群上。测试

在实例中,咱们须要开发其中名为optimize-allocate 的一个feature:ui

则开发流程为:

  1. 首先,在 Gitlab 上建立了编号为80的Issue,跟进这个optimize-allocate的feature;

  2. 从dev分支建立一个新分支,名为feature/80-optimize-allocate,在该分支上进行开发;

  3. 在feature/80-optimize-allocate上开发完成,进行commit,此时会触发静态测试、单元测试、Review等Pipeline Job;

  4. 测试经过后,建立一个从feature/80-optimize-allocate到dev的merge request,由负责人进行审核。审核经过而且merge成功后,触发静态测试、单元测试、镜像构建、镜像部署、集成测试等Pipeline Job;

  5. 测试经过后,建立一个从dev到master的mergerequest,由负责人进行审核。审核经过而且merge成功后,负责人建立tag v1.1.1,而后触发静态测试、单元测试、镜像构建、镜像部署、集成测试等Pipeline Job;

注:版本号tag是有命令规范的,v{x}.{y}.{z}表明着v{主版本}.{次版本}.{小修订版本}

Gitlab CI/CD Pipeline

Gitlab 8.0版本之后,默认集成并开启了Gitlab-CI,是能够提供必定CI能力的,咱们以此搭建持续集成的流水线,其中有Pipeline、Stage和Job三个层级须要设计。

Pipeline

Gitlab 会检测一个项目的根目录下的 .Gitlab-CI.yml 文件,用户可在该文件中定义 CI/CD Pipeline,一个 Pipeline 表明了 CI/CD 的整个过程。代码发生变化时(好比 push、tag、merge等),将触发一个 Pipeline 的运行。

Stage

一个 Pipeline 包含多个 Stage,好比“静态检查”、“单元测试”、“构建镜像”等等,这些 Stage 一个接一个顺序执行。

Job

每个 Stage 能够包含多个 Job,同一个 Stage 的全部 Job 同时执行。每一个Job需指定若干个重要属性如image, stage, tags, service等。

在StepFlow例子中,针对要开发的feature,其Pipeline设计以下,包括静态检查、单元测试和最后的两个手动 Code Review:

当其须要发布到公共测试环境(相似预发布环境),则设计另外一个Pipeline,包括:执行完整的静态检查, 单元测试, 预发布镜像 build, 预发布部署, 预发布集成测试。

而合并 master 以后触发 prod 环境的另外一个 Pipeline,包括静态检查、生产环境镜像的 build、生产环节的部署、最后集成测试:

Gitlab Runner

咱们将Gitlab Runner和Gitlab-CI配合使用,负责具体 Job 的运行。Gitlab Runner Kubernetes Executor 提供了在 Kubernetes 中运行 Job 的能力。运行原理以下:

Gitlab Runner 须要事先部署并注册到 Gitlab 上; 当代码发生更新时,Gitlab 根据用户的配置,通知 runner 来运行 Job; Gitlab Runner 使用某个镜像来建立一个 Pod,而后在其中运行某些命令; Gitlab Runner 将整个运行过程以及运行结果告诉 Gitlab。

Kaniko集成和改造:在容器中构建Docker镜像

为了使用 CI/CD 将代码变成最终运行在 Kubernetes 中的服务,必不可少的一步就是容器镜像的构建。因为CI Job自己就是以容器的形式运行的,因此须要在容器中构建出 Docker 镜像。

已有的方法,包括把 Host 上的 Docker Socket 挂载到 Pod 里面去(Docker Socket Mounting),或者是在 Pod 再启动一个 Docker Daemon(Docker-in-Docker),然而,前者有安全风险,后者须要 Pod 具有特权,两种方法都不适合。

Kaniko(github.com/GoogleConta… Google开源的一个工具,能够实如今 docker 容器里面制做 docker 镜像,而且不须要任何特权。

可是原生的 Kaniko 镜像因为缺乏一些必要的工具,没法和Gitlab CI集成。为此咱们修改了Kaniko镜像,添加了整个busybox工具包进去,以支持其做为一个CI Job来运行。而后就能够把Gitlab往内部容器服务平台KUN对接了。代码示例以下:

use Docker:cd /path/to/project && \ docker build -t uhub.service.ucloud.cn/myimage:0.0.1 -f deploy/Dockerfile && \ docker push uhub.service.ucloud.cn/myimage:0.0.1# use Kaniko: /kaniko/executor -c /path/to/project -f deploy/Dockerfile -d uhub.service.ucloud.cn/myimage:0.0.1

KUN+Gitlab:基于Kubernetes的CI/CD流程

KUN中CI/CD的整个流程如上图所示。从图中咱们能够看到,CI部分是一个单元测试,预发布部署,集成测试,Debug,提交代码的循环过程。在CI过程当中预发布的部署是经过CD系统来实现的,CI其中一个步骤是生成部署文件,而后按照项目、资源集、版本等参数提交到CD后端系统。CD系统提供了页面入口,当部署文件推送到CD系统后,用户能够在页面查找对应的部署文件。若是须要部署,在页面点击“部署”按钮便可实现部署。

YAML编辑器

为方便用户使用,咱们为KUN开发了专门的YAML编辑器,相比用普通的文本编辑器写YAML,能够提供智能模板补全、搜索替换等能力。

上图展现了一个使用案例,目前页面编辑器支持的功能有:

Snippet:模版补全,用户编辑文档时,会提示相关模版,可选择直接模版输入

Hover:用户鼠标放置关键字,提示关键字含义和官方文档连接

搜索替换:使用⌘+F/Ctrl+F打开页面搜索支持页面直接查询

部署系统

为了在Gitlab CI Job中把服务部署到Kubernetes上,咱们研发了部署系统。在CI Pipeline的最后一步,用户生成一个YAML文件,定义须要部署到Kubernetes上的资源,而后使用部署系统提供的一个工具镜像,该镜像会调用部署系统的API,将YAML提交给部署系统。接下来部署系统将使用用户的权限,调用Kubernetes API实现真正的部署。

目前部署系统主要包含两部分功能:

1. 资源集管理:

资源集是用户项目下一个或多个资源的集合,资源指 Kubernetes 的 object 的描述文件,通常为 YAML 文件; 资源集分为多个版本,不一样的版本对应资源的不一样的描述文件; 用户能够选择某个版本,而后指定集群执行部署。

2. 部署任务

用户每次部署都会生成一个 job,就是部署任务 执行部署后,用户可在任务详情页直接查看部署任务日志。

当完成上述全部工做,Gitlab能很好嵌入KUN平台,运行在Kubernetes上的各模块就可像齿轮同样有序运转,从而得到CI/CD上的良好效果。

前面提到的StepFlow项目,从一开始就实施了这样一套 CI/CD,效率得到了很大提高,每一个编译Job耗时约3分钟,其余Job耗时在1分钟之内。

总结

CI/CD是提供高质量互联网服务必不可少的一环。Gitlab和Kubernetes都是很是优秀的开源软件,在此基础上,咱们根据本身的实际状况,结合二者打造了一套高效的CI/CD平台,努力提高研发效率,为用户提供更优质的服务。

相关文章
相关标签/搜索