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后端可见Screen Shot 2021-09-23 at 11.00.59 AM

# 检查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的链路过长,可以在部分关键阶段,添加执行前后的通知。

原文地址:https://www.cnblogs.com/zihunqingxin/p/15323371.html