写点什么

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

  • 2019-11-10
  • 本文字数:3386 字

    阅读完需:约 11 分钟

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

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

我们对 CI/CD 的目标

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


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:



则开发流程为:


  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 是 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 文件;

  • 资源集分为多个版本,不同的版本对应资源的不同的描述文件;

  • 用户可以选择某个版本,然后指定集群执行部署。




  1. 部署任务


  • 用户每次部署都会生成一个 job,就是部署任务

  • 执行部署后,用户可在任务详情页直接查看部署任务日志。




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


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

总结

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


本文转载自公众号 UCloud 技术(ID:ucloud_tech)。


原文链接:


https://mp.weixin.qq.com/s/RXUw-3ztRB54MCaOc1wcHg


2019-11-10 23:301215

评论

发布
暂无评论
发现更多内容

修改Tomcat窗口的名称

阡陌r

Java tomcat 踩坑 实施

“数据资产”究竟是“数据”还是“资产”

马踏飞机747

大数据 数据中台 数据治理 数据资产

【应用异常监控利器Sentry搭建与学习笔记】

卓丁

Docker Sertry Fasthttp CI/CD Go 语言

职位拆解:互联网-运营

Taylor

行业资讯 移动互联网 运营 AARRR

LeetCode 241. Different Ways to Add Parentheses

liu_liu

LeetCode

你所不知道的淘宝325秘密

Geek_i59t1w

ios 淘宝 325

ARTS 第一周

onee

ARTS 打卡计划

Kubernetes 资料集合

倪朋飞

学习 Kubernetes 架构模式

手把手透析C语言堆内存申请malloc及扩容realloc

卓丁

c 堆内存管理 heap memory malloc realloc

鄙视链 & 全栈

伯薇

学习 能力提升 全栈

【ARTS】Week 1

Amos

ARTS 打卡计划

LeetCode 1048. Longest String Chain

liu_liu

LeetCode

Mobileye如何在云上进行深度学习模型训练

Randy

自动驾驶 学习 AI AWS

字节跳动:高级人才的五个基本素质

池建强

人才培养

Service Provider Interface介绍

Skysper

spi

游戏夜读 | 刀塔选手比较老吗?

game1night

Lucene的Smart CN实现分词、停用词、扩展词

Page

中文分词 lucene 停用词 扩展词 SmartCN

Linux如何调试内存泄漏

泰伦卢

c c++ C#

我的读书生涯-小学到大学: 没有成长, 只有不断加深的疑惑

lmymirror

人生 读书 经历 半虚构

Spring Data R2DBC 入门

稻草鸟人

MySQL WebFlux springboot R2DBC

转行程序员浅谈Linux下的多线程编程

WB

Linux 程序员 多线程

John 易筋 ARTS打卡Week 01

John(易筋)

ARTS 打卡计划

ARTS week 1

刘昱

Java 火焰图

wong

Java flamegraph

leetcode练级-只出现一次的数字

幸福三寸日光

算法 LeetCode js

leetcode练级-只出现一次的数字 升级版

幸福三寸日光

算法 LeetCode js

向往优雅的代码

Janenesome

编码习惯 读书

Python 3.6.1 官方文档练习——初入江湖(三)

小匚

Python python教程

我的 Windows Terminal 配置

FeiLong

Windows Terminal

ARTS打卡 week 1

猫吃小怪兽

ARTS 打卡计划

ARTS 01 - 为什么写作在远程工作中那么重要?

Calvin

ARTS 打卡计划

Kubernetes如何加速UCloud内部代码部署的CI/CD流程_文化 & 方法_高鹏_InfoQ精选文章