Argo CD 优化以及使用钉钉接收状态消息

运维 系统运维
本文我们将介绍 Argo CD 通过 webhook 来优化应用检测、使用 Prometheus 监控 Argo CD,已经使用钉钉来接收 Argo CD 应用状态变化的消息通知。

[[410637]]

本文我们将介绍 Argo CD 通过 webhook 来优化应用检测、使用 Prometheus 监控 Argo CD,已经使用钉钉来接收 Argo CD 应用状态变化的消息通知。

webhook 配置

我们知道 Argo CD 会自动检查到配置的应用变化,这是因为 Argo CD 会每隔三分钟去轮询一次 Git 存储库来检测清单的变化,为了消除这种轮询延迟,我们也可以将 API 服务端配置为接收 webhook 事件的方式,这样就能实时获取到 Git 存储库中的变化了。Argo CD 支持来着 GitHub、GitLab、Bitbucket、Bitbucket Server 和 Gogs 的 Git webhook 事件,这里我们仍然以上面的 GitLab 为例来说明如果配置 Webhook。

进入到 GitLab 项目仓库 http://git.k8s.local/course/devops-demo-deploy 中配置 Webhooks:

图片

配置 Webhooks

Webhook 的地址填写 Argo CD 的 API 接口地址 http://argocd.k8s.local/api/webhook,下面的 Secret token 是可选的,建议添加上,任意定义即可。另外需要注意这里我们使用的是自签名的 https 证书,所以需要在下方去掉 启用SSL验证。

然后需要将上面配置的 Secret token 添加到 Argo CD 的 Secret 配置中:

  1. ➜  ~ kubectl edit secret argocd-secret -n argocd 
  2. apiVersion: v1 
  3. kind: Secret 
  4. metadata: 
  5.   name: argocd-secret 
  6.   namespace: argocd 
  7. type: Opaque 
  8. data: 
  9. ... 
  10. stringData: 
  11.   # gitlab webhook secret 
  12.   webhook.gitlab.secret: youdianzhishi 

保存后,更改会自动生效,我们可以在 GitLab 这边测试配置的 Webhook,查看 Argo CD 的 API 服务 Pod 日志,正常就可以收到 Push 事件了:

  1. ➜  ~ kubectl logs -f argocd-server-5cc96b75b4-zws2c -n argocd 
  2. time="2021-07-08T07:15:32Z" level=info msg="finished streaming call with code OK" grpc.code=OK grpc.method=Watch grpc.service=application.ApplicationService grpc.start_time="2021-07-08T07:15:01Z" grpc.time_ms=31314.16 span.kind=server system=grpc 
  3. time="2021-07-08T07:15:37Z" level=info msg="Received push event repo: http://git.k8s.local/course/devops-demo-deploy, revision: master, touchedHead: true" 
  4. time="2021-07-08T07:15:37Z" level=info msg="Requested app 'devops-demo' refresh" 

Metrics 指标

Argo CD 作为我们持续部署的关键组件,对于本身的监控也是非常有必要的,Argo CD 本身暴露了两组 Prometheus 指标,所以我们可以很方便对接监控报警。

默认情况下 Metrics 指标通过端点 argocd-metrics:8082/metrics 获取指标,包括:

  • 应用健康状态指标
  • 应用同步状态指标
  • 应用同步历史记录

关于 Argo CD 的 API 服务的 API 请求和响应相关的指标(请求数、响应码值等等...)通过端点 argocd-server-metrics:8083/metrics 获取。

然后可以根据我们自己的需求来配置指标抓取任务,比如我们是手动维护 Prometheus 的方式,并且开启了 endpoints 这种类型的服务自动发现,那么我们可以在几个指标的 Service 上添加 prometheus.io/scrape: "true" 这样的 annotation:

  1. ➜  ~ kubectl edit svc argocd-metrics -n argocd 
  2. apiVersion: v1 
  3. kind: Service 
  4. metadata: 
  5.   annotations: 
  6.     kubectl.kubernetes.io/last-applied-configuration: | 
  7.       {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"metrics","app.kubernetes.io/name":"argocd-metrics","app.kubernetes.io/part-of":"argocd"},"name":"argocd-metrics","namespace":"argocd"},"spec":{"ports":[{"name":"metrics","port":8082,"protocol":"TCP","targetPort":8082}],"selector":{"app.kubernetes.io/name":"argocd-application-controller"}}} 
  8.     prometheus.io/scrape: "true" 
  9.   creationTimestamp: "2021-07-03T06:16:47Z" 
  10.   labels: 
  11.     app.kubernetes.io/component: metrics 
  12.     app.kubernetes.io/name: argocd-metrics 
  13.     app.kubernetes.io/part-of: argocd 
  14. ...... 
  15. ➜  ~ kubectl edit svc argocd-server-metrics -n argocd 
  16. apiVersion: v1 
  17. kind: Service 
  18. metadata: 
  19.   annotations: 
  20.     kubectl.kubernetes.io/last-applied-configuration: | 
  21.       {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"server","app.kubernetes.io/name":"argocd-server-metrics","app.kubernetes.io/part-of":"argocd"},"name":"argocd-server-metrics","namespace":"argocd"},"spec":{"ports":[{"name":"metrics","port":8083,"protocol":"TCP","targetPort":8083}],"selector":{"app.kubernetes.io/name":"argocd-server"}}} 
  22.     prometheus.io/scrape: "true" 
  23.     prometheus.io/port: "8083"  # 指定8084端口为指标端口 
  24.   creationTimestamp: "2021-07-03T06:16:47Z" 
  25.   labels: 
  26.     app.kubernetes.io/component: server 
  27.     app.kubernetes.io/name: argocd-server-metrics 
  28.     app.kubernetes.io/part-of: argocd 
  29. ...... 
  30. ➜  ~ kubectl edit svc argocd-repo-server -n argocd 
  31. apiVersion: v1 
  32. kind: Service 
  33. metadata: 
  34.   annotations: 
  35.     kubectl.kubernetes.io/last-applied-configuration: | 
  36.       {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/component":"repo-server","app.kubernetes.io/name":"argocd-repo-server","app.kubernetes.io/part-of":"argocd"},"name":"argocd-repo-server","namespace":"argocd"},"spec":{"ports":[{"name":"server","port":8081,"protocol":"TCP","targetPort":8081},{"name":"metrics","port":8084,"protocol":"TCP","targetPort":8084}],"selector":{"app.kubernetes.io/name":"argocd-repo-server"}}} 
  37.     prometheus.io/scrape: "true" 
  38.     prometheus.io/port: "8084"  # 指定8084端口为指标端口 
  39.   creationTimestamp: "2021-07-03T06:16:47Z" 
  40.   labels: 
  41.     app.kubernetes.io/component: repo-server 
  42.     app.kubernetes.io/name: argocd-repo-server 
  43.     app.kubernetes.io/part-of: argocd 
  44. ...... 

配置完成后正常就可以自动发现上面的几个指标任务了:

argocd metrics

如果你使用的是 Prometheus Operator 方式,则可以手动创建 ServiceMonitor 对象来创建指标对象。

然后我们可以在 Grafana 中导入 Argo CD 的 Dashboard,地址:https://github.com/argoproj/argo-cd/blob/master/examples/dashboard.json

argocd grafana

消息通知

上面我们配置了 Argo CD 的监控指标,我们可以通过 AlertManager 来进行报警,但是有的时候我们可能希望将应用同步的状态发送到指定的渠道,这样方便我们了解部署流水线的结果,Argo CD 本身并没有提供内置的同步状态通知功能,但是我们可以与第三方的系统进行集成。

  • ArgoCD Notifications - Argo CD 通知系统,持续监控 Argo CD 应用程序,旨在与各种通知服务集成,例如 Slack、SMTP、Telegram、Discord 等。
  • Argo Kube Notifier - 通用 Kubernetes 资源控制器,允许监控任何 Kubernetes 资源并在满足配置的规则时发送通知。
  • Kube Watch - 可以向 Slack/hipchat/mattermost/flock 频道发布通知,它监视集群中的资源变更并通过 webhook 通知它们。

我们知道 Argo CD 本身是提供 resource hook 功能的,在资源同步前、中、后提供脚本来执行相应的动作, 那么想在资源同步后获取应用的状态,然后根据状态进行通知就非常简单了,通知可以是很简单的 curl 命令:

  • PreSync: 在同步之前执行相关操作,这个一般用于比如数据库操作等
  • Sync: 同步时执行相关操作,主要用于复杂应用的编排
  • PostSync: 同步之后且app状态为health执行相关操作
  • SyncFail: 同步失败后执行相关操作,同步失败一般不常见

但是对于 PostSync 可以发送成功的通知,但对于状态为 Processing 的无法判断,而且通知还是没有办法做到谁执行的 pipeline 谁接收通知的原则,没有办法很好地进行更细粒度的配置。ArgoCD Notifications 就可以来解决我们的问题,这里我们就以 ArgoCD Notifications 为例来说明如何使用钉钉来通知 Argo CD 的同步状态通知。

首先下载 ArgoCD Notifications 官方安装资源清单:

  1. ➜  ~ wget https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/stable/manifests/install.yaml 

然后我们需要在钉钉群中创建一个机器人,现在的机器人安全认证有几种方式,这里我们就选择关键字的方式,配置包含 ArgoCD 关键字的机器人:

add dingtalk robot

然后我们需要修改 install.yaml 文件中的 argocd-notifications-cm 添加相关配置才能支持钉钉。

  1. apiVersion: v1 
  2. kind: ConfigMap 
  3. metadata: 
  4.   name: argocd-notifications-cm 
  5. data: 
  6.   service.webhook.dingtalk: | 
  7.     url: https://oapi.dingtalk.com/robot/send?access_token=31429a8a66c8cd5beb7c4295ce592ac3221c47152085da006dd4556390d4d7e0 
  8.     headers: 
  9.       - name: Content-Type 
  10.         value: application/json 
  11.   context: | 
  12.     argocdUrl: http://argocd.k8s.local 
  13.   template.app-sync-change: | 
  14.     webhook: 
  15.       dingtalk: 
  16.         method: POST 
  17.         body: | 
  18.           { 
  19.                 "msgtype""markdown"
  20.                 "markdown": { 
  21.                     "title":"ArgoCD同步状态"
  22.                     "text""### ArgoCD同步状态\n> - app名称: {{.app.metadata.name}}\n> - app同步状态: {{ .app.status.operationState.phase}}\n> - 时间:{{.app.status.operationState.startedAt}}\n> - URL: [点击跳转ArgoCD]({{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true) \n" 
  23.                 } 
  24.             } 
  25.   trigger.on-deployed: | 
  26.     - description: Application is synced and healthy. Triggered once per commit
  27.       oncePer: app.status.sync.revision 
  28.       send: [app-sync-change]  # template names 
  29.       # trigger condition 
  30.       when: app.status.operationState.phase in ['Succeeded'and app.status.health.status == 'Healthy' 
  31.   trigger.on-health-degraded: | 
  32.     - description: Application has degraded 
  33.       send: [app-sync-change] 
  34.       when: app.status.health.status == 'Degraded' 
  35.   trigger.on-sync-failed: | 
  36.     - description: Application syncing has failed 
  37.       send: [app-sync-change]  # template names 
  38.       when: app.status.operationState.phase in ['Error''Failed'
  39.   trigger.on-sync-running: | 
  40.     - description: Application is being synced 
  41.       send: [app-sync-change]  # template names 
  42.       when: app.status.operationState.phase in ['Running'
  43.   trigger.on-sync-status-unknown: | 
  44.     - description: Application status is 'Unknown' 
  45.       send: [app-sync-change]  # template names 
  46.       when: app.status.sync.status == 'Unknown' 
  47.   trigger.on-sync-succeeded: | 
  48.     - description: Application syncing has succeeded 
  49.       send: [app-sync-change]  # template names 
  50.       when: app.status.operationState.phase in ['Succeeded'
  51.   subscriptions: | 
  52.     - recipients: [dingtalk]  # 可能有bug,正常应该是webhook:dingtalk 
  53.       triggers: [on-sync-running, on-deployed, on-sync-failed, on-sync-succeeded] 

其中 argocd-notifications-cm 中添加了一段如下所示的配置:

  1. subscriptions: | 
  2.   - recipients: [dingtalk] 
  3.     triggers: [on-sync-running, on-deployed, on-sync-failed, on-sync-succeeded] 

这个是为定义的触发器添加通知订阅,正常这里的 recipients 是 webhook:dingtalk,不知道是否是因为该版本有 bug,需要去掉前缀才能正常使用。

此外还可以添加一些条件判断,如下所示:

  1. subscriptions: 
  2. global subscription for all type of notifications 
  3. - recipients: 
  4.   - slack:test1 
  5.   - webhook:github 
  6. # subscription for on-sync-status-unknown trigger notifications 
  7. - recipients: 
  8.   - slack:test2 
  9.   - email:test@gmail.com 
  10.   triggeron-sync-status-unknown 
  11. global subscription restricted to applications with matching labels only 
  12. - recipients: 
  13.   - slack:test3 
  14.   selector: test=true 

然后可以根据不同的状态来配置不同的触发器,如下所示:

  1. trigger.on-sync-status-unknown: | 
  2.   - description: Application status is 'Unknown' 
  3.     send: [app-sync-change]  # template names 
  4.     when: app.status.sync.status == 'Unknown' 

该触发器定义包括名称、条件和通知模板引用:

  • send:表示通知内容使用的模板名称
  • description:当前触发器的描述信息
  • when:条件表达式,如果应发送通知,则返回 true

然后下面就是配置发送的消息通知模板:

  1. template.app-sync-change: | 
  2.   webhook: 
  3.     dingtalk: 
  4.       method: POST 
  5.       body: | 
  6.         { 
  7.               "msgtype""markdown"
  8.               "markdown": { 
  9.                   "title":"ArgoCD同步状态"
  10.                   "text""### ArgoCD同步状态\n> - app名称: {{.app.metadata.name}}\n> - app同步状态: {{ .app.status.operationState.phase}}\n> - 时间:{{.app.status.operationState.startedAt}}\n> - URL: [点击跳转ArgoCD]({{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true) \n" 
  11.               } 
  12.           } 

该模板用于生成通知内容,该模板利用 Golang 中的 html/template 包定义,允许定义通知标题和正文,可以重用,并且可以由多个触发器引用。每个模板默认都可以访问以下字段:

  • app:保存应用程序对象
  • context:是用户定义的字符串映射,可能包含任何字符串键和值
  • notificationType 保留通知服务类型名称,该字段可用于有条件地呈现服务特定字段

然后记得使用钉钉机器人的 webhook 地址替换掉上面的 argocd-notifications-secret 中的 url 地址。

配置完成后直接创建整个资源清单文件:

  1. ➜  ~ kubectl apply -f install.yaml 
  2. ➜  ~ kubectl get pods -n argocd 
  3. NAME                                               READY   STATUS    RESTARTS   AGE 
  4. argocd-application-controller-0                    1/1     Running   0          5d4h 
  5. argocd-dex-server-76ff776f97-ds7mm                 1/1     Running   0          5d4h 
  6. argocd-notifications-controller-5c548f8dc9-dx824   1/1     Running   0          9m22s 
  7. argocd-redis-747b678f89-w99wf                      1/1     Running   0          5d4h 
  8. argocd-repo-server-6fc4456c89-586zl                1/1     Running   0          5d4h 
  9. argocd-server-5cc96b75b4-zws2c                     1/1     Running   0          4d22h 

安装完成后重新去修改下应用代码触发整个 GitOps 流水线,正常就可以在钉钉中收到如下所示的消息通知了,如果没有正常收到消息,可以通过 argocd-notifications 的 CLI 命令进行调试:

  1. ➜  ~ kubectl exec -it argocd-notifications-controller-5c548f8dc9-dtq7h -n argocd -- /app/argocd-notifications template notify app-sync-change guestbook --recipient dingtalk 
  2. DEBU[0000] Sending request: POST /robot/send?access_token=31429a8a66c8cd5beb7c4295ce592ac3221c47152085da006dd4556390d4d7e0 HTTP/1.1 
  3. Host: oapi.dingtalk.com 
  4. Content-Type: application/json 
  5.  
  6.       "msgtype""markdown"
  7.       "markdown": { 
  8.           "title":"ArgoCD同步状态"
  9.           "text""### ArgoCD同步状态\n> - app名称: guestbook\n> - app同步状态: Succeeded\n> - 时间:2021-07-03T12:53:44Z\n> - URL: [点击跳转ArgoCD](http://argocd.k8s.local/applications/guestbook?operation=true) \n" 
  10.       } 
  11.   }  service=dingtalk 
  12. DEBU[0000] Received response: HTTP/2.0 200 OK 
  13. Cache-Control: no-cache 
  14. Content-Type: application/json 
  15. Date: Thu, 08 Jul 2021 11:45:12 GMT 
  16. Server: Tengine 
  17.  
  18. {"errcode":0,"errmsg":"ok"}  service=dingtalk 

钉钉通知

关于 ArgoCD Notification 的更多使用可以参考官方文档了解更多:https://argocd-notifications.readthedocs.io/en/stable/。

 

责任编辑:姜华 来源: k8s技术圈
相关推荐

2020-02-17 15:17:57

钉钉

2022-06-05 14:57:35

发送钉钉运维架构

2021-05-29 14:14:16

阿里云钉钉低代码开发

2018-08-10 12:56:00

大数据

2023-08-22 20:48:06

模型钉钉阿里云

2020-06-10 14:01:46

阿里云钉钉Windows

2022-12-06 08:00:16

awscli工具监控

2018-07-16 12:22:42

白熊视频

2016-09-06 18:20:43

存储

2018-04-18 07:20:12

微信腾讯阿里巴巴

2020-09-18 15:05:24

阿里政务钉钉

2020-04-10 16:41:27

微信钉钉APP

2016-01-21 11:05:38

太平洋电脑网

2018-08-07 11:51:27

钉钉

2016-05-13 16:54:06

阿里云办公

2023-09-27 08:24:49

2018-08-15 16:15:35

钉钉

2017-12-27 15:42:36

钉钉阿里巴巴数据

2018-08-02 16:11:12

2018-07-03 15:03:50

点赞
收藏

51CTO技术栈公众号