这是一个演示 Tekton CICD 的 demo。下面我们将从搭建本地 k8s 集群开始,同步镜像至国内并部署 Tekton,一步一步实现一个 CICD 流水线。实现更新代码自动触发流水线,构建镜像推送到目标仓库,并更新 deployment 镜像滚动更新应用,最后钉钉机器人通知到群聊。
- Tekton CICD Demo
Created by gh-md-toc
我心目中理想的CICD工具应该包含以下特性:
- 声明式配置,新增配置不需要在UI上操作,便于迁移,可使用git版本控制
- 配置与项目代码解耦,统一集中管理
- 灵活易扩展
Gitlab 和 Github 的 CICD 都是在当前 repo 中存放配置,对于开源项目一般就一个 repo 倒也没什么,但是在公司内部往往有很多服务很多 repo,配置散落在各个 repo 中,不方便统筹管理。
Jenkins 虽然可以将 Jenkinsfile 脚本集中管理,但针对每个项目还需要在 UI 上配置。Jenkins 也有相关插件 configuration-as-code-plugin,没用过就不评价了。
而 Tekton 所有配置都是以 k8s 式 Yaml 文件形式存在,即使换了一个集群,只需要应用 Yaml 配置即可无缝迁移。
- 完成以下步骤需要 k8s 基础使用能力
- k8s server version >= v1.15
- 以下命令中
alias kc=kubectl
- Tekton 的一些概念和资源在此不再赘述,请查阅官方文档:https://tekton.dev/docs/pipelines/
- 以下步骤在 macOS 10.15 上测试通过,一些命令在 Windows 上可能没有。
- registry.cn-huhehaote.aliyuncs.com/feng-566/ 旗下镜像均可公开访问,但是推送镜像需要认证。所以需要一个镜像仓库用于推送制品镜像,推荐阿里云镜像仓库注册账号即可免费使用。
- 接收 github webhook 需要一个拥有公网 IP 的服务器。如果没有,可使用 pull 模式替代。
- 出现问题请先查看 问题排查
使用 kind 创建测试集群。如果你已有 k8s 集群可跳过此步。
cat <<EOF >kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
EOF
kind create cluster --config ./kind-config.yaml
由于 Tekton 镜像都是在 gcr.io 上,需要 VPN 才能拉取,所以第一步需要将镜像同步至国内。这里我写了脚本(./src/sync/main.go)将镜像都同步至阿里云镜像仓库,并设为公开访问,如无必要可跳过此步。
make sync
部署 pipeline、trigger、dashboard 三个组件。
kc apply -f ./src/sync/dst
check:
kc get po
测试 demo,用于后面流水线滚动更新。
kc apply -f ./demo/go-echo/deploy/deploy.yaml
创建 Task 和 Pipeline 资源,每个 Task 为一个独立任务,Pipeline 则是将多个 Task 串成流水线。
更多 Task 例子可以在官方仓库找到:https://github.com/tektoncd/catalog
./manifests/pipeline/sercret.yaml
配置 github 和 docker registry。
将其中url, username, password 修改为你自己的 access token。
./manifests/resource/cluster-kind.yaml
配置部署时 kubectl 使用的配置。
将其修改为你本地 kind 集群的 kubeconfig。
./manifests/pipeline/notify.yaml
配置执行成功后聊天机器人通知地址,可接入钉钉或企业微信。
钉钉机器人文档:https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq
大家可自行创建团队测试机器人,不需要真实企业认证。
kc apply -f ./manifests/pipeline
kc apply -f ./manifests/resource
手动执行 PipelineRun,测试 pipeline 流程。
kc apply -f ./manifests/test/pipeline-run-demo.yaml
check:
kc get pr
通过 dashboard 我们可以查看流水线执行状态。由于 kind 网络隔离的原因,此处我们使用 kc port-forward 将端口暴露出来。
kc port-forward svc/tekton-dashboard 9097
# new terminal session
# 打开浏览器
open http://localhost:9097/#/namespaces/tekton-pipelines/pipelineruns
流水线执行成功实例:
前面的步骤中,我们用手动的方式执行了 pipeline,下面我们配置 Tekton triggers,通过 webhok 的方式自动执行。
Tekton trigger 组件是用来接收 webhook,做一些校验,过滤,参数绑定等前处理,然后帮你自动创建 PipelineRun 等资源执行流水线。
kc apply -f ./manifests/triggers
接收 webhook 需要一个拥有公网 ip 的服务器,首先在 github repo 中配置 webhook。
webhook 地址为 http://<your-remote-host>:9080/tekton-el
,勾选 Pull requests
,Pushs
events,token 为 ./manifests/triggers/webhook-token.yaml
中的值。
webhook 配置参考文档: https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/webhooks
webhook playload 数据结构: https://docs.github.com/en/free-pro-team@latest/developers/webhooks-and-events/webhook-events-and-payloads
将 kind 中 eventLister 端口暴露出来:
kc port-forward svc/el-demo-listener 9080:8080
服务端监听 0.0.0.0 需要 sshd 配置中包含 GatewayPorts clientspecified
,详见: https://serverfault.com/questions/861909/ssh-r-make-target-host-accept-connection-on-all-interfaces
将服务器 9080 端口转发到本地 9080 端口:
ssh -N -R 0.0.0.0:9080:localhost:9080 <user>@<your-remote-host> -p 22
check port connected:
nc -v <your-remote-host> 9080
部署成功后参考 测试 CICD 中步骤进行测试。
可通过查看 eventLister 日志进行 debug:
kc logs -l eventlistener=demo-listener
./manifests/triggers/print.yaml
print task 将 webhook head 及 body 打印出来。
Tekton 官方并没有提供类似 Jenkins 那种轮询 pull 检测 git repo,有新的 commit 则触发构建。理由是 pull 模式会对 git 造成较大压力。
但借助 k8s CronJob,自己实现 pull 模式。./src/pull
中的代码实现了一个简单的 pull 程序,定期检查对应仓库和分支有没有新的 commit,自动创建 PipelineRun。
./src/pull/deploy/configmap.yaml
为 PipelineRun 模板,修改 params 部分目标 IMAGE,NAME 等参数。
./src/pull/deploy/cronJob.yaml
为 Pull 脚本定时任务, 修改 args 部分需监听的 repo,branch 等参数。
应用:
kc apply -f ./src/common/rbac.yaml
kc apply -f ./src/pull/deploy
部署成功后参考 测试 CICD 中步骤进行测试。
提交 commit 进行测试:
git commit -a -m "build commit" --allow-empty && git push
Tekton 中的 PipelineRun 资源执行完后并不会自动清理,这里我们使用 CronJob 配合 ./src/cleanup
中的代码清理老旧资源。
应用:
kc apply -f ./src/common/rbac.yaml
kc apply -f ./src/cleanup/deploy
schedule: "0 3 * * *"
配置每天凌晨三点运行。
--range
参数配置清理多久之前(秒)的创建资源,默认:三天前。
--excluded-selector
参数配置需排除掉的 labelSelecor 。
build-image 使用 kaniko 在容器中构建,不依赖 docker daemon,镜像每次都会重新下载,所以 Dockerfile 中如果使用 golang:1.14 等体积很大的 dockerhub 镜像,因网络问题下载很慢甚至失败,会导致 build 超时,最好将镜像同步至内网。
检查 secret git-auth
是否配置正确。
检查 secret docker-auth
是否配置正确。pipeline 中推送镜像地址是否改为你个人镜像仓库地址。
部分任务配置了 securityContext.runAsUser: 0
,在 openshift 运行需要配置 scc=anyuid
。 参考:
https://docs.openshift.com/container-platform/4.6/authentication/managing-security-context-constraints.html
- pipeline 中途失败无法发送机器人通知