Argo CD 優(yōu)化以及使用釘釘接收狀態(tài)消息
本文我們將介紹 Argo CD 通過(guò) webhook 來(lái)優(yōu)化應(yīng)用檢測(cè)、使用 Prometheus 監(jiān)控 Argo CD,已經(jīng)使用釘釘來(lái)接收 Argo CD 應(yīng)用狀態(tài)變化的消息通知。
webhook 配置
我們知道 Argo CD 會(huì)自動(dòng)檢查到配置的應(yīng)用變化,這是因?yàn)?Argo CD 會(huì)每隔三分鐘去輪詢一次 Git 存儲(chǔ)庫(kù)來(lái)檢測(cè)清單的變化,為了消除這種輪詢延遲,我們也可以將 API 服務(wù)端配置為接收 webhook 事件的方式,這樣就能實(shí)時(shí)獲取到 Git 存儲(chǔ)庫(kù)中的變化了。Argo CD 支持來(lái)著 GitHub、GitLab、Bitbucket、Bitbucket Server 和 Gogs 的 Git webhook 事件,這里我們?nèi)匀灰陨厦娴?GitLab 為例來(lái)說(shuō)明如果配置 Webhook。
進(jìn)入到 GitLab 項(xiàng)目倉(cāng)庫(kù) http://git.k8s.local/course/devops-demo-deploy 中配置 Webhooks:

配置 Webhooks
Webhook 的地址填寫 Argo CD 的 API 接口地址 http://argocd.k8s.local/api/webhook,下面的 Secret token 是可選的,建議添加上,任意定義即可。另外需要注意這里我們使用的是自簽名的 https 證書,所以需要在下方去掉 啟用SSL驗(yàn)證。
然后需要將上面配置的 Secret token 添加到 Argo CD 的 Secret 配置中:
- ➜ ~ kubectl edit secret argocd-secret -n argocd
- apiVersion: v1
- kind: Secret
- metadata:
- name: argocd-secret
- namespace: argocd
- type: Opaque
- data:
- ...
- stringData:
- # gitlab webhook secret
- webhook.gitlab.secret: youdianzhishi
保存后,更改會(huì)自動(dòng)生效,我們可以在 GitLab 這邊測(cè)試配置的 Webhook,查看 Argo CD 的 API 服務(wù) Pod 日志,正常就可以收到 Push 事件了:
- ➜ ~ kubectl logs -f argocd-server-5cc96b75b4-zws2c -n argocd
- 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
- 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"
- time="2021-07-08T07:15:37Z" level=info msg="Requested app 'devops-demo' refresh"
Metrics 指標(biāo)
Argo CD 作為我們持續(xù)部署的關(guān)鍵組件,對(duì)于本身的監(jiān)控也是非常有必要的,Argo CD 本身暴露了兩組 Prometheus 指標(biāo),所以我們可以很方便對(duì)接監(jiān)控報(bào)警。
默認(rèn)情況下 Metrics 指標(biāo)通過(guò)端點(diǎn) argocd-metrics:8082/metrics 獲取指標(biāo),包括:
- 應(yīng)用健康狀態(tài)指標(biāo)
- 應(yīng)用同步狀態(tài)指標(biāo)
- 應(yīng)用同步歷史記錄
關(guān)于 Argo CD 的 API 服務(wù)的 API 請(qǐng)求和響應(yīng)相關(guān)的指標(biāo)(請(qǐng)求數(shù)、響應(yīng)碼值等等...)通過(guò)端點(diǎn) argocd-server-metrics:8083/metrics 獲取。
然后可以根據(jù)我們自己的需求來(lái)配置指標(biāo)抓取任務(wù),比如我們是手動(dòng)維護(hù) Prometheus 的方式,并且開啟了 endpoints 這種類型的服務(wù)自動(dòng)發(fā)現(xiàn),那么我們可以在幾個(gè)指標(biāo)的 Service 上添加 prometheus.io/scrape: "true" 這樣的 annotation:
- ➜ ~ kubectl edit svc argocd-metrics -n argocd
- apiVersion: v1
- kind: Service
- metadata:
- annotations:
- kubectl.kubernetes.io/last-applied-configuration: |
- {"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"}}}
- prometheus.io/scrape: "true"
- creationTimestamp: "2021-07-03T06:16:47Z"
- labels:
- app.kubernetes.io/component: metrics
- app.kubernetes.io/name: argocd-metrics
- app.kubernetes.io/part-of: argocd
- ......
- ➜ ~ kubectl edit svc argocd-server-metrics -n argocd
- apiVersion: v1
- kind: Service
- metadata:
- annotations:
- kubectl.kubernetes.io/last-applied-configuration: |
- {"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"}}}
- prometheus.io/scrape: "true"
- prometheus.io/port: "8083" # 指定8084端口為指標(biāo)端口
- creationTimestamp: "2021-07-03T06:16:47Z"
- labels:
- app.kubernetes.io/component: server
- app.kubernetes.io/name: argocd-server-metrics
- app.kubernetes.io/part-of: argocd
- ......
- ➜ ~ kubectl edit svc argocd-repo-server -n argocd
- apiVersion: v1
- kind: Service
- metadata:
- annotations:
- kubectl.kubernetes.io/last-applied-configuration: |
- {"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"}}}
- prometheus.io/scrape: "true"
- prometheus.io/port: "8084" # 指定8084端口為指標(biāo)端口
- creationTimestamp: "2021-07-03T06:16:47Z"
- labels:
- app.kubernetes.io/component: repo-server
- app.kubernetes.io/name: argocd-repo-server
- app.kubernetes.io/part-of: argocd
- ......
配置完成后正常就可以自動(dòng)發(fā)現(xiàn)上面的幾個(gè)指標(biāo)任務(wù)了:
argocd metrics
如果你使用的是 Prometheus Operator 方式,則可以手動(dòng)創(chuàng)建 ServiceMonitor 對(duì)象來(lái)創(chuàng)建指標(biāo)對(duì)象。
然后我們可以在 Grafana 中導(dǎo)入 Argo CD 的 Dashboard,地址:https://github.com/argoproj/argo-cd/blob/master/examples/dashboard.json
argocd grafana
消息通知
上面我們配置了 Argo CD 的監(jiān)控指標(biāo),我們可以通過(guò) AlertManager 來(lái)進(jìn)行報(bào)警,但是有的時(shí)候我們可能希望將應(yīng)用同步的狀態(tài)發(fā)送到指定的渠道,這樣方便我們了解部署流水線的結(jié)果,Argo CD 本身并沒有提供內(nèi)置的同步狀態(tài)通知功能,但是我們可以與第三方的系統(tǒng)進(jìn)行集成。
- ArgoCD Notifications - Argo CD 通知系統(tǒng),持續(xù)監(jiān)控 Argo CD 應(yīng)用程序,旨在與各種通知服務(wù)集成,例如 Slack、SMTP、Telegram、Discord 等。
- Argo Kube Notifier - 通用 Kubernetes 資源控制器,允許監(jiān)控任何 Kubernetes 資源并在滿足配置的規(guī)則時(shí)發(fā)送通知。
- Kube Watch - 可以向 Slack/hipchat/mattermost/flock 頻道發(fā)布通知,它監(jiān)視集群中的資源變更并通過(guò) webhook 通知它們。
我們知道 Argo CD 本身是提供 resource hook 功能的,在資源同步前、中、后提供腳本來(lái)執(zhí)行相應(yīng)的動(dòng)作, 那么想在資源同步后獲取應(yīng)用的狀態(tài),然后根據(jù)狀態(tài)進(jìn)行通知就非常簡(jiǎn)單了,通知可以是很簡(jiǎn)單的 curl 命令:
- PreSync: 在同步之前執(zhí)行相關(guān)操作,這個(gè)一般用于比如數(shù)據(jù)庫(kù)操作等
- Sync: 同步時(shí)執(zhí)行相關(guān)操作,主要用于復(fù)雜應(yīng)用的編排
- PostSync: 同步之后且app狀態(tài)為health執(zhí)行相關(guān)操作
- SyncFail: 同步失敗后執(zhí)行相關(guān)操作,同步失敗一般不常見
但是對(duì)于 PostSync 可以發(fā)送成功的通知,但對(duì)于狀態(tài)為 Processing 的無(wú)法判斷,而且通知還是沒有辦法做到誰(shuí)執(zhí)行的 pipeline 誰(shuí)接收通知的原則,沒有辦法很好地進(jìn)行更細(xì)粒度的配置。ArgoCD Notifications 就可以來(lái)解決我們的問(wèn)題,這里我們就以 ArgoCD Notifications 為例來(lái)說(shuō)明如何使用釘釘來(lái)通知 Argo CD 的同步狀態(tài)通知。
首先下載 ArgoCD Notifications 官方安裝資源清單:
- ➜ ~ wget https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/stable/manifests/install.yaml
然后我們需要在釘釘群中創(chuàng)建一個(gè)機(jī)器人,現(xiàn)在的機(jī)器人安全認(rèn)證有幾種方式,這里我們就選擇關(guān)鍵字的方式,配置包含 ArgoCD 關(guān)鍵字的機(jī)器人:
add dingtalk robot
然后我們需要修改 install.yaml 文件中的 argocd-notifications-cm 添加相關(guān)配置才能支持釘釘。
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: argocd-notifications-cm
- data:
- service.webhook.dingtalk: |
- url: https://oapi.dingtalk.com/robot/send?access_token=31429a8a66c8cd5beb7c4295ce592ac3221c47152085da006dd4556390d4d7e0
- headers:
- - name: Content-Type
- value: application/json
- context: |
- argocdUrl: http://argocd.k8s.local
- template.app-sync-change: |
- webhook:
- dingtalk:
- method: POST
- body: |
- {
- "msgtype": "markdown",
- "markdown": {
- "title":"ArgoCD同步狀態(tài)",
- "text": "### ArgoCD同步狀態(tài)\n> - app名稱: {{.app.metadata.name}}\n> - app同步狀態(tài): {{ .app.status.operationState.phase}}\n> - 時(shí)間:{{.app.status.operationState.startedAt}}\n> - URL: [點(diǎn)擊跳轉(zhuǎn)ArgoCD]({{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true) \n"
- }
- }
- trigger.on-deployed: |
- - description: Application is synced and healthy. Triggered once per commit.
- oncePer: app.status.sync.revision
- send: [app-sync-change] # template names
- # trigger condition
- when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
- trigger.on-health-degraded: |
- - description: Application has degraded
- send: [app-sync-change]
- when: app.status.health.status == 'Degraded'
- trigger.on-sync-failed: |
- - description: Application syncing has failed
- send: [app-sync-change] # template names
- when: app.status.operationState.phase in ['Error', 'Failed']
- trigger.on-sync-running: |
- - description: Application is being synced
- send: [app-sync-change] # template names
- when: app.status.operationState.phase in ['Running']
- trigger.on-sync-status-unknown: |
- - description: Application status is 'Unknown'
- send: [app-sync-change] # template names
- when: app.status.sync.status == 'Unknown'
- trigger.on-sync-succeeded: |
- - description: Application syncing has succeeded
- send: [app-sync-change] # template names
- when: app.status.operationState.phase in ['Succeeded']
- subscriptions: |
- - recipients: [dingtalk] # 可能有bug,正常應(yīng)該是webhook:dingtalk
- triggers: [on-sync-running, on-deployed, on-sync-failed, on-sync-succeeded]
其中 argocd-notifications-cm 中添加了一段如下所示的配置:
- subscriptions: |
- - recipients: [dingtalk]
- triggers: [on-sync-running, on-deployed, on-sync-failed, on-sync-succeeded]
這個(gè)是為定義的觸發(fā)器添加通知訂閱,正常這里的 recipients 是 webhook:dingtalk,不知道是否是因?yàn)樵摪姹居? bug,需要去掉前綴才能正常使用。
此外還可以添加一些條件判斷,如下所示:
- subscriptions:
- # global subscription for all type of notifications
- - recipients:
- - slack:test1
- - webhook:github
- # subscription for on-sync-status-unknown trigger notifications
- - recipients:
- - slack:test2
- - email:test@gmail.com
- trigger: on-sync-status-unknown
- # global subscription restricted to applications with matching labels only
- - recipients:
- - slack:test3
- selector: test=true
然后可以根據(jù)不同的狀態(tài)來(lái)配置不同的觸發(fā)器,如下所示:
- trigger.on-sync-status-unknown: |
- - description: Application status is 'Unknown'
- send: [app-sync-change] # template names
- when: app.status.sync.status == 'Unknown'
該觸發(fā)器定義包括名稱、條件和通知模板引用:
- send:表示通知內(nèi)容使用的模板名稱
- description:當(dāng)前觸發(fā)器的描述信息
- when:條件表達(dá)式,如果應(yīng)發(fā)送通知,則返回 true
然后下面就是配置發(fā)送的消息通知模板:
- template.app-sync-change: |
- webhook:
- dingtalk:
- method: POST
- body: |
- {
- "msgtype": "markdown",
- "markdown": {
- "title":"ArgoCD同步狀態(tài)",
- "text": "### ArgoCD同步狀態(tài)\n> - app名稱: {{.app.metadata.name}}\n> - app同步狀態(tài): {{ .app.status.operationState.phase}}\n> - 時(shí)間:{{.app.status.operationState.startedAt}}\n> - URL: [點(diǎn)擊跳轉(zhuǎn)ArgoCD]({{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true) \n"
- }
- }
該模板用于生成通知內(nèi)容,該模板利用 Golang 中的 html/template 包定義,允許定義通知標(biāo)題和正文,可以重用,并且可以由多個(gè)觸發(fā)器引用。每個(gè)模板默認(rèn)都可以訪問(wèn)以下字段:
- app:保存應(yīng)用程序?qū)ο?/li>
- context:是用戶定義的字符串映射,可能包含任何字符串鍵和值
- notificationType 保留通知服務(wù)類型名稱,該字段可用于有條件地呈現(xiàn)服務(wù)特定字段
然后記得使用釘釘機(jī)器人的 webhook 地址替換掉上面的 argocd-notifications-secret 中的 url 地址。
配置完成后直接創(chuàng)建整個(gè)資源清單文件:
- ➜ ~ kubectl apply -f install.yaml
- ➜ ~ kubectl get pods -n argocd
- NAME READY STATUS RESTARTS AGE
- argocd-application-controller-0 1/1 Running 0 5d4h
- argocd-dex-server-76ff776f97-ds7mm 1/1 Running 0 5d4h
- argocd-notifications-controller-5c548f8dc9-dx824 1/1 Running 0 9m22s
- argocd-redis-747b678f89-w99wf 1/1 Running 0 5d4h
- argocd-repo-server-6fc4456c89-586zl 1/1 Running 0 5d4h
- argocd-server-5cc96b75b4-zws2c 1/1 Running 0 4d22h
安裝完成后重新去修改下應(yīng)用代碼觸發(fā)整個(gè) GitOps 流水線,正常就可以在釘釘中收到如下所示的消息通知了,如果沒有正常收到消息,可以通過(guò) argocd-notifications 的 CLI 命令進(jìn)行調(diào)試:
- ➜ ~ kubectl exec -it argocd-notifications-controller-5c548f8dc9-dtq7h -n argocd -- /app/argocd-notifications template notify app-sync-change guestbook --recipient dingtalk
- DEBU[0000] Sending request: POST /robot/send?access_token=31429a8a66c8cd5beb7c4295ce592ac3221c47152085da006dd4556390d4d7e0 HTTP/1.1
- Host: oapi.dingtalk.com
- Content-Type: application/json
- {
- "msgtype": "markdown",
- "markdown": {
- "title":"ArgoCD同步狀態(tài)",
- "text": "### ArgoCD同步狀態(tài)\n> - app名稱: guestbook\n> - app同步狀態(tài): Succeeded\n> - 時(shí)間:2021-07-03T12:53:44Z\n> - URL: [點(diǎn)擊跳轉(zhuǎn)ArgoCD](http://argocd.k8s.local/applications/guestbook?operation=true) \n"
- }
- } service=dingtalk
- DEBU[0000] Received response: HTTP/2.0 200 OK
- Cache-Control: no-cache
- Content-Type: application/json
- Date: Thu, 08 Jul 2021 11:45:12 GMT
- Server: Tengine
- {"errcode":0,"errmsg":"ok"} service=dingtalk
釘釘通知
關(guān)于 ArgoCD Notification 的更多使用可以參考官方文檔了解更多:https://argocd-notifications.readthedocs.io/en/stable/。