什么是CI?
持续集成(Continuous integration)频繁的将代码提交然后集成到主干。
什么CD?
持续交付(Continuous Delivery)
持续交付是在CI的基础上,将集成到主干的代码,产出的可部署软件版本,部署到类生产环境进行测试验证,没问题在手动部署到生产环境。
持续部署(Continuous Deployment)
在持续交付基础上,部署到生产环境是自动操作的。
最终
为什么要做CI/CD?
- 提高效率,减少人工操作。
- 能够快速确定新代码和原有代码能否集成。
- 降低风险,快速发现错误。
- 加速软件发布周期。
需要什么?
1、具有版本管理功能的代码仓库管理系统(svn,gitlab,github)
2、CI工具(jenkins,gitlab-ci,drone)
3、自动化测试
4、自动化部署工具(ansible、puppet,saltstack)
基于容器实现CICD的优势
持续集成与持续交付的难点在于如何屏蔽不同语言、不同框架、不同系统之间的持续集成与持续交付流程的差异性。
- 标准化打包方式,解决应用部署依赖问题。
- 抹平环境差异
- 提升软件交付和迭代效率,还能避免交付内容不同导致的人为错误。
CICD工具
常见:
- Drone
- GitlabCI
- Jenkins
工具选型考虑点:
- 支持的代码库
- 易用性
- 插件生态
Drone
版本:1.0.0-rc2
GO语言开发的一个非常轻量级的开源CI工具,整个镜像大小只有60多M,原生支持docker并且完全基于docker的CI工具,甚至连插件都是容器形式,使用的CICD操作,编译,测试,构建全部是都在docker中进行。
部署方式:
- docker
- Kubernetes
项目地址
https://github.com/drone/drone
插件地址
http://plugins.drone.io/
文档地址
https://docs.drone.io/user-guide/
支持的代码仓库
易用性
Everything as docker,所有组件都是容器,包括你使用的插件
CI的执行是通过在代码仓库内定义个.drone.yml的文件,里面编写好对应的pipeline然后drone会去读取这个文件并执行。
让CI工作所需的步骤可归纳为
- 部署drone-server
- 添加.drone.yml到代码仓库的根目录
没有自己的用户系统及认证系统,通过OAuth2.0协议与对接的代码仓库进行用户登证及代码仓库同步。也就意味着你不需要在单独管理CI系统的用户。
UI整体简洁、美观。显示的是当前这个用户的项目信息,包括最新 commit信息及CICD
能清晰看见当前项目所有执行过的pipeline,以及这个pipeline是谁触发的。
单个pipeline的完整执行流程,及每个流程完整日志及消耗时间
Pipeline as code
pipeline编写,Pipeline as code 所有的操作都是通过代码实现,包括drone1.0版本pipeline语法更贴近Kubernetes yaml语法,使用起来更加高效。
1 | kind: pipeline |
插件比较丰富,函盖了目前主要的一些应用场景
当需要自定义插件时也非常简单,因为drone Everything as docker,插件也是通过以容器方式运行,然后将pipeline中自定义的环境变量传到这个容器中去执行。
如设计个slack插件
确定好需要传输的参数
确定好需要传输哪些参数比如Slack插件将需要webhook网址,频道和消息文本
1 | kind: pipeline |
输入参数作为环境变量传递给插件,前缀为PLUGIN_。上面示例中的输入参数将传递给插件,如下所示:
1 | PLUGIN_CHANNEL=general |
创建脚本
使用上一节中定义的输入参数替换
1 | #!/bin/sh |
构建插件
插件作为Docker镜像打包。创建一个Dockerfile,将先前创建的shell脚本添加到镜像。
1 | FROM alpine |
构建你的插件docker镜像
1 | docker build -t rancher/slack . |
总结:
优点:
- 非常轻量级,部署简单。
- 高效率(Pipeline as code)
- 原生支持docker( Everything as docker)
- 自定义插件和社区插件使用比较简单
- 难够针对pipeline的单个步骤多事件触发,或分支触发
1 | kind: pipeline |
通过使用插件能够触发其他CI服务
分布式
缺点:
- 高度依赖社区,文档不完善
- 插件质量参差不齐
- UI非常简陋
- 只支持对接一个代码仓库管理系统
GitlabCI
GitLab CI / CD是GitLab的一部分,gitlab 8.0版本开始新增的功能,是用Ruby和Go语言编写的。根我们通常的CI系统不一样通常的是一个master-slave架构,即使没有slave,master一样可以做CI,slave只是做为一个压力分担功能,gitlab是gitlab-server本身是不执行的,是通过api与GitLab Runner交互让gitlab-runner去执行CI。
GitLab Runner是一个go语言编写程序,它可以运行在任何可以运行go环境的平台上(二进制包、docker、k8s)
支持的代码仓库
易用性
同样也是Everything as docker
Gitlab CI 整个流程和 Drone 以及流行的 Travis CI 都是比较类似的,通过在项目中添加一个 .gitlab-ci.yml 的配置文件,配置文件中描述构建流水线来执行任务,对不同编程语言的编译通过不同的docker image实现。
CI的执行是通过在代码仓库内定义个.drone.yml的文件,里面编写好对应的pipeline然后drone会去读取这个文件并执行。
让CI工作所需的步骤可归纳为
- 添加.gitlab-ci.yml到存储库的根目录
- 配置一个Runner
Runner分两种类型,
Specific Runners:单个项目独享
Shared Runners:整个gitlab共享
Runner也可以选择CI方式:docker, parallels, shell, kubernetes, docker-ssh, ssh, virtualbox, docker+machine, docker-ssh+machine。如果是容器,代码编译的容器镜像需要提前在runner配置文件里面定义好。
1 | concurrent = 1 |
.gitlab-ci.yaml默认build, test和deploy三个stage
.gitlab-ci.yaml pipeline as code
当前项目下CI的执行记录。
整个pipeline的流程。
pipeline中的单个job执行过程详细信息输出,同时可以针对但个job进行重复执行。
项目CICD信息统计,按年、月、周汇总,报表展示
能直接对接现有Kubernetes集群,runner部署及pipeline CD流程。
插件生态
优点:
- 根gitlab集成度非常高
- 不需要部署有gitlab>=8.0 就能直接使用
- runner支持Autoscale
- UI可视化,可操作性强,可针对但个流程进行重复执行及报表展示
- CI完全属于你这个代码库
缺点:
- 没有插件,对接第三方系统需要自己实现
- 只能支持gitlab代码仓库
Jenkins
https://jenkins.io/
Jenkins是一款java开发的功能强大的CI工具,其前身为oracle的Hudson (软件)项目,2011年正式独立出来,Jenkins也是目前非常老牌和主流的CI工具,最早只能支持java语言,后续通过各类语言插件实现多种编程语言支持,Jenkins也是目前插件种类最丰富的CI工具。
易用性:
万物基于插件
提供功能强大的UI,大部分操作都可以通过UI完成,但UI样式不符合当前审美于是Jenkins又开发一个Blueocean皮肤插件
对不同编程语言、docker、k8s、代码仓库对接都是通过插件方式去实现支持,当然也可以直接在Jenkins宿主机上安装好,直接通过shell方式调用。
对代码仓库对Jenkins的对接,需要手动配置token,触发需要手动配置webhook和对应的触发事件。
支持master-slave的架构方式,同时也能通过对接Kubernetes实现一个slave的动态创建过程,当然此时你可以封装不同编程语言的编译环境镜像,或在一个镜像内实现全部的编程语言。
这样可以大节省资源和多语言环境下部署slave的难度。
Jenkins根drone和gitlab CI不一样,它拥有自己的用户认证系统,当然也可以去对接LDAP或AD。这样带来的问题是,权限管理很麻烦。
Jenkins可以通过UI去配置CI,也可以通过Jenkinsfile是Groovy语言语法
以下为例
代码仓库支持
支持常见代码仓库
插件生态
非常丰富的插件,覆盖面非常全
https://plugins.jenkins.io/
自定义插件学习成本较大,需要掌握JAVA语言
总结:
优点:
- 既有功能完善的UI,也支持pipeline as code
- 老牌CI工具文档很全面
- 插件生态丰富,基本上想要对接的工具都能找到对应插件
- 支持同时对接多个不同代码仓库
缺点:
- 对容器、k8s,代码仓库对接配置比较烦索
- 自定义插件难度大
- 独立的用户权限管理系统,多个开发团队共享一个master,会导致权限配置很困难,但若每个团队用各自Jenkins,又容易导致很多重复性工作
总结:
没有最好的工具,只有最合适的应用场景。
小团队,用的代码管理软件是gitlab,容器编排工具是Kubernetes建议用Gitlab-CI或Drone,开箱即用,可以减少很多工作量。
对插件有强烈需求,并且喜欢UI操作流水线的建议用Jenkins。
1 | https://mp.weixin.qq.com/s?__biz=MzIzNjUxMzk2NQ==&mid=2247489519&idx=1&sn=4b42ec3c14b7ba8e21c741413d7bd6e4&chksm=e8d7e82ddfa0613b85cf828443311af52890571052c6b6dce911c1cfe4e814dde28f8f98e086&scene=27#wechat_redirect |