kubernetes gitlab runner ci/cd 通知方案补充
回顾下之前的ci cd 布署方案,有以下几步
抽像为4个步骤
1 prepare: 根据提交分枝判断上线环境-生成相关的环境变量
2 pakage: 编译/打包项目,生成编译后可执行文件(部分项目项目不需要该步骤,例如python)
3 docker-build: docker 生成镜像并上传docker hub
4 k8s-deploy: 提交相应发布.yaml配置文件至k8s 上线/更新服务
实际项目触发ci/cd执行后缺少反馈,每个步骤都缺少反馈和异常感知,需要补充,最优先第4项k8s-deploy
gitlab 本身提供ci/cd结果的通知服务,可以集成。
由于代码/分枝merge触发ci/cd 相关研发人员本身就是关注gitlab runner的执行状态,从gitlab web ui 就能看到足够的信息
ci/cd通知执行成功,但第4项k8s-deploy只是把任务提交给k8s,什么时候才执行完?
方案只是把yaml提交给k8s,但k8s真正分配资源调度服务,细节里的pull image都有更细的流程
服务执行到cicd结束,只表示任务提给了k8s,但是这个任务真正执行完成,还是需要时间的,也是需要感知的
这个状态在目前不可见,只能通过其他手段查看,例如查k8s dashbard 或kubectl 命令
因此在k8s-deploy 实现状态感知,有一定必要性的,也是本篇博客的主要内容
这一步骤5,先命名 k8s-wait-finish
我们查看下服务的基本状态(大部分web类服务以deploy为主,以deploy布署2个节点为例)
Name: cicd-demo-prod
Namespace: common
CreationTimestamp: Wed, 22 Sep 2021 10:58:29 +0800
Labels: app=cicd-demo-prod
Annotations: deployment.kubernetes.io/revision: 3
kubernetes.io/change-cause:
kubectl set image deployment/cicd-demo-prod cicd-demo-prod=hub.intra.mlamp.cn/mz-bia/cicd-java-demo:prod --server=https://10.11....
Selector: app=cicd-demo-prod
Replicas: 2 desired | 1 updated | 3 total | 1 available | 2 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=cicd-demo-prod
date=1632279510
Containers:
cicd-demo-prod:
Image: yourimgae:prod
Port: <none>
Host Port: <none>
Command:
java
Args:
-Xms1g
-Xmx1g
-XX:+UseG1GC
-XX:G1ReservePercent=10
-XX:+UseStringDeduplication
-jar
-Dspring.profiles.active=prod
app.jar
Limits:
cpu: 1
memory: 2Gi
Requests:
cpu: 1
memory: 1Gi
Environment:
TZ: Asia/Shanghai
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available False MinimumReplicasUnavailable
Progressing True ReplicaSetUpdated
OldReplicaSets: cicd-demo-prod-6cf6885b58 (1/1 replicas created), cicd-demo-prod-589db644bf (1/1 replicas created)
NewReplicaSet: cicd-demo-prod-65d7d48cfc (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 39s deployment-controller Scaled up replica set cicd-demo-prod-6cf6885b58 to 2
Normal ScalingReplicaSet 38s deployment-controller Scaled up replica set cicd-demo-prod-589db644bf to 1
Normal ScalingReplicaSet 38s deployment-controller Scaled down replica set cicd-demo-prod-6cf6885b58 to 1
Normal ScalingReplicaSet 38s deployment-controller Scaled up replica set cicd-demo-prod-65d7d48cfc to 1
信息太多,与服务状态有关的以下几部分,这是在未执行完的状态
Replicas: 2 desired | 1 updated | 3 total | 1 available | 2 unavailable
Available False MinimumReplicasUnavailable
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
Available True MinimumReplicasAvailable
实际我们以Available True
来判断是否布署完成就足够了,代码精简自解释,用shell实现简单的grep+awk即可导出状态
echo只是打印些辅助排查的信息,可以按需多print些,这些在gitlab web后端可见
# 检查Available状态直到完成
until [ $(kubectl -n common describe deploy cicd-demo-prod | grep Available | head -n 1 |awk '{print $2}') = "true" ]; do
echo 'waiting deploy available,current status: ' $(kubectl -n common describe deploy cicd-demo-prod | grep Replicas | head -n 1 );
sleep 3;
done;
这一步实现k8s的布署过程可见,并轮训直到成功
新需求来了,项目上线,需要一个方法来实现通知,gitlab的通知较为简洁,也很难定制,要实现自定义的通知
另外,gitlab本身的通知,只在pipeline最终失败/成功时发送一次,有需要中间状态的通知的场景
通知方式也有必要扩充,邮件一般没人看,目前IM类的消息,钉钉,微信使用的较多
因此需要自定义实现一个更容易定制的场景,供执行结束发通知消息
这一步叫叫 6 message
这时有多种方法
1 curl调用+外部邮件api服务,提交curl/http api请求算是一类hook的接入点
2 直接执行脚本
问题是脚本在哪里执行,如果是另外起一个容器,则不受任何限制,给一个python的image,含发邮件服务即可
如果想在运行的服务里 执行,则有部分限制
1 执行环境问题,例如服务是个java服务,在java的pod里执行脚本,如果是shell curl通用信较好,如果是个python脚本,java的image里并没有python的环境,则同时打包java和python镜像于于臃肿
2 信息缺失,例如服务是个java服务,进入这个contain里,执行发邮件,发是可以,但是cicd相关的信息是没有的,需要提前传入即,打包进image存部分meta文件,env,cmd等
具体选择就结合现有组件和功能需求了
另外这一步并不只是执行是通知,可作为一个模版,当做通用一个hook,可以放在执行的每一阶段。
如果ci/cd的链路过长,可以在部分关键阶段,添加执行前后的通知。