lapee79's Tech Blog

lapee79의 기술 지식 창고.

Alertmanager로 Prometheus의 알람을 Microsoft Teams에 발송하기

Alertmanager를 사용하면 Prometheus에서 발생한 알람을 이메일, Slack, SMS 등의 클라이언트에 발송할 수 있습니다. 하지만 필자가 일하는 회사에서는 Slack이 아니라 Microsoft Teams를 사용하고 있었습니다. Alertmanager에서는 이메일, HipChat, PagerDuty, Slack 등은 네이티브로 지원하지만 Microsoft Teams는 Webhook을 이용하여 써드파티 도구를 사용해야 합니다. 여기에서는 Kubernetes 클러스터 모니터링을 위해 Prometheus operator가 설치된 상황에서 Microsoft Teams로 알람을 수신하여 모니터링할 수 있는 환경을 구축해보겠습니다.

Microsoft Teams에서 Incoming Webhook URL 받기

여기에서는 Teams의 기본적인 내용은 스킵하고 채널에 Incoming Webhook을 구성하는 단계부터 설명하도록 하겠습니다.

먼저 알람을 받기 위한 채널에서 ... 을 클릭한 다음 커넥터를 선택합니다.

teams-select-connector

커넥터 리스트에서 Incoming Webhook 커넥터를 선택합니다.

select-incomingwebhook

나중에 webhook을 식별할 수 있도록 이름을 입력합니다. 그리고

naming-incommingwebhook

“만들기” 버튼을 클릭하면 메시지를 이 채널에 게시하는데 사용될 수 있는 webhook URL이 생성됩니다. 이 URL을 잘 복사해둡니다.

webhook-url

Prometheus operator의 Alertmanager 설정

이제 Alertmanager에서 Microsoft Teams 서드파티 도구로 알람을 전송할 수 있도록 alertmanager.yaml 설정 파일을 생성합니다.

global:
  resolve_timeout: 5m
receivers:
- name: prometheus-msteams
  webhook_configs:
  - url: "http://prometheus-msteams:2000/alertmanager"
    send_resolved: true
route:
  group_by:
  - job
  group_interval: 5m
  group_wait: 30s
  receiver: prometheus-msteams
  repeat_interval: 12h
  routes:
  - match:
      alertname: Watchdog
    receiver: prometheus-msteams

위 파일에서는 receiver를 webhook으로 설정하여 이름을 prometheus-msteams으로 지정했습니다. 이제 생성된 alertmanager.yaml 파일을 base64로 인코딩합니다.

cat alertmanager.yaml | base64
Z2xvYmFsOgogIHJlc29sdmVfdGltZW91dDogNW0KcmVjZWl2ZXJzOgotIG5hbWU6IHByb21ldGhldXMtbXN0ZWFtcwogIHdlYmhvb2tfY29uZmlnczoKICAtIHVybDogImh0dHA6Ly9wcm9tZXRoZXVzLW1zdGVhbXM6MjAwMC9hbGVydG1hbmFnZXIiCiAgICBzZW5kX3Jlc29sdmVkOiB0cnVlCnJvdXRlOgogIGdyb3VwX2J5OgogIC0gam9iCiAgZ3JvdXBfaW50ZXJ2YWw6IDVtCiAgZ3JvdXBfd2FpdDogMzBzCiAgcmVjZWl2ZXI6IHByb21ldGhldXMtbXN0ZWFtcwogIHJlcGVhdF9pbnRlcnZhbDogMTJoCiAgcm91dGVzOgogIC0gbWF0Y2g6CiAgICAgIGFsZXJ0bmFtZTogV2F0Y2hkb2cKICAgIHJlY2VpdmVyOiBwcm9tZXRoZXVzLW1zdGVhbXMK

위에서 생성된 base64로 암호화된 문자열을 가지고 Prometheus operator의 Alertmanager에서 사용될 수 있도록 Secret 오브젝트를 생성해서 Kubernetes에 적용합니다.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: alertmanager-main
  namespace: monitoring
type: Opaque
data:
  alertmanager.yaml: Z2xvYmFsOgogIHJlc29sdmVfdGltZW91dDogNW0KcmVjZWl2ZXJzOgotIG5hbWU6IHByb21ldGhldXMtbXN0ZWFtcwogIHdlYmhvb2tfY29uZmlnczoKICAtIHVybDogImh0dHA6Ly9wcm9tZXRoZXVzLW1zdGVhbXM6MjAwMC9hbGVydG1hbmFnZXIiCiAgICBzZW5kX3Jlc29sdmVkOiB0cnVlCnJvdXRlOgogIGdyb3VwX2J5OgogIC0gam9iCiAgZ3JvdXBfaW50ZXJ2YWw6IDVtCiAgZ3JvdXBfd2FpdDogMzBzCiAgcmVjZWl2ZXI6IHByb21ldGhldXMtbXN0ZWFtcwogIHJlcGVhdF9pbnRlcnZhbDogMTJoCiAgcm91dGVzOgogIC0gbWF0Y2g6CiAgICAgIGFsZXJ0bmFtZTogV2F0Y2hkb2cKICAgIHJlY2VpdmVyOiBwcm9tZXRoZXVzLW1zdGVhbXMK
