Observability/Prometheus

EP05 [Part 2: Prometheus Operator 설치와 구성 #2] Helm을 사용한 kube-prometheus-stack 배포

ygtoken 2025. 3. 19. 14:50
728x90

이 글에서는 Helm을 활용하여 kube-prometheus-stack을 Kubernetes 클러스터에 배포하는 과정을 상세히 다룹니다. 설치 전 Helm 설정부터 시작하여 실제 배포 명령어, 설치 검증, 문제 해결 방법까지 단계별로 안내합니다. 또한 업그레이드 및 확장 관련 실무 팁도 제공하여 안정적인 모니터링 환경을 구축할 수 있도록 도와드립니다.


📌 Helm을 통한 설치 준비

Helm을 사용하여 kube-prometheus-stack을 설치하기 전에 필요한 설정과 준비 사항을 확인합니다.

 

Helm 상태 확인

Helm이 제대로 설정되어 있는지 확인합니다.

# Helm 버전 확인
helm version
# 출력 예시
# version.BuildInfo{Version:"v3.10.3", GitCommit:"..."}

# Prometheus 커뮤니티 차트 레포지토리 확인
helm repo list | grep prometheus-community
# prometheus-community가 목록에 없으면 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

# 레포지토리 최신화
helm repo update

 

설치 가능한 버전 확인

사용 가능한 kube-prometheus-stack 버전을 확인합니다.

# 사용 가능한 버전 확인
helm search repo prometheus-community/kube-prometheus-stack -l | head -n 10
# 출력 예시
# NAME                                              CHART VERSION  APP VERSION  DESCRIPTION
# prometheus-community/kube-prometheus-stack        45.10.1        v0.63.0      kube-prometheus-stack collects Kubernetes manifests...
# prometheus-community/kube-prometheus-stack        45.10.0        v0.63.0      kube-prometheus-stack collects Kubernetes manifests...
# ...

 

설치 전 차트 검증

실제 설치 전에 차트 내용을 검증합니다.

# 차트 구조 확인
helm show chart prometheus-community/kube-prometheus-stack

# values.yaml 기본값 확인
helm show values prometheus-community/kube-prometheus-stack > default-values.yaml

# 테스트 렌더링 (실제 설치 X)
helm template prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace > test-rendered.yaml

 

사용자 정의 values.yaml 준비

이전 글에서 준비한 custom-values.yaml 파일을 최종 점검합니다. 만약 준비하지 않았다면, 아래 예시 파일을 기준으로 작성합니다.

# custom-values.yaml

# 글로벌 설정
global:
  rbac:
    create: true
    pspEnabled: false # Kubernetes 1.25+ 에서는 PSP가 제거됨
  
  # 이미지 풀 정책 설정
  imagePullSecrets: []

# Prometheus Operator 설정
prometheusOperator:
  enabled: true
  
  # 리소스 설정
  resources:
    limits:
      cpu: 200m
      memory: 256Mi
    requests:
      cpu: 100m
      memory: 128Mi
  
  # Admission Webhook 설정
  admissionWebhooks:
    enabled: true
    patch:
      enabled: true

# Grafana 설정
grafana:
  enabled: true
  
  # 관리자 계정 설정
  adminPassword: "admin123"  # 실제 환경에서는 보안 시크릿 사용 권장
  
  # 외부 접근 설정
  service:
    type: ClusterIP # 클러스터 내부 접근용, LoadBalancer 또는 NodePort로 변경 가능
  
  # 영구 스토리지 설정
  persistence:
    enabled: true
    size: 10Gi
    storageClassName: standard # 클러스터에 맞는 스토리지 클래스 지정
  
  # 리소스 설정
  resources:
    limits:
      cpu: 200m
      memory: 256Mi
    requests:
      cpu: 100m
      memory: 128Mi
  
  # 대시보드 자동 로드
  defaultDashboardsEnabled: true

# Prometheus 설정
prometheus:
  enabled: true
  
  # Prometheus 서버 설정
  prometheusSpec:
    replicas: 1  # 고가용성이 필요하면 2 이상으로 설정
    
    # 보존 정책 설정
    retention: "10d"
    
    # 스토리지 설정
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: standard  # 클러스터에 맞는 스토리지 클래스
          resources:
            requests:
              storage: 50Gi
    
    # 리소스 설정
    resources:
      limits:
        cpu: 1000m
        memory: 2Gi
      requests:
        cpu: 500m
        memory: 1Gi
    
    # 보안 컨텍스트 설정
    securityContext:
      fsGroup: 2000
      runAsNonRoot: true
      runAsUser: 1000

# Alertmanager 설정
alertmanager:
  enabled: true
  
  # Alertmanager 스펙 설정
  alertmanagerSpec:
    replicas: 1  # 고가용성이 필요하면 2 이상으로 설정
    
    # 스토리지 설정
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: standard  # 클러스터에 맞는 스토리지 클래스
          resources:
            requests:
              storage: 10Gi
    
    # 리소스 설정
    resources:
      limits:
        cpu: 100m
        memory: 256Mi
      requests:
        cpu: 50m
        memory: 128Mi

# kube-state-metrics 설정
kubeStateMetrics:
  enabled: true

# Node Exporter 설정
nodeExporter:
  enabled: true

# 기본 Prometheus 규칙 설정
defaultRules:
  create: true
  # 특정 규칙 비활성화 (필요한 경우)
  disabled:
    KubeSchedulerDown: false

 

네임스페이스 준비

# 모니터링 네임스페이스 생성
kubectl create namespace monitoring

# 네임스페이스 상태 확인
kubectl get namespace monitoring

▶️ 설치 준비 팁: 프로덕션 환경에서는 민감한 자격 증명(예: Grafana 관리자 비밀번호)을 values.yaml 파일에 평문으로 저장하지 마세요. 대신 쿠버네티스 시크릿을 미리 생성하고 이를 참조하는 방식을 사용하세요.


📌 Helm을 사용한 kube-prometheus-stack 설치

준비가 완료되었으면 Helm을 사용하여 kube-prometheus-stack을 설치합니다.

 

기본 설치 명령어

가장 간단한 설치 방법은 기본 설정을 사용하는 것입니다:

# 기본 설정으로 설치
helm install prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace

 

사용자 정의 설정으로 설치

앞서 준비한 custom-values.yaml 파일을 사용하여 설치합니다:

# 사용자 정의 설정으로 설치
helm install prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  -f custom-values.yaml

 

특정 차트 버전 설치

버전 호환성 문제를 방지하기 위해 특정 차트 버전을 지정할 수 있습니다:

# 특정 버전 설치
helm install prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  -f custom-values.yaml \
  --version 45.10.1 # 원하는 버전 지정

 

명령줄에서 직접 값 설정

일부 설정만 변경하려면 명령줄에서 직접 지정할 수 있습니다:

# 명령줄에서 특정 값 설정
helm install prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --set prometheus.prometheusSpec.retention=15d \
  --set grafana.adminPassword=admin123 \
  --set prometheus.service.type=NodePort

▶️ 설치 팁: 실제 프로덕션 환경에서는 helm install 전에 --debug --dry-run 플래그를 사용하여 생성될 리소스를 미리 확인하는 것이 좋습니다. 이는 예기치 않은 구성 문제를 사전에 방지하는 데 도움이 됩니다.


📌 설치 확인 및 상태 점검

kube-prometheus-stack이 성공적으로 설치되었는지 확인합니다.

 

Helm 릴리스 확인

# 설치된 Helm 릴리스 확인
helm list -n monitoring
# 출력 예시
# NAME            NAMESPACE   REVISION  UPDATED                              STATUS    CHART                         APP VERSION
# prom-stack      monitoring  1         2023-05-01 12:34:56.789123 +0900 KST deployed  kube-prometheus-stack-45.10.1  v0.63.0

 

Pod 상태 확인

# Pod 상태 확인
kubectl get pods -n monitoring
# 출력 예시
# NAME                                                   READY   STATUS    RESTARTS   AGE
# alertmanager-prom-stack-kube-prometheus-alertmanager-0 2/2     Running   0          5m
# prom-stack-grafana-5c88f5fb68-q4dv2                    3/3     Running   0          5m
# prom-stack-kube-prometheus-operator-65df4d8f7c-t9vq2   1/1     Running   0          5m
# prom-stack-kube-state-metrics-79d954c69-hfmvz          1/1     Running   0          5m
# prom-stack-prometheus-node-exporter-6zwxt              1/1     Running   0          5m
# prometheus-prom-stack-kube-prometheus-prometheus-0      2/2     Running   0          5m

 

Service 확인

# Service 확인
kubectl get svc -n monitoring
# 출력 예시
# NAME                                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
# alertmanager-operated                     ClusterIP   None            <none>        9093/TCP,9094/TCP,9094/UDP   5m
# prom-stack-grafana                        ClusterIP   10.100.200.1    <none>        80/TCP                       5m
# prom-stack-kube-prometheus-alertmanager   ClusterIP   10.100.200.2    <none>        9093/TCP                     5m
# prom-stack-kube-prometheus-operator       ClusterIP   10.100.200.3    <none>        443/TCP                      5m
# prom-stack-kube-prometheus-prometheus     ClusterIP   10.100.200.4    <none>        9090/TCP                     5m
# prom-stack-kube-state-metrics             ClusterIP   10.100.200.5    <none>        8080/TCP                     5m
# prom-stack-prometheus-node-exporter       ClusterIP   10.100.200.6    <none>        9100/TCP                     5m
# prometheus-operated                       ClusterIP   None            <none>        9090/TCP                     5m

 

CustomResource 확인

# Prometheus CR 확인
kubectl get prometheuses -n monitoring
# 출력 예시
# NAME                                    VERSION   REPLICAS   AGE
# prom-stack-kube-prometheus-prometheus   v2.41.0   1          5m

# AlertManager CR 확인
kubectl get alertmanagers -n monitoring
# 출력 예시
# NAME                                       VERSION   REPLICAS   AGE
# prom-stack-kube-prometheus-alertmanager    v0.25.0   1          5m

# ServiceMonitor 확인
kubectl get servicemonitors -n monitoring
# 출력 예시
# NAME                                                 AGE
# prom-stack-grafana                                   5m
# prom-stack-kube-prometheus-alertmanager              5m
# prom-stack-kube-prometheus-apiserver                 5m
# ...

 

웹 인터페이스 접근

각 컴포넌트의 웹 인터페이스에 접근하는 방법은 서비스 타입과 환경에 따라 다릅니다.

  1. 포트 포워딩을 통한 접근
# Prometheus UI 접근
kubectl port-forward -n monitoring svc/prom-stack-kube-prometheus-prometheus 9090:9090
# 브라우저에서 http://localhost:9090 접속

# Grafana 접근
kubectl port-forward -n monitoring svc/prom-stack-grafana 3000:80
# 브라우저에서 http://localhost:3000 접속
# 기본 사용자: admin, 비밀번호: 설정한 값 또는 기본값 prom-operator

# Alertmanager 접근
kubectl port-forward -n monitoring svc/prom-stack-kube-prometheus-alertmanager 9093:9093
# 브라우저에서 http://localhost:9093 접속
  1. NodePort를 통한 접근 (NodePort 타입으로 서비스를 설정한 경우)
# NodePort 확인
kubectl get svc -n monitoring prom-stack-kube-prometheus-prometheus -o=jsonpath='{.spec.ports[0].nodePort}'
# 출력 예시: 30090

# 노드 IP 확인
kubectl get nodes -o wide
# 브라우저에서 http://<노드IP>:30090 접속
  1. LoadBalancer를 통한 접근 (LoadBalancer 타입으로 서비스를 설정한 경우)
# 외부 IP 확인
kubectl get svc -n monitoring prom-stack-kube-prometheus-prometheus
# 출력 예시:
# NAME                                     TYPE          CLUSTER-IP     EXTERNAL-IP     PORT(S)          AGE
# prom-stack-kube-prometheus-prometheus    LoadBalancer  10.100.200.4   35.123.456.78   9090:30090/TCP   5m
# 브라우저에서 http://35.123.456.78:9090 접속
  1. Ingress를 통한 접근 (Ingress를 설정한 경우)
# Ingress 상태 확인
kubectl get ingress -n monitoring
# 브라우저에서 설정한 호스트 이름으로 접속

▶️ 접근 보안 팁: 프로덕션 환경에서는 모니터링 UI에 대한 무단 접근을 방지하기 위해 인증 메커니즘(OAuth2, LDAP 등)을 구현하세요. 또한 TLS를 사용하여 통신을 암호화하는 것이 좋습니다.


📌 설치 후 기본 검증

설치가 완료된 후 모니터링 시스템이 제대로 작동하는지 기본적인 검증을 수행합니다.

 

Prometheus 웹 UI 검증

Prometheus UI에 접속하여 다음을 확인합니다:

  1. Status > Targets: 타겟 상태가 "UP"인지 확인
  2. Status > Service Discovery: 서비스 디스커버리가 정상 작동하는지 확인
  3. Alerts: 알림 규칙이 로드되었는지 확인
  4. Graph: 기본 쿼리를 실행하여 데이터가 수집되는지 확인
# Prometheus UI에서 테스트할 기본 쿼리 예시
up  # 모든 타겟의 상태(1=UP, 0=DOWN)
node_memory_MemAvailable_bytes  # 노드별 가용 메모리
kube_pod_container_status_running  # 실행 중인 컨테이너 수
rate(node_cpu_seconds_total{mode="idle"}[5m])  # CPU 유휴 시간 비율

 

Grafana 대시보드 검증

Grafana에 로그인하여 다음을 확인합니다:

  1. Home > Dashboards > Browse: 기본 제공 대시보드 목록 확인
  2. 설정 > Data Sources: Prometheus 데이터 소스가 정상적으로 설정되었는지 확인
  3. 다음 주요 대시보드 확인:
    • Kubernetes / Compute Resources / Cluster
    • Kubernetes / Compute Resources / Namespace (Pods)
    • Node Exporter / Nodes
    • Kubernetes / Compute Resources / Workload

AlertManager 검증

AlertManager UI에 접속하여 다음을 확인합니다:

  1. Alerts 탭: 현재 알림 상태 확인
  2. Silences 탭: 알림 무음 처리 기능 확인
  3. Status 탭: 설정 및 클러스터 상태 확인

메트릭 수집 검증

특정 메트릭이 제대로 수집되는지 확인합니다:

# kubectl을 통한 메트릭 API 확인
kubectl get --raw /apis/metrics.k8s.io/v1beta1/nodes

# Prometheus API로 직접 쿼리
curl -s http://localhost:9090/api/v1/query?query=up | jq .

▶️ 검증 팁: 모니터링 시스템을 설치한 후에는 의도적으로 부하를 생성하거나 일부 서비스를 중단시켜 알림이 제대로 작동하는지 테스트하는 것이 좋습니다. 이를 통해 프로덕션 환경에서 문제가 발생했을 때 모니터링 시스템이 제대로 작동하는지 확인할 수 있습니다.


📌 일반적인 문제 및 해결 방법

kube-prometheus-stack 설치 및 구성 과정에서 발생할 수 있는 일반적인 문제와 해결 방법을 알아봅니다.

 

Pod가 시작되지 않는 문제

# 문제가 있는 파드 확인
kubectl get pods -n monitoring | grep -v Running

# 자세한 파드 상태 확인
kubectl describe pod <pod-name> -n monitoring

# 파드 로그 확인
kubectl logs <pod-name> -n monitoring
# 컨테이너가 여러 개인 경우
kubectl logs <pod-name> -c <container-name> -n monitoring

 

일반적인 원인 및 해결 방법:

  1. 리소스 부족
    • 증상: Pod가 Pending 상태
    • 해결: 노드 리소스 확인, request/limit 조정
    # 노드 리소스 확인
    kubectl describe node <node-name>
    
    # values.yaml에서 리소스 설정 조정 후 업그레이드
    helm upgrade prom-stack prometheus-community/kube-prometheus-stack \
      -n monitoring \
      -f custom-values.yaml
    
  2. 권한 문제
    • 증상: RBAC 관련 오류
    • 해결: RBAC 설정 확인 및 수정
    # RBAC 리소스 확인
    kubectl get clusterroles,clusterrolebindings -l app=<app-label> -n monitoring
    
    # 필요한 경우 RBAC 수동 보완
    kubectl apply -f additional-rbac.yaml
    
  3. 스토리지 문제
    • 증상: PVC 생성 실패 또는 Pending
    • 해결: 스토리지 클래스 및 용량 확인
    # PVC 상태 확인
    kubectl get pvc -n monitoring
    
    # 스토리지 클래스 확인
    kubectl get storageclass
    
    # values.yaml에서 스토리지 설정 조정
    

Prometheus 타겟 검색 문제

# ServiceMonitor 확인
kubectl get servicemonitors -n monitoring

# 특정 ServiceMonitor 상세 정보
kubectl describe servicemonitor <name> -n monitoring

 

일반적인 원인 및 해결 방법:

  1. 레이블 불일치
    • 증상: 타겟이 발견되지 않음
    • 해결: ServiceMonitor와 Service의 레이블 확인
    # 서비스의 레이블 확인
    kubectl get svc <service-name> -n <namespace> --show-labels
    
    # ServiceMonitor의 selector 확인
    kubectl get servicemonitor <name> -n monitoring -o yaml | grep -A5 selector
    
  2. 네임스페이스 불일치
    • 증상: 타겟이 발견되지 않음
    • 해결: ServiceMonitor의 namespaceSelector 확인
    # ServiceMonitor의 namespaceSelector 확인
    kubectl get servicemonitor <name> -n monitoring -o yaml | grep -A5 namespaceSelector
    
  3. 엔드포인트 설정 불일치
    • 증상: 타겟이 발견되었지만 스크래핑 실패
    • 해결: 엔드포인트 구성 확인
    # 서비스 포트 확인
    kubectl get svc <service-name> -n <namespace> -o yaml | grep -A10 ports
    
    # ServiceMonitor 엔드포인트 확인
    kubectl get servicemonitor <name> -n monitoring -o yaml | grep -A10 endpoints
    

Grafana 문제

# Grafana 파드 로그 확인
kubectl logs -n monitoring <grafana-pod-name>

# Grafana ConfigMap 확인
kubectl get configmap -n monitoring | grep grafana
kubectl describe configmap <grafana-configmap> -n monitoring

 

일반적인 원인 및 해결 방법:

  1. 로그인 문제
    • 증상: 관리자 계정으로 로그인 불가
    • 해결: 비밀번호 재설정
    # 관리자 비밀번호 확인 (시크릿에서)
    kubectl get secret -n monitoring prom-stack-grafana -o jsonpath="{.data.admin-password}" | base64 --decode
    
    # 비밀번호 수동 변경 (Grafana 파드 내에서)
    kubectl exec -it <grafana-pod-name> -n monitoring -- grafana-cli admin reset-admin-password <new-password>
    
  2. 대시보드 로드 실패
    • 증상: 대시보드가 표시되지 않거나 데이터 없음
    • 해결: 데이터 소스 및 대시보드 구성 확인
    # Grafana 데이터 소스 ConfigMap 확인
    kubectl get configmap -n monitoring prom-stack-grafana-datasources -o yaml
    
    # Grafana 대시보드 ConfigMap 확인
    kubectl get configmap -n monitoring -l "grafana_dashboard=1"
    

알림 전송 문제

# AlertManager 구성 확인
kubectl get secret -n monitoring alertmanager-prom-stack-kube-prometheus-alertmanager -o jsonpath="{.data.alertmanager\.yaml}" | base64 --decode

# AlertManager 로그 확인
kubectl logs -n monitoring <alertmanager-pod-name>

 

일반적인 원인 및 해결 방법:

  1. 구성 오류
    • 증상: 알림이 전송되지 않음
    • 해결: AlertManager 구성 수정
    # values.yaml에서 AlertManager 구성 수정 후 업그레이드
    helm upgrade prom-stack prometheus-community/kube-prometheus-stack \
      -n monitoring \
      -f custom-values.yaml
    
  2. 외부 서비스 연결 문제
    • 증상: 알림 전송 실패 로그
    • 해결: 네트워크 연결 및 인증 정보 확인
    # AlertManager 파드에서 외부 서비스 연결 테스트
    kubectl exec -it  -n monitoring -- wget -q -O - --spider https://webhook-service.example.com
    

▶️ 문제 해결 팁: 문제 해결 과정을 문서화하고, 발견한 문제와 해결 방법을 팀과 공유하세요. 이러한 지식은 향후 비슷한 문제가 발생했을 때 빠르게 해결하는 데 도움이 됩니다.


📌 Helm을 사용한 업그레이드 및 관리

kube-prometheus-stack을 설치한 후 업그레이드 및 관리 방법을 알아봅니다.

 

업그레이드 전 확인사항

업그레이드 전에 다음 사항을 확인하세요:

# 현재 배포된 버전 확인
helm list -n monitoring

# 최신 버전 확인
helm repo update
helm search repo prometheus-community/kube-prometheus-stack

# 변경 사항 확인
helm show readme prometheus-community/kube-prometheus-stack | grep -A20 "^## Change"

 

업그레이드 수행

# dry-run으로 변경 사항 미리 확인
helm upgrade --dry-run prom-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f custom-values.yaml

# 실제 업그레이드 수행
helm upgrade prom-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f custom-values.yaml

 

설정 변경

values.yaml 파일을 수정한 후 업그레이드하여 설정을 변경할 수 있습니다:

# values.yaml 파일 수정 후 업그레이드
helm upgrade prom-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f custom-values.yaml

 

롤백

업그레이드 문제가 발생한 경우 이전 버전으로 롤백할 수 있습니다:

# 배포 기록 확인
helm history prom-stack -n monitoring

# 특정 버전으로 롤백
helm rollback prom-stack <revision-number> -n monitoring

 

제거

모니터링 스택을 완전히 제거해야 하는 경우:

# Helm 릴리스 제거
helm uninstall prom-stack -n monitoring

# CRD 제거 (필요한 경우)
kubectl delete crd prometheuses.monitoring.coreos.com
kubectl delete crd alertmanagers.monitoring.coreos.com
kubectl delete crd servicemonitors.monitoring.coreos.com
kubectl delete crd podmonitors.monitoring.coreos.com
kubectl delete crd prometheusrules.monitoring.coreos.com
kubectl delete crd thanosrulers.monitoring.coreos.com

# PVC 제거 (필요한 경우)
kubectl delete pvc -n monitoring --all
# 네임스페이스 제거 (필요한 경우)
kubectl delete namespace monitoring

 

▶️ **관리 팁**: Prometheus 및 Alertmanager 구성은 CRD를 통해 관리됩니다. 기존 구성을 유지하려면 `helm upgrade` 명령에 `--reset-values` 플래그를 사용하지 마세요. 이 플래그는 이전에 설정한 모든 값을 기본값으로 재설정합니다.

---

## 📌 확장 및 커스터마이징

기본 설치 이후 모니터링 스택을 확장하고 커스터마이징하는 방법을 알아봅니다.

✅ **추가 ServiceMonitor 생성**

기본 설치에 포함되지 않은 서비스를 모니터링하기 위해 ServiceMonitor를 추가할 수 있습니다:

 

 

# custom-service-monitor.yaml

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-service-monitor
  namespace: monitoring
  labels:
    # Prometheus CR의 serviceMonitorSelector와 일치하는 레이블 필요
    release: prom-stack
spec:
  # 모니터링할 서비스가 있는 네임스페이스
  namespaceSelector:
    matchNames:
      - my-app-namespace
  
  # 서비스 선택자 (레이블 기반)
  selector:
    matchLabels:
      app: my-app
  
  # 엔드포인트 설정
  endpoints:
  - port: metrics  # 서비스의 포트 이름
    interval: 30s  # 스크래핑 간격
    path: /metrics  # 메트릭 경로
# ServiceMonitor 적용
kubectl apply -f custom-service-monitor.yaml

 

추가 알림 규칙 생성

사용자 정의 알림 규칙을 추가할 수 있습니다:

# custom-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: my-app-rules
  namespace: monitoring
  labels:
    # Prometheus CR의 ruleSelector와 일치하는 레이블 필요
    release: prom-stack
spec:
  groups:
  - name: my-app.rules
    rules:
    - alert: MyAppHighErrorRate
      expr: sum(rate(http_requests_total{app="my-app", status=~"5.."}[5m])) / sum(rate(http_requests_total{app="my-app"}[5m])) > 0.1
      for: 10m
      labels:
        severity: warning
        team: backend
      annotations:
        summary: "High error rate detected in My App"
        description: "Error rate is higher than 10% for the last 10 minutes (current value: {{ $value | humanizePercentage }})"
# 규칙 적용
kubectl apply -f custom-rules.yaml

 

외부 시스템에 알림 전송 설정

AlertManager 구성을 수정하여 Slack, Email, PagerDuty 등으로 알림을 전송할 수 있습니다:

# alertmanager-config.yaml
alertmanager:
  config:
    global:
      resolve_timeout: 5m
      smtp_smarthost: 'smtp.example.com:587'
      smtp_from: 'alerts@example.com'
      smtp_auth_username: 'alerts@example.com'
      smtp_auth_password: 'password'
    
    route:
      group_by: ['job', 'alertname', 'severity']
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 12h
      receiver: 'team-emails'
      routes:
      - match:
          severity: critical
        receiver: 'team-pager'
      - match:
          team: backend
        receiver: 'backend-slack'
    
    receivers:
    - name: 'team-emails'
      email_configs:
      - to: 'team@example.com'
    
    - name: 'team-pager'
      pagerduty_configs:
      - routing_key: ''
        severity: '{{ .CommonLabels.severity }}'
    
    - name: 'backend-slack'
      slack_configs:
      - api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
        channel: '#backend-alerts'
        title: '{{ .CommonLabels.alertname }}'
        text: '{{ .CommonAnnotations.description }}'
        send_resolved: true
# values.yaml 파일에 위 구성 추가하고 업그레이드
helm upgrade prom-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f custom-values.yaml

 

Grafana 추가 데이터 소스 구성

Prometheus 외에 다른 데이터 소스를 추가할 수 있습니다:

# grafana-datasources.yaml
grafana:
  additionalDataSources:
  - name: Loki
    type: loki
    url: http://loki-gateway.logging.svc.cluster.local
    access: proxy
  
  - name: Jaeger
    type: jaeger
    url: http://jaeger-query.tracing.svc.cluster.local:16686
    access: proxy
# values.yaml 파일에 위 구성 추가하고 업그레이드
helm upgrade prom-stack prometheus-community/kube-prometheus-stack \
  -n monitoring \
  -f custom-values.yaml

 

Grafana 추가 대시보드 구성

사용자 정의 대시보드를 추가할 수 있습니다:

# grafana-dashboards.yaml
grafana:
  dashboards:
    default:
      my-app-dashboard:
        # gnetId: 12345  # Grafana.com에서 대시보드 가져오기
        json: |
          {
            "annotations": {
              "list": [
                {
                  "builtIn": 1,
                  "datasource": "-- Grafana --",
                  "enable": true,
                  "hide": true,
                  "iconColor": "rgba(0, 211, 255, 1)",
                  "name": "Annotations & Alerts",
                  "type": "dashboard"
                }
              ]
            },
            "editable": true,
            "gnetId": null,
            "graphTooltip": 0,
            "id": null,
            "links": [],
            "panels": [
              // 패널 구성...
            ],
            "refresh": "10s",
            "schemaVersion": 27,
            "style": "dark",
            "tags": [],
            "templating": {
              "list": []
            },
            "time": {
              "from": "now-6h",
              "to": "now"
            },
            "timepicker": {},
            "timezone": "",
            "title": "My App Dashboard",
            "uid": "my-app",
            "version": 1
          }

▶️ 확장 팁: 자체 대시보드를 개발할 때는 먼저 Grafana UI에서 대시보드를 만든 다음, JSON으로 내보내서 values.yaml 파일에 추가하는 것이 좋습니다. 이렇게 하면 시각적으로 대시보드를 구성하고 테스트할 수 있습니다.


📌 고가용성 구성

프로덕션 환경에서는 모니터링 시스템의 가용성을 높이기 위한 구성이 필요합니다.

 

Prometheus HA 구성

# prometheus-ha.yaml
prometheus:
  prometheusSpec:
    replicas: 2  # 2개 이상의 복제본으로 고가용성 확보
    
    # 외부 레이블 설정
    # 여러 Prometheus 인스턴스에서 수집된 데이터를 구분하기 위한 레이블
    # $(POD_NAME)은 런타임에 파드 이름으로 대체되어 복제본 식별에 사용됨
    externalLabels:
      cluster: "production"  # 클러스터 식별자
      replica: "$(POD_NAME)"  # 복제본 식별자
    
    # 영구 스토리지 설정
    # 각 Prometheus 인스턴스는 별도의 PVC를 사용
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: standard  # 클러스터에서 사용 가능한 스토리지 클래스
          resources:
            requests:
              storage: 50Gi  # 각 인스턴스당 50GB 스토리지 요청
    
    # 원격 쓰기 설정
    # 모든 Prometheus 인스턴스에서 수집된 데이터를 외부 저장소(Thanos)로 전송
    # 이를 통해 장기 저장 및 글로벌 쿼리 기능 제공
    remoteWrite:
      - url: "http://thanos-receive.monitoring.svc.cluster.local:19291/api/v1/receive"

 

Alertmanager HA 구성

# alertmanager-ha.yaml
alertmanager:
  alertmanagerSpec:
    replicas: 3  # 3개의 복제본 (쿼럼 기반 HA를 위해 홀수 권장)
    
    # 노드 셀렉터 설정
    # 여러 가용 영역에 Alertmanager 인스턴스를 분산 배치하여 영역 장애에 대응
    nodeSelector:
      topology.kubernetes.io/zone: us-east-1a,us-east-1b,us-east-1c
    
    # 노드 안티어피니티 설정
    # 서로 다른 노드에 파드를 배포하여 단일 노드 장애 방지
    # requiredDuringScheduling...은 스케줄링 시 반드시 조건을 만족해야 함
    affinity:
      podAntiAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
        - labelSelector:
            matchExpressions:
            - key: app  # app 레이블이
              operator: In  # 다음 값들 중 하나와 일치할 때
              values:
              - alertmanager  # alertmanager 레이블을 가진 파드와
          topologyKey: "kubernetes.io/hostname"  # 같은 호스트에 스케줄링되지 않도록 함

 

Grafana HA 구성

# grafana-ha.yaml
grafana:
  replicas: 2  # 2개 이상의 복제본으로 고가용성 확보
  
  # 영구 스토리지 설정
  # 대시보드, 데이터 소스 등의 구성 정보 저장
  persistence:
    enabled: true
    storageClassName: standard  # 클러스터에서 사용 가능한 스토리지 클래스
    size: 10Gi  # 10GB 스토리지 요청
  
  # 외부 데이터베이스 구성 (PostgreSQL)
  # 기본 SQLite 대신 외부 PostgreSQL을 사용하여 다중 인스턴스 지원
  env:
    GF_DATABASE_TYPE: postgres  # 데이터베이스 타입 (PostgreSQL)
    GF_DATABASE_HOST: postgres.monitoring.svc.cluster.local:5432  # DB 호스트
    GF_DATABASE_NAME: grafana  # 데이터베이스 이름
    GF_DATABASE_USER: grafana  # 사용자 이름
    GF_DATABASE_SSL_MODE: disable  # SSL 모드 (개발 환경용, 프로덕션에서는 enable 권장)
  
  # 비밀번호를 시크릿에서 가져오기
  # 환경 변수값을 시크릿에서 참조하여 보안 강화
  envValueFrom:
    GF_DATABASE_PASSWORD:
      secretKeyRef:
        name: grafana-db-credentials  # 시크릿 이름
        key: password  # 시크릿 내 키
  
  # 세션 저장소 Redis 구성
  # 다중 인스턴스 간 세션 공유를 위한 Redis 사용
  env:
    GF_SESSION_PROVIDER: redis  # 세션 저장소 타입
    GF_SESSION_PROVIDER_CONFIG: addr=redis.monitoring.svc.cluster.local:6379,db=0,prefix=grafana:  # Redis 연결 정보

 

네트워크 분리 및 토폴로지 분산

# network-topology.yaml
prometheus:
  prometheusSpec:
    # Prometheus 파드 안티어피니티 설정
    # 서로 다른 노드에 파드를 배포하여 단일 노드 장애 영향 최소화
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - prometheus  # prometheus 레이블을 가진 파드끼리
        topologyKey: "kubernetes.io/hostname"  # 같은 호스트에 스케줄링되지 않도록 함

alertmanager:
  alertmanagerSpec:
    # Alertmanager 파드 안티어피니티 설정
    # 서로 다른 노드에 파드를 배포하여 단일 노드 장애 영향 최소화
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - alertmanager  # alertmanager 레이블을 가진 파드끼리
        topologyKey: "kubernetes.io/hostname"  # 같은 호스트에 스케줄링되지 않도록 함

# Node Exporter 설정
# 모든 노드에 Node Exporter 배포 보장
nodeExporter:
  tolerations:
  - operator: "Exists"  # 모든 테인트(taint)에 대해 허용
                       # 이를 통해 control-plane 노드를 포함한 모든 노드에 배포 가능

▶️ 고가용성 팁: 모니터링 시스템의 가용성만으로는 충분하지 않습니다. 장기 메트릭 스토리지를 위해 Thanos나 Cortex와 같은 솔루션을 고려하세요. 이러한 도구는 메트릭 데이터를 장기간 저장하고, 쿼리 성능을 향상시키며, 다중 클러스터 모니터링을 가능하게 합니다.


📌 Summary

  • Helm을 사용한 kube-prometheus-stack 설치는 모니터링 시스템을 쉽게 배포하고 관리할 수 있는 효율적인 방법입니다.
  • 설치 전 준비 과정에는 Helm 설정, 네임스페이스 생성, custom-values.yaml 파일 준비가 포함됩니다.
  • 설치 명령은 간단하지만, 프로덕션 환경에서는 사용자 정의 값과 특정 차트 버전을 지정하는 것이 좋습니다.
  • 설치 후 검증은 Pod 상태, Service 확인, 웹 인터페이스 접근, 기본 기능 검증으로 구성됩니다.
  • 일반적인 문제로는 Pod 시작 문제, 타겟 검색 문제, Grafana 설정 문제, 알림 전송 문제 등이 있으며, 각각의 해결 방법에 대해 알아보았습니다.
  • 업그레이드 및 관리는 Helm을 통해 간편하게 수행할 수 있으며, 문제 발생 시 롤백도 가능합니다.
  • 확장 및 커스터마이징으로 추가 ServiceMonitor, 알림 규칙, 외부 시스템 연동, 대시보드 추가 등을 수행할 수 있습니다.
  • 고가용성 구성은 Prometheus, Alertmanager, Grafana 각각에 대한 복제본 증가와 네트워크 분리 등을 통해 구현할 수 있습니다.

 

728x90