CI / CD
CI / CD( Continuous Integration / Continuous Deployment )是一种通过在应用开发阶段引入自动化来加快应用交付的方法。CI / CD 主要由持续集成、持续交付和持续部署三部分构成,由于持续交付和持续部署只存在发布阶段是否自动化的区别,因此本文中,CI / CD 主要指持续集成及持续部署。
前言
传统模式中,前端负责制作静态页面,后端负责将静态页面嵌入进 PHP、JSP、ASP 等模板引擎中并提供 Web 服务,集成及部署时,动态资源和静态资源全部耦合在一起,前后端项目部署在同一物理机器上。
云服务时代,前端提供单页面应用( SPA ),后端通过 Web 服务提供 HTTP API,集成及部署时,前后端项目分离部署,再通过 Docker 分发到相应的云端机器上。
工作流
如上图所示:
- 持续集成(CI)是在源代码变更后自动检测、拉取、构建并进行单元测试及集成测试的过程。
- 持续部署(CD)是在持续集成的基础上,以自动化方式,频繁而且持续性的,将应用部署到生产环境的过程。
核心概念
阅前说明
在熟悉及上手 CI 工具时,需要简单了解下其核心概念。
以下概念均以 NodeJS 做演示说明,分为工作流、配置及触发器三大部分。
Workflow
CI 工具中,通常利用
.yml
及.xml
文件来描述工作流。工作流一般由以下四个部分组成(在不同 CI 工具里会有对应调整):
Task
单个任务的描述
通常为单行命令,如下:
yarn install
Step
单(多)个任务的集合
通常为单(多)行命令的集合,并依次执行,而且只要单个命令失败,剩余的命令将不再执行,如下:
# 以 circleci 为例 steps: - run: name: install command: | node -v yarn -v yarn install
Job
单(多)个步骤的集合
通常为单(多)个步骤的集合,并依次执行,而且只要单个步骤失败,剩余的步骤将不再执行,如下:
# 以 circleci 为例 version: 2 jobs: build: working_directory: ~/repo docker: - image: circleci/node:latest steps: - checkout - run: name: install command: | node -v yarn -v yarn install
Pipline
单(多)个工作的集合
通常为单(多)个工作的集合,并依次执行,而且只要单个工作失败,剩余的工作将不再执行,如下:
# 在 circleci 中, Pipline 即为其 Workflow version: 2 jobs: build: docker: - image: circleci/node:latest steps: - checkout - run: name: install command: | node -v yarn -v yarn install - run: name: build command: | yarn build test: docker: - image: circleci/node:latest steps: - checkout - run: name: test command: | yarn test workflows: version: 2 main-workflow: jobs: - build: - test: requires: # test will not run until the `build` job is completed. - build
Setting
配置主要提供环境变量及加密信息:
Environment Variables
环境变量为开发者在配置中定义的变量,可以在执行命令时获取对应的值,一般分为公共变量和私有变量两种,公共变量一般直接暴露在
.yml
文件中或存储于同级目录下的.env
文件中,私有变量一般在仓库配置项中进行配置,通常用于私密性信息的存储,并且只对该仓库生效。# 以 .travis.yml 为例 # GH_TOKEN 为存储在仓库配置项中的环境变量,如下图所示配置 # GH_REF 为存储在 .travis.yml 中的环境变量 language: node_js node_js: stable install: - yarn install script: - yarn build after_script: - git add A - git commit -m "deploy" - git push -f "https://${GH_TOKEN}@${GH_REF}" master:gh-pages env: global: - GH_REF: github.com/Damo/demo.git
Encrypted Secrets
加密信息一般用于保障信息的传递过程,CI / CD 构建发布过程中,通常需要一些敏感信息,如 Github 及 Gitlab 的 Personal access tokens,DB 的用户名及密码,Git 仓库的 SSH Keys 等。
在加密过程中,我们可以利用 CI 平台自身的加密工具来进行加密,比如利用 travis encrypt 命令加密 Slack 信息,如下:
# slackDomain:k4RhBu6TpTLBdQ1hPTKMSglB#web-notification 为需要加密信息 travis encrypt "slackdomain:k4RhBu6TpTLBdQ1hPTKMSglB#web-notification" --pro
可以利用第三方加密工具来进行加密,比如利用 ssh-keygen 命令生成 SSH keys,如下:
# 一路回车即可生成 # 生成后,查询公钥 cat id_rsa.pub # 生成后,查询私钥 cat id_rsa ssh-keygen
当加密信息过多时,也可以采用 Vault 来进行管理。
Trigger
触发器是 CI / CD 服务器执行构建操作行为的依据,有以下三种方式:
Webhook Push
推送是最常用的 CI / CD 触发器,通常与 Webhook 结合使用。
通俗来讲,Webhook 是让一个网站(订阅者)订阅另一个网站(发布者)特定事件的方法,以 Github 为例,通常 CI / CD 服务器会订阅 Github Rep Webhook,当源代码分支触发 push 或 pull request 事件时,Github Rep Webhook 就会通过 HTTP Service 通知 CI / CD 服务器进行构建操作。
Poll SCM( Software Configuration Management )
定时轮询 Git SCM 或 Webhook ,一旦源代码变动,则启动构建。
Build Periodically
不论源代码是否有变动,定期启动构建,通常情况下,一般不采用这种构建方式。
工具链
常用的 CI 工具如下:
-
基于 Ruby 开发,只适用于 Github 仓库,开源项目可免费使用
-
基于 Clojure 开发,适用于 Github 及 Bitbucket 仓库,仅提供一个 Linux容器免费使用
-
基于 Java 开发,适用于所有 Git 仓库,项目开源,插件丰富,生态完善
-
基于 Go 开发,适用于所有 Git 仓库,项目开源,原生容器支持,体积轻巧,构建速度快
-
基于 Ruby 开发,只适用于 Gitlab 仓库,社区版本免费使用
综上所述,中小团队推荐使用 Drone CI 来实现 CI / CD 工作流,中大型团队推荐使用 Jenkins CI 来实现 CI / CD 工作流,Github 开源项目推荐使用 Travis CI 及 Circle CI 来实现 CI / CD 工作流,Gitlab 项目推荐使用 Gitlab CI 来实现 CI / CD 工作流。
构建速度
评测注意事项
代码仓库为 GitHub 仓库,利用 Slack 通知机制,Gitlab CI 不在评测范围内
Jenkins 版本号为 2.164.3,Drone 版本号为 1.0
Circle 及 Travis 版本号为截至2019年5月的线上版本
CI 工具的构建速度可参考下图:
需要说明的是,Drone CI、Circle CI 及 Travis CI 都是基于 Docker 构建,未做 node_modules 缓存;Jenkins CI 未基于 Docker 构建,默认缓存 node_modules 。
关闭 Jenkins CI 的 node_modules 缓存,各 CI 工具构建速度如下:
可以发现,基于容器化方案的 Drone CI 和 Circle CI 在构建速度上不相伯仲,Jenkins CI 次之,而采用容器化方案的 Travis CI 稍逊色。