介绍一下现在最🔥的 CICD 平台的一些使用技巧
什么是 CICD
CICD
的中文翻译是 持续集成,持续部署,简单来说就是在程序员们每天不断的合并代码时,有一个系统可以自动对合入的代码进行各种测试,以保证合入代码没有对服务造成破坏,然后自动化地构建产物(比如 Docker 镜像、编译后的二进制执行文件),并完成自动化部署等等。
一个比较有名的 CICD 系统是 Jenkins
,它通过 Pipeline 定义工作流,也可以直接使用任务模板,强大又灵活。 Jenkins 通常需要开发者自行部署到服务器,所以它是一种本地 CICD 方案。
因此也有一些专门做云上 CICD 的平台,比如 Travis CI
、AppVeyor
等。我们要介绍的 Github Workflow
也是一种云上 CICD 平台,它最大的优势是天然的和 Github 绑定,可以非常方便地使用他人开发的 Github Actions
。
一个简单的 Workflow
只需要将这个文件放到 Github 仓库中,它就会在每次主分支有提交时运行,还可以在 Actions
选项卡看到运行情况:
本文不是 Github Workflow 的使用教程,所以不再介绍基本的使用方法,可以到官网查看完整的教程。
CICD 设计思路
为一个双环境系统设计一套 CICD,双环境是指有一个 Production
线上生产环境,还有一个 Testing
测试环境。这套 CICD 的大致流程如下:
每个代码仓库有且仅有一个主分支,主分支对应 Testing 环境,当 Git 推送 commit 或合并 PR 时,自动进行单元测试、镜像构建,并最终发布到 Testing 环境。当 Git 推送 tag 时,构建的产物将会自动部署的 Production 环境。
这里的构建产物虽然可以是前端的 dist
文件,或者后端的 bin
可执行文件,但更好的方法是通过镜像和容器来管理我们的服务,通过镜像版本来管理我们的服务版本。对于产物是镜像的服务,它的一个简单 CICD 流程可以如下:
注意这里的 dev 镜像版本可以是 commit sha
,如 server:411f38c
。推送 tag 时,根据 tag 对应的 commit sha
拉取之前构建好的镜像,并重新打上标签,如 server:1.0.0
,并最终手动部署到 Production 环境。
CICD on Github Workflow
由于 Github Workflow 设计上的灵活性,我们可以每部分拆解来看实现方式。
自动化测试
自动化构建
代码仓库下需要添加一个 Dockerfile 文件,来编写服务编译脚本,例如一个简单的前端服务:
自动化部署
一个最简单的使用 SSH 登录到服务器,并执行升级服务脚本的 Workflow:
关于 Docker Service 的教程可以参考我的这篇文章。
当然实际情况肯定比这个要复杂,我们可以一步一步解决实际可能遇到的问题。
管理配置文件
服务升级肯定不只是升级服务的程序,还要考虑它需要的配置文件,以及不同环境如何使用不同的配置文件。
如果你使用 k8s
管理服务,那么你不需要关注这个章节,因为 ConfigMap
已经替你做了大部分工作。
如果你使用 Github 仓库来管理配置文件,那么可以给服务器安装 Git,通过 git pull
拉取最新的配置文件,例如:
然而这需要服务器具有访问你的 Github Repo 的权限,并且同一仓库下具有多个服务时,git pull
会更新到其他原本不想更新的文件,还会出现并发问题导致部署失败。
所以一个更好的方法是使用 Docker Config
管理配置文件,它可以将配置文件标记版本号,以便将镜像版本和配置文件版本绑定起来更新。关于 Docker Config 的使用方法可以参考我的这篇文章。
另外还可以使用其他存储服务(如 OSS
)来代替本地 git pull
的方式更新配置文件,当配置文件更新时自动推送到 OSS,然后在服务器挂载 OSS 到本地目录即可。这样服务器只需要有 OSS 的访问权限即可,这在同一个云服务商下很容易做到,而且更利于扩容。
一个自动推送配置文件到 OSS 的 Workflow:
支持回滚重启等操作
写一个 service.sh
脚本,根据不同的参数执行不同的操作,例如:
使用方法:
然后在 Workflow 中使用 SSH 登录到服务器上执行这个脚本即可:
多环境部署
Testing 环境往往部署在单独的服务器,只需要根据环境选择 SSH 登录到不同服务器即可。
Workflow 重用
有多个服务需要管理时,如果每个服务的部署脚本相同还好,用上面的 Workflow 传入不同的 service 就可以了。
但如果有些服务的部署流程比较特殊,必须单独为每个服务编写一个脚本来执行部署、回滚操作的话,每个 Workflow 都写这么冗长就有些难以维护了,这就要用到 Workflow 的 重用 功能了。
重用就是用类似函数调用的方式去调用一个 Workflow,也就是 Workflow 的封装。
可以这样将 SSH 登录执行和服务独立配置分割开:
构建后自动部署
想要实现构建后自动部署到 Testing 环境,如果所有 Workflow 都在同一个仓库下,那直接重用即可。
如果不再同一个仓库下,可以用 repository_dispatch
的方式调用另一个仓库下的 Workflow。
被调用仓库的 Workflow:
构建产物的 Workflow:
部署后周知工作群
github-script
这个 Action 可以执行 js 代码,那我们就可以用支持 API 的群机器人来发送通知。
例如,下面的代码发送通知到 Lark 群:
这个 Workflow 会通过 Lark 机器人发送一张消息卡片,发送消息的代码如下:
当然卡片也可以在 Workflow 中通过变量做一些美化,测试效果: