[k8s] ArgoCD Notification으로 Slack에 배포 알림 구성하기

빠른 개발 환경 흐름을 완성하기 위해서는, 빠르게 배포하고, 배포가 완료되었을때 그 시점을 잘 잡는 것이 중요하다. 하지만 기본 k8s 구성에서는 이걸 제때 잡기가 쉽지는 않다. 계속 kubectl로 모니터링을 할 수도 없는 노릇이니 말이다.

배포가 완료된 시점에 Slack 등을 통해서 완료를 확실하게 알 수 있다면 참 편할 것이다.

다행히도 ArgoCD를 쓸 경우에는 이런 부분이 좀 간편해진다. 자체적으로 알림용 도구를 지원하기 때문이다.

먼저 nofiticaion 리소스가 실행되고 있는지 확인한다.

kubectl get deployment -n argocd 2>/dev/null | grep notification || echo "ArgoCD namespace not found. Checking other namespaces..." && kubectl get deployment -A | grep argocd

ConfigMap을 작성하고

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd  # ArgoCD namespace로 변경
data:
  # Slack Bot Token 설정
  service.slack: |
    token: Slack 토큰

  # Deployment 완료 템플릿
  template.deployment-success: |
    message: |
*Deployment Completed*
      *Application:* {{.app.metadata.name}}
      {{- if .app.spec.destination.namespace}}
      *Namespace:* {{.app.spec.destination.namespace}}
      {{- end}}
      {{- if .app.spec.destination.server}}
      *Cluster:* {{.app.spec.destination.server}}
      {{- end}}
      *Revision:* {{substr 0 7 .app.status.sync.revision}}
      {{- if .app.status.operationState.operation.initiatedBy.username}}
      *Synced by:* {{.app.status.operationState.operation.initiatedBy.username}}
      {{- end}}
      {{- if .app.status.operationState.syncResult}}
      *Deployed Resources:*
      {{- range .app.status.operationState.syncResult.resources}}
      {{- if or (eq .kind "Deployment") (eq .kind "StatefulSet") (eq .kind "Application")}}
{{.kind}}/{{.name}}{{if .namespace}} ({{.namespace}}){{end}}
      {{- end}}
      {{- end}}
      {{- end}}

  # Deployment 실패 템플릿
  template.deployment-failed: |
    message: |
*Deployment Failed*
      *Application:* {{.app.metadata.name}}
      {{- if .app.spec.destination.namespace}}
      *Namespace:* {{.app.spec.destination.namespace}}
      {{- end}}
      {{- if .app.status.operationState.message}}
      *Error:* {{.app.status.operationState.message}}
      {{- end}}
      {{- if .app.status.operationState.syncResult}}
      *Failed Resources:*
      {{- range .app.status.operationState.syncResult.resources}}
      {{- if ne .status "Synced"}}
{{.kind}}/{{.name}}{{if .namespace}} ({{.namespace}}){{end}} - {{.status}}
      {{- end}}
      {{- end}}
      {{- end}}

  # Trigger 설정
  trigger.on-deployed: |
    - description: Application is synced and healthy
      send:
      - deployment-success
      when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
    oncePer: app.status.operationState.finishedAt

  trigger.on-deployment-failed: |
    - description: Application sync failed
      send:
      - deployment-failed
      when: app.status.operationState.phase in ['Error', 'Failed']
    oncePer: app.status.operationState.finishedAt

  # 기본 구독 설정
  subscriptions: |
    - recipients:
      - slack:슬랙 채널 ID
      triggers:
      - on-deployed
      - on-deployment-failed

그걸 적용한다.

kubectl apply -f argocd-notifications-config.yaml

그리고 기존 Application에 annotation을 추가해준다.
여기에 슬랙 채널 ID를 넣으면 된다.

kubectl patch app serverroom-apps -n argocd --type merge -p '{
  "metadata": {
    "annotations": {
      "notifications.argoproj.io/subscribe.on-deployed.slack": "채널ID",
      "notifications.argoproj.io/subscribe.on-deployment-failed.slack": "채널ID"
    }
  }
}'

그럼 이런 식으로 Deployment의 배포가 완료될때마다 - 정확히는 ArgoCD Sync가 될때마다 트리거되어서 알림이 전송될 것이다.

근데 이 방식에는 좀 단점이 있다. argocd가 Sync에 대한 정보를 상세하게 주지는 않는다는 것이다. 어떤 Deployment가 변경된 것인지 알 수가 없다.
그래서 이걸 잘 활용하려면, argocd Application을 시스템별로 쪼개서 Apps of App 패턴을 잘 구현해야 하고 개별 App 단위에 대해서 Noti를 받도록 구성해야 한다.

그래서 관리포인트가 좀 복잡해질 수 있다는 것이 단점이다.



참조
https://argo-cd.readthedocs.io/en/stable/operator-manual/notifications/