Kubernetes下CICD工具的选型

什么是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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
kind: pipeline
name: test
steps:
- name: build
image: golang
commands:
- CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
- ./app
- name: publish
image: plugins/docker
settings:
repo: 172.31.164.66/library/test
registry: 172.31.164.66
insecure: true
tags: ${DRONE_COMMIT_MESSAGE}
trigger:
branch:
- dev
event:
- push

插件生态
http://plugins.drone.io/

插件比较丰富,函盖了目前主要的一些应用场景

当需要自定义插件时也非常简单,因为drone Everything as docker,插件也是通过以容器方式运行,然后将pipeline中自定义的环境变量传到这个容器中去执行。

如设计个slack插件
确定好需要传输的参数
确定好需要传输哪些参数比如Slack插件将需要webhook网址,频道和消息文本

1
2
3
4
5
6
7
8
9
10
kind: pipeline
name: default

steps:
- name: webhook
image: janecitizen/slack
settings:
webhook: https://hooks.slack.com/services/...
channel: general
text: hello

输入参数作为环境变量传递给插件,前缀为PLUGIN_。上面示例中的输入参数将传递给插件,如下所示:

1
2
3
PLUGIN_CHANNEL=general
PLUGIN_WEBHOOK=https://hooks.slack.com/services/...
PLUGIN_TEXT=hello

创建脚本
使用上一节中定义的输入参数替换

1
2
3
4
5
#!/bin/sh
curl -X POST \
-H 'Content-type: application/json' \
-d '{"text":"${PLUGIN_TEXT}","channel":"${PLUGIN_CHANNEL"}' \
${PLUGIN_WEBHOOK}

构建插件
插件作为Docker镜像打包。创建一个Dockerfile,将先前创建的shell脚本添加到镜像。

1
2
3
4
5
FROM alpine
ADD script.sh /bin/
RUN chmod +x /bin/script.sh
RUN apk -Uuv add curl ca-certificates
ENTRYPOINT /bin/script.sh

构建你的插件docker镜像

1
docker build -t rancher/slack .

总结:
优点:

  • 非常轻量级,部署简单。
  • 高效率(Pipeline as code)
  • 原生支持docker( Everything as docker)
  • 自定义插件和社区插件使用比较简单
  • 难够针对pipeline的单个步骤多事件触发,或分支触发
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
kind: pipeline
name: default
steps:
- name: build
image: golang
commands:
- go build
- go test -short

- name: integration
image: golang
commands:
- go test -v
when:
event:
- pull_request
branch:
- feature

通过使用插件能够触发其他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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "49faa2f8e25b"
url = "http://47.104.182.1:1080/"
token = "6ca2241a2924bd8763137d3bebf1c4"
executor = "docker"
[runners.docker]
tls_verify = false
image = "golang:1.10"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
shm_size = 0
[runners.cache]
Insecure = false

.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
2
https://mp.weixin.qq.com/s?__biz=MzIzNjUxMzk2NQ==&mid=2247489519&idx=1&sn=4b42ec3c14b7ba8e21c741413d7bd6e4&chksm=e8d7e82ddfa0613b85cf828443311af52890571052c6b6dce911c1cfe4e814dde28f8f98e086&scene=27#wechat_redirect
https://www.itread01.com/content/1531239621.html