在之前一篇体验一把使用argocd对多k8s集群进行gitops的实践,在团队使用过程中会发现,argocd的sync状态跟app health状态是两个步骤,经常出现资源同步成功了但是deployment在k8s一起起不来,在argocd app status 一直都是Processing
,如何处理这种情况呢? argocd如何做 resource check,有没有必要引用notification机制
Resource Check
argocd官网文档: health
首先解决一下比较常见的 app的状态一直是Processing
这里就要区别说一下argocd的两个命令:
1 | # 1. argocd app sync |
作者最开始时,只使用app sync
,这就忽略了对整个app的health状态的判断,因此会出现CI/CD所有stage都成功了,但是pod一直处于重启状态
为解决这个问题,比较简单一点的做法就是在app sync
后使用app wait --health --timeout
来对check app health
,如果不成功,则pipeline exit 1
,这样可以在CI/CD阶段就暴露资源异常问题
但这也有明显的缺点: 如果资源异常,则必须要等timeout
时间之后才能发现,这个问题则可以结合k8s集群的监控发现,还能接受.
从官网的文档来,argocd本身提供了对k8s中的常用资源对象的健康检查,比如对于deployment,argocd详细地说明了如何判断其达到health状态的.
同时,也提供了自定义的检查机制,有2种形式,本人看了一下,第一种使用LUA语言写的,也就几行代码,倒也不难,作者没有采用,原因首先现在的业务大部分都是k8s常用资源对象,argocd本身支持度非常高,不需要
第二种则需要以特殊的目录结构来组织,作者也没有采用,实在是在开发端维护这些跟业务无法的文件,会引起复杂性.
取舍作者最后还是采用 app wait
的方式,这还有一个好处是,不需要做额外的工作就可以将通知精准地发送给对应的enduser,比如gitlab本身的ci/cd,如果整个pipeline的失败会直接给发起pipeline的人发送邮件
notifications
这里还是需要分析一下argocd里的通知机制, argocd本身不提供notification,要依赖第三方提供的机制, 参考notifications
resource hook
resource hook是argocd本身提供的功能,简单来说,就是在资源同步前,中,后提供hoo脚本来执行相应的动作, 那么想在资源同步后获取app的状态,然后根据状态进行通知就非常简单了,通知可以是很简单的curl命令
1 | PreSync: 在同步之前执行相关操作,这个一般用于比如数据库操作等 |
用的最多的就是PostSync,用来获取app是否成功启动,hook一般是放在job中执行,比如
1 | apiVersion: batch/v1 |
这个job比较容易理解,就是sync同步成功且app状态为health后发送一个slack消息
结合业务来说, 作者并没有采用这种方法来发送通知,原因如下:
- 对于PostSync可以发送成功的通知,但对于状态为Processing的无法判断
- 存量的业务都需要将这个job加入到git中,最大的考量在于,通知还是没有办法做到谁执行的pipeline,谁接收通知的原则,比如上面的通知收件人,没有办法很好地更细粒度地指定,要么指定一个组,大家都收,要么指定一个人,但是模块都是多人开发,只发给一个人不合适
argocd-notifications
argocd-notification是argocd自家开发的通知系统,也是argocd推荐之一
Argocd-notifications v1.0之前的版本与v1.0+版本有很大的不一样,建议大家认真阅读update
安装很简单,就一条命令
1 | kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/stable/manifests/install.yaml |
起来之后就一个controller应用,这里以邮件为例
首先,配置一下邮箱
1 | apiVersion: v1 |
然后添加相应状态通知:
1 | apiVersion: v1 |
如上面的配置,用于监控argocd同步状态为 Unknown的情况,发送邮件告警
当然, 在argocd部署应用的时候,也可以添加订阅者,直接在annotations中添加即可
1 | notifications.argoproj.io/subscribe.on-app-synched.eamil: [email protected] |
argocd-notification每隔一分钟就会扫描所有argocd app,感觉还是比较频繁,如果应用一多的话,不知道是不是影响性能,这个时间目前不支持通过参数覆盖,如果需要调整只能修改源码后重新编译
作者最后也没有采用这种形式,原因在于argocd-notification还是用于监控argocd 的sync状态,并不关心app 是否health
argo-kube-notifier
最后argocd也推荐使用argo-kube-notifier,但感觉这个跟argocd本身就没多大关系了,完且是发布后的health check,这个主要用于k8s集群应用状态的check,实现这个目的的组件很多,而且argo-kube-notifier还是没办法实现谁执行的pipeline,谁接收通知的原则
综上,还是直接使用argo app wait
简单粗暴,加两行代码,贴合需求
参考文章:
- https://izsk.me/2020/12/04/argoCD-Usage/
- https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/webhook.md
- https://github.com/argoproj-labs/argocd-notifications/blob/d0da61d206/docs/upgrading/0.x-1.0.md
- https://www.jianshu.com/p/a0613951c4b4
- https://argoproj.github.io/argo-cd/operator-manual/health/
- https://argoproj.github.io/argo-cd/operator-manual/notifications/