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(https://github.com/GoogleContainerTools/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 文件;
资源集分为多个版本,不同的版本对应资源的不同的描述文件;
用户可以选择某个版本,然后指定集群执行部署。


2. 部署任务

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


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

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

总结

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

原文地址:https://blog.51cto.com/13832960/2421743

时间: 2024-10-08 04:13:30

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

5步实现规模化的Kubernetes CI/CD 流水线

一.背景在近几年,Kubernetes迅速成为了容器编排的事实上的开源标准.与虚拟机不同,Kubernetes在抽象化基础架构的同时可靠地大规模编排容器,这可以帮助开发人员将工作负载与基础架构的复杂性质分开.Kubernetes是CI/CD自动化的理想选择,因为它提供了许多内置功能,这些功能使应用程序部署实现标准化和可重用,提高了开发人员的生产力,并加快了云原生应用程序的采用.Platform9是成立于2013年的云服务提供商,能够提供业界唯一由SaaS管理的混合云解决方案,使用户能够快速采用云

Jenkins CI/CD on Kubernetes with dynamic slaves

本文档介绍如何通过在 Kubernetes 集群上创建并配置 Jenkins Server 实现应用开发管理的 CI/CD 流程,并且利用 Kubernetes-Jenkins-Plugin 实现动态按需扩展 jenkins-slave. 步骤 1 安装 Kubernetes 集群 如果您没有 Kubernetes 集群,您需要先创建一个.具体操作参见 部署 Kubernetes 集群. 步骤 2 连接 Kubernetes 集群 有关如何连接到 Kubernetes 集群,参见 通过 kube

Kubernetes 集群的两种部署过程(daemon部署和容器化部署)以及glusterfs的应用!

ClusterIp:通过VIP来访问, NodePort: 需要自己搭建负载据衡器 LoadBalancer:仅仅用于特定的云提供商 和 Google Container Engine https://www.nginx.com/blog/load-balancing-kubernetes-services-nginx-plus/ port:相当于服务端口(对及集群内客户访问) targetPort: 相当于pods端口 nodePort: 宿主机端口(也是服务端口,只不过是对集群外客户访问)

mysql内部代码的优缺点

mysql内部代码有四种:存储过程,存储函数,事件,触发器. 存储过程&存储函数: 优点: 内部执行,离数据最近,另外在服务器上执行还可以节省宽带和网络延迟 代码重用,可以方便地统一业务规则,保证某些行为总是一致,也可以为应用提供一定的安全性. 简化代码的维护和版本更新. 帮助提升安全,提供更细颗粒度的权限控制. 缓存执行计划,如果反复调用可以降低消耗. 维护简单,没外部依赖 更好在开发和数据库维护人员间分工. 缺点: mysql没有提供好的开发和调试工具,编写调试困难. 效率差,存储过程使用的

宝塔面板 + Rancher + 阿里云镜像仓库 + +Docker + Kubernetes,添加集群、部署 web 应用

目录 一,安装宝塔面板(V 6.8) 二,使用宝塔安装 Docker,配置阿里云容器服务 三,安装 Rancher (Server) 四,管理 Rancher.添加集群 五,添加 Rancher 应用.服务,与 Nginx 六,ASP.NET Core 应用部署 七,相关文章推荐 前言: 本文使用 Centos 7.x 进行操作,Rancher 官方推荐使用 Ubuntu. Docker 对内核要求 大于 3.10,你可以使用 uname -r 检测系统内容版本. 通过 Rancher,可以很方

基于 Kubernetes v1.14.0 之 CoreDNS部署

1.部署容器前说明: 1.1.如果没有特殊指明,本文档的所有操作均在 k8s-operation 节点上执行: kuberntes 自带插件的 manifests yaml 文件使用 gcr.io 的 docker registry,国内被墙,需要手动替换为其它 registry 地址: 1.2.由于k8s-master 没有部署容器服务于路由服务,但是k8s-master 又要访问容器网络跟k8s集群网络,1.在上级路由器写入静态路由让其能访问容器网络与k8s集群网络.2.在k8s-maste

【Kubernetes系列】第7篇 CI/CD之组件部署

前言 应对敏捷开发的需求,对CI(持续集成))/CD(持续交付)的提出了更高的标准,今天来讨论下,如何基于开源组件(gitlab/jenkins/harbor/kubernetes)使用CI/CD,赋能团队的开发.运维. 核心组件 组件名称 版本 备注 kubernetes v1.15.3 10.0.0.182:6443 jenkins 2.176.2 集群内部署/ namespace: devops gitlab 11.8 主机部署 harbor v1.7.4 docker-compose部署

亚马逊云代码部署(NodeJS)

首先需要使用ssh或者putty登陆AWS ec2的linux实例(在Windows中使用putty连接linux实例参见:在Windows中连接亚马逊云服务器). 一 .为了方便文件传输  需要安装两个软件 1. winscp  WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端.同时支持SCP协议.它的主要功能就是在本地与远程计算机间安全的复制文件. 支持基于SSH-1.SSH-2的SFTP和SCP协议[2] 支持批处理脚本和命令行方式 多种半自动.自动的目录同步方式

Python调用Java代码部署及初步使用

Python调用Java代码部署: jpype下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#jpype 下载的时候需要使用Chrome浏览器进行下载. 安装顺序: 1.pip install wheel 待wheel安装好以后,再安装已经下载的JPype1-0.6.2-cp36-cp36m-win_amd64.whl 文件 2.pip install JPype1-0.6.2-cp36-cp36m-win_amd64.whl 如果有问题,缺少库