AWS. EKS 그라파나 알람 설정하기
created Oct 10, 2022 | updated Dec 12, 2022
AWS EKS 모니터링을 위해 kube-prometheus-stack를 설치하면 기본적인 설정은 끝났다. 하지만 사람이 여러 대시보드를 주시하고 모니터링을 24시간 실시간으로 할 수 없기 때문에 주요 지표에 대해서 알람 설정을 해주는 것이 필수이다. 그라파나에 알람 설정을 추가하고 슬랙으로 전송해보자.
본 포스팅은 AWS EKS와 kube-prometheus-stack이 이미 설치된 상황을 가정하고 설명한다.
준비하기
- AWS EKS에 kube-prometheus-stack 설치하기 : https://oflouis.dev/sw_development/devops/aws-eks-monitoring-kube-prometheus-stack/
슬랙 알림 메세지 샘플 화면
슬랙 알람 전송 설정
슬랙 메세지 포맷 설정
- Alerting > Contact points > New Template
- {{ .CommonLabels.xxx }}와 {{ .Annotations.summary }}의 내용은 각각의 알림에서 설정한다. alert.json 샘플을 참고하자.
{{ define "slack.alert_title" }}
[ {{ .Status | toUpper }} ] {{ .CommonLabels.region | toUpper }} | {{ .CommonLabels.env | toUpper }} | {{ .CommonLabels.alertname }}{{ end }}
{{ define "slack.alert_message" }}
{{ range .Alerts }}
*Summary*: *{{ .Annotations.summary }}**Labels*:
{{ range .Labels.SortedPairs }}{{ if or (eq .Name "env") (eq .Name "app") (eq .Name "namespace") (eq .Name "instance") }} *- {{ .Name }} = {{ .Value }}*{{end}}
{{ end }}
{{ end }}
{{ end }}
슬랙 연동 설정
- 슬랙 채널 만들기
- 슬랙 앱 만들기
- 슬랙 앱 관리 화면에서 WebhookURL을 생성
- Alerting > Contact points > New Contact point
- Contact point type : Slack
- Webhook URL : Slack Webhook URL
- Optional Slack setting > Title : {{ template "slack.alert_title" . }}
- Optional Slack setting > Text Body : {{ template "slack.alert_message" . }}
- Optional Slack setting > Mention Users : 멘션할 슬랙 ID(들) 입력
그라파나 알람 규칙 추가
본 포스팅에서는 그라파나의 Alerting Provisioning HTTP API를 사용하여 알람 규칙을 생성 및 관리하는 내용을 작성했다. 프로비저닝 방식으로 생성한 경우 UI에서 생성하지 않았기 때문에 UI를 통한 수정 및 삭제는 불가능하니 참고하자.
환경변수 설정
export GRAFANA_USER_NAME=
export GRAFANA_USER_PASSWORD=
export GRAFANA_HOST_URL=
폴더 생성
# 폴더 생성
curl -X POST http://${GRAFANA_USER_NAME}:${GRAFANA_USER_PASSWORD}@${GRAFANA_HOST_URL}/api/folders \
-H 'content-type: application/json' \
-d '{"title" : "Service Monitoring" }'
# 폴더 UID 확인
curl http://${GRAFANA_USER_NAME}:${GRAFANA_USER_PASSWORD}@${GRAFANA_HOST_URL}/api/folders |jq
[
{
"id": 111,
"uid": "7KVKla2Ef", "title": "Service Monitoring"
}
...
]
알람 규칙
- 규칙을 정의한 파일 생성 (샘플)
alert.json
{
"title": "NodeHighCPU",
"orgID": 1,
"folderUID": "7KVKla2Ef",
"ruleGroup": "Instance",
"condition": "C",
"execErrState": "Alerting",
"noDataState": "NoData",
"for": "5m",
"annotations": { "summary": "CPU Usage : {{ humanize $values.B.Value }} %, Node : {{ $labels.instance }}" }, "labels": { "env": "integ", "region": "kor" }, "data": [
{"refId":"A","queryType":"","relativeTimeRange":{"from":600,"to":0},"datasourceUid":"prometheus","model":{"editorMode":"code","expr":"100 - (max by(instance) (irate(node_cpu_seconds_total{mode=\"idle\"}[5m])) * 100)","hide":false,"intervalMs":1000,"legendFormat":"__auto","maxDataPoints":43200,"range":true,"refId":"A"}},
{"refId":"B","queryType":"","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"-100","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"params":[],"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"A","hide":false,"intervalMs":1000,"maxDataPoints":43200,"reducer":"max","refId":"B","type":"reduce"}},
{"refId":"C","queryType":"","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"-100","model":{"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":["B"]},"reducer":{"params":[],"type":"avg"},"type":"query"}],"datasource":{"name":"Expression","type":"__expr__","uid":"__expr__"},"expression":"round($B) > 70","hide":false,"intervalMs":1000,"maxDataPoints":43200,"refId":"C","type":"math"}}
]
}
- 명령들
# 생성
curl -X POST http://${GRAFANA_USER_NAME}:${GRAFANA_USER_PASSWORD}@${GRAFANA_HOST_URL}/api/v1/provisioning/alert-rules \
-H 'content-type: application/json' -d @./alert.json
# 생성 결과 : {"id":11,"uid":"Qvbocu40z","orgID":1,"folderUID":"7KVKla2Ef", ...}
export ALERT_RULE_UID=생성 결과의 uid 값
# 조회
curl http://${GRAFANA_USER_NAME}:${GRAFANA_USER_PASSWORD}@${GRAFANA_HOST_URL}/api/v1/provisioning/alert-rules/${ALERT_RULE_UID}
# 수정
curl -X PUT http://${GRAFANA_USER_NAME}:${GRAFANA_USER_PASSWORD}@${GRAFANA_HOST_URL}/api/v1/provisioning/alert-rules/${ALERT_RULE_UID} \
-H 'content-type: application/json' -d @./alert_mod.json
# 삭제
curl -X DELETE http://${GRAFANA_USER_NAME}:${GRAFANA_USER_PASSWORD}@${GRAFANA_HOST_URL}/api/v1/provisioning/alert-rules/${ALERT_RULE_UID}
- 주요 항목 표현식
* node cpu : 100 - (max by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
* node memory : max by(instance) (instance:node_memory_utilisation:ratio{job="node-exporter"}) * 100
* node disk : max by(instance) ((node_filesystem_size_bytes{job="node-exporter"} - node_filesystem_avail_bytes{job="node-exporter"}) / node_filesystem_size_bytes{job="node-exporter"} * 100)
* container cpu : 100 * max(rate(container_cpu_usage_seconds_total[5m]) / on (container, pod) kube_pod_container_resource_limits{resource="cpu"}) by (container)
* container memory : max by (container) (container_memory_working_set_bytes / on (container, pod) kube_pod_container_resource_limits{resource="memory"}) * 100
참고
- https://api.slack.com/messaging/webhooks
- https://github.com/grafana/grafana/blob/main/pkg/services/ngalert/notifier/channels/default_template.go
- https://grafana.com/docs/grafana/latest/alerting/contact-points/message-templating/example-template/
- https://grafana.com/docs/grafana/latest/developers/http_api/curl-examples/
- https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/