반응형
이번에 작업을 하면서 ServiceMonitor에 대해서 알게되었는데. 이게 정확히 어떤방식으로 동작하는지 정리를 하면 좋을것같아서 글을 작성합니다.
왜 사용함?
Prometheus에서 일반적으로는 static-configs에 옵션으로 수집할 대상(target)을 지정해주는데. 지정 대상이 한두개면 작업할만하지만, 지정 대상이 수백개 이상이 되어버리면 하나하나 지정해주기가 매우 불편한 상황이 옴. 따라서 더 유연하고 선언적인 방식으로 모니터링 타켓을 관리하기 위해 Prometheus Operator중 하나인 ServiceMonitor를 사용하게됨.
어떻게 사용함?
모니터링 대상 App에 /metrics 엔드포인트 노출
당연하지만 해당 포트에는 Exporter와 같이 메트릭을 노출하는 애플리케이션이 실행중이여야함
apiVersion: v1
kind: Service
metadata:
name: my-app
labels:
app: my-app
spec:
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080
ServiceMonitor 정의
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: my-app-monitor
labels:
release: prometheus # Prometheus CR와 연결하는 라벨
spec:
selector:
matchLabels:
app: my-app # 수집 대상 Service를 식별하는 라벨
endpoints:
- port: http # Service에서 수집할 포트 이름
path: /metrics # 기본 경로는 /metrics
interval: 15s # 수집 주기
Prometheus가 해당 ServiceMonitor를 인식하도록 설정
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: k8s
spec:
serviceMonitorSelector:
matchLabels:
release: prometheus # ServiceMonitor와 같은 라벨이어야 함
Alertmanager에 대한 소소한 정리
Prometheus에서 Rule을 정의하고 이걸 알람을 발생시켜서 Slack에 보낸다고했을때 아래와같은 구조로 이뤄진다.
Prometheus에서 Alertmanager를 연결 진행. Prometheus Operator의 Prometheus CR을 사용하면 아래 변수를 설정하면된다. alertmanager를 띄워놓은 namespace그리고 연결하는 port를 지정해주면 된다.
...
alerting = {
alertmanagers = [
{
namespace = var.prometheus_stack_namespace
name = "alertmanager-operated"
port = "web"
}
]
}
...
그런다음 Alertmanager에서 Slack으로 메세지를 전송하기 위해서는 아래와같은 요소가 필요함
- serviceaccount (alertmanager-main)
- slack web hook을 넣어줄 secret
- slack message template정보를 넣어줄 alertmanager config
terraform으로는 아래와같이 작업함
resource "kubernetes_service_account" "alertmanager" {
metadata {
name = "alertmanager-main"
namespace = var.prometheus_stack_namespace
}
}
resource "kubernetes_secret_v1" "slack_api_url" {
metadata {
name = "slack-api-url"
namespace = var.prometheus_stack_namespace
}
data = {
# service-status web hook url
url = ""
}
}
# https://prometheus-operator.dev/docs/developer/alerting/#using-alertmanagerconfig-resources
resource "kubernetes_manifest" "alertmanager_config" {
manifest = {
apiVersion = "monitoring.coreos.com/v1alpha1"
kind = "AlertmanagerConfig"
metadata = {
name = "alertmanager-config"
namespace = var.prometheus_stack_namespace
}
spec = {
route = {
repeatInterval = "12h"
receiver = "slack"
}
# https://prometheus-operator.dev/docs/api-reference/api/#monitoring.coreos.com/v1alpha1.Receiver
receivers = [
{
name = "slack"
slackConfigs = [
{
apiURL = {
key = "url"
name = kubernetes_secret_v1.slack_api_url.metadata[0].name
}
sendResolved = true
# message format from https://grafana.com/blog/2020/02/25/step-by-step-guide-to-setting-up-prometheus-alertmanager-with-slack-pagerduty-and-gmail/?utm_source=chatgpt.com
title = <<-EOT
[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }}
{{- if gt (len .CommonLabels) (len .GroupLabels) -}}
{{" "}}(
{{- with .CommonLabels.Remove .GroupLabels.Names }}
{{- range $index, $label := .SortedPairs -}}
{{ if $index }}, {{ end }}
{{- $label.Name }}="{{ $label.Value -}}"
{{- end }}
{{- end -}}
)
{{- end }}
EOT
text = <<-EOT
{{ range .Alerts -}}
*Alert:* {{ .Annotations.title }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }}
*Cluster:* Moreh-QA
*Description:* {{ .Annotations.description }}
*Details:*
{{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
{{ end }}
{{ end }}
EOT
mrkdwnIn = ["text", "title"]
}
]
}
]
}
}
}
resource "kubernetes_manifest" "alertmanager_main" {
manifest = {
apiVersion = "monitoring.coreos.com/v1"
kind = "Alertmanager"
metadata = {
name = "main"
namespace = var.prometheus_stack_namespace
}
spec = {
replicas = 1
serviceAccountName = kubernetes_service_account.alertmanager.metadata[0].name
alertmanagerConfiguration = {
name = kubernetes_manifest.alertmanager_config.manifest.metadata.name
}
}
}
wait {
condition {
type = "Available"
status = "True"
}
}
}
반응형
'Develop > DevOps' 카테고리의 다른 글
[Prometheus] Prometheus HA를 위한 Thanos 배포 (0) | 2025.03.27 |
---|---|
[helm] local-path-provisioner helm chart 작업 (0) | 2025.03.25 |
[istio] terraform istio 설치 및 Gateway & VirtualService 사용 정리 (0) | 2025.02.26 |
[k8s] offline-kubespray 사용 방법 (0) | 2025.02.20 |
[DevOps] 인증서 관련해서 내용 정리 (1) | 2024.12.19 |