EOF

이제 Alertmanager는 webhook을 통해 알람을 발송할 준비가 되었습니다.

멀티 클러스터 환경에서 클러스터 식별 Label 생성

다수의 Kubernetes 클러스터를 운영하는 상황에서는 어떤 클러스터에서 알람이 발생된 것인지 구분할 수 있어야 합니다. 따라서 클러스터를 구분할 수 있는 Label이 알람에 추가될 수 있도록 Prometheus에 externalLabelscluster: <CLUSTER_NAME> 형태로 정보를 추가해줍니다.

cat <<EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  labels:
    prometheus: k8s
  name: k8s
  namespace: monitoring
spec:
  alerting:
    alertmanagers:
    - name: alertmanager-main
      namespace: monitoring
      port: web
  baseImage: quay.io/prometheus/prometheus
  nodeSelector:
    beta.kubernetes.io/os: linux
  replicas: 2
  resources:
    requests:
      memory: 400Mi
  ruleSelector:
    matchLabels:
      prometheus: k8s
      role: alert-rules
  securityContext:
    fsGroup: 2000
    runAsNonRoot: true
    runAsUser: 1000
  serviceAccountName: prometheus-k8s
  serviceMonitorNamespaceSelector: {}
  serviceMonitorSelector: {}
  version: v2.7.2
  externalLabels:
    cluster: test

prometheus-msteams 설정 및 구성

이제 Prometheus에서 발생한 알람을 Microsoft Teams에 전달하는 prometheus-msteams를 설정하고 구성해봅시다.

chart download

repository를 clone합니다.

git clone https://github.com/bzon/prometheus-msteams
cd prometheus-msteams/chart

Microsoft Teams Message card template 수정

Microsoft Teams로 전송 시에 에러가 발생하지 않도록 기본 Microsoft Teams Message card template을 다음과 같이 수정합니다.

vim prometheus-msteams/card.tmpl
{{ define "teams.card" }}
{
  "@type": "MessageCard",
  "@context": "http://schema.org/extensions",
  "themeColor": "{{- if eq .Status "resolved" -}}2DC72D
                 {{- else if eq .Status "firing" -}}
                    {{- if eq .CommonLabels.severity "critical" -}}8C1A1A
                    {{- else if eq .CommonLabels.severity "warning" -}}FFA500
                    {{- else -}}808080{{- end -}}
                 {{- else -}}808080{{- end -}}",
  "summary": "{{- if eq .CommonAnnotations.summary "" -}}
                  {{- if eq .CommonAnnotations.message "" -}}
                    {{- js .CommonLabels.cluster | reReplaceAll "_" " " | reReplaceAll `\\'` "'" -}}
                  {{- else -}}
                    {{- js .CommonAnnotations.message | reReplaceAll "_" " " | reReplaceAll `\\'` "'" -}}
                  {{- end -}}
              {{- else -}}
                  {{- js .CommonAnnotations.summary | reReplaceAll "_" " " | reReplaceAll `\\'` "'" -}}
              {{- end -}}",
  "title": "Prometheus Alert ({{ .Status }})",
  "sections": [ {{$externalUrl := .ExternalURL}}
  {{- range $index, $alert := .Alerts }}{{- if $index }},{{- end }}
    {
      "activityTitle": "[{{ js $alert.Annotations.description |  reReplaceAll "_" " " | reReplaceAll `\\'` "'" }}]({{ $externalUrl }})",
      "facts": [
        {{- range $key, $value := $alert.Annotations }}
        {
          "name": "{{ $key }}",
          "value": "{{ js $value | reReplaceAll "_" " " | reReplaceAll `\\'` "'" }}"
        },
        {{- end -}}
        {{$c := counter}}{{ range $key, $value := $alert.Labels }}{{if call $c}},{{ end }}
        {
          "name": "{{ $key }}",
          "value": "{{ js $value | reReplaceAll "_" " " | reReplaceAll `\\'` "'" }}"
        }
        {{- end }}
      ],
      "markdown": true
    }
    {{- end }}
  ]
}
{{ end }}

helm template으로 Kubernetes에 배포

Microsoft Teams에서 얻은 Incoming Webhook URL을 설정 값으로 넘기면서 Kubernetes에 배포합니다.

helm template prometheus-msteams/ --name prometheus-msteams --set connectors.alertmanager=https://outlook.office.com/webhook/xxxx/xxxx | kubectl apply -f -
configmap/prometheus-msteams-config created
configmap/prometheus-msteams-card-template created
service/prometheus-msteams created
deployment.apps/prometheus-msteams created

수신된 알람 확인

이제 모든 설정이 완료되었으므로 알람이 발생하면 Microsoft Teams의 채널에 다음과 같이 알람을 받을 수 있을 것입니다.

teams-alert-message

comments powered by Disqus