NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

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:301035

评论

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

极客时间架构师训练营 - week4 - 作业 1

jjn0703

极客大学架构师训练营

架构师训练营第四周作业

Melo

Golang中的Interface(接口),全面解析

Eriol

接口 interface Go 语言

前端存储除了 localStorage 还有啥

阿宝哥

Java 大前端 存储

消息队列(五)如何保证消息的顺序性?

奈何花开

Java MQ 消息队列

程序员面试与 HR 谈薪资技巧

张小方

程序员 面试 offer 年终奖 月薪

ARTS - Week Six

shepherd

Java algorithm

架构师训练营 第4周作业

Glowry

极客大学架构师训练营

架构师是怎样炼成的 04-1互联网分布式系统架构演化

闷骚程序员

极客大学架构师训练营

漫画:对象是如何被找到的?句柄 OR 直接指针?

王磊

Java 面试

「架构师训练营」第 4 周 学习总结

guoguo 👻

极客大学架构师训练营

计算机操作系统基础(七)---作业管理之死锁

书旅

php laravel 线程 操作系统 进程

架构师训练营:第四周作业

zcj

极客大学架构师训练营

架构师训练营 第4周学习总结

Glowry

极客大学架构师训练营

架构师训练营总结-20200627

caibird1984

极客大学架构师训练营

一张PDF了解JDK9 GC调优秘籍-附PDF下载

程序那些事

性能调优 GC JDK9 cheatsheet 秘籍

漫画:15张图,帮你看懂布隆算法

Java小咖秀

面试 算法 布隆过滤器

戴尔Latitude 9510 雅典娜计划标准的英特尔移动超能版笔记本

最新动态

极客大学算法训练营第一课

落曦

第四周作业

芒夏

极客大学架构师训练营

架构设计之常识篇

魔曦

架构师 极客大学架构师训练营

第四周总结

芒夏

极客大学架构师训练营

消息队列(四)如何处理消息丢失的问题?

奈何花开

Java MQ 消息队列

聊聊Hystrix中的命令模式

老胡爱分享

Java 面试 设计模式 命令模式

理解了 1+2 的过程,你就理解了Java虚拟机

侯树成

JVM JVM原理

架构师训练营第三周作业

陈靓-哲露

Python多重继承问题之MRO和C3算法

王坤祥

Python MRO C3算法 多继承

架构师训练营第四周作业

W_T

架构师训练营作业-20200627

caibird1984

极客大学架构师训练营

使用 Python 制作酷炫多彩的 Jenkins 插件词云图

donghui

jenkins wordcloud

【6月】本月读书学到了什么

Neco.W

读书感悟 阅读量

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