쿠버네티스 모니터링 구축

클러스터를 운영하려면 현재 사용량뿐 아니라 시간에 따른 변화와 장애 징후를 볼 수 있어야 합니다. 순간값은 Metrics Server, 장기 추세와 알림은 Prometheus·Grafana로 나눠 구성하면 이해하기 쉽습니다.

Metrics Server 설치

kubectl top은 Metrics Server가 kubelet의 Metrics API를 수집해야 동작합니다.

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kubectl -n kube-system rollout status deployment/metrics-server
kubectl top nodes
kubectl top pods -A --sort-by=memory

수집이 안 되면 Deployment 옵션부터 바꾸지 말고 로그와 API 상태를 확인합니다.

kubectl -n kube-system logs deployment/metrics-server
kubectl get apiservice v1beta1.metrics.k8s.io
kubectl describe apiservice v1beta1.metrics.k8s.io

kubelet 인증서 오류

x509: certificate ... doesn't contain any IP SANs가 나오면 kubelet 서빙 인증서가 문제입니다. kubeadm 클러스터에서는 각 노드의 /var/lib/kubelet/config.yaml에 다음 값을 설정하고 kubelet을 재시작합니다.

serverTLSBootstrap: true
systemctl restart kubelet
kubectl get csr

CSR의 요청자와 노드 이름을 확인한 뒤 해당 요청만 승인합니다.

kubectl describe csr [CSR_NAME]
kubectl certificate approve [CSR_NAME]

--kubelet-insecure-tls는 인증서 검증을 건너뛰므로 임시 실습 외에는 사용하지 않는 편이 안전합니다.

kube-prometheus-stack 설치

Prometheus, Grafana, Alertmanager, node-exporter, kube-state-metrics를 각각 관리하기보다 Prometheus Community의 kube-prometheus-stack Helm chart로 묶어 설치할 수 있습니다.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm show values prometheus-community/kube-prometheus-stack > values-reference.yaml

운영에 필요한 저장 기간과 PVC를 values.yaml에 명시합니다.

prometheus:
  prometheusSpec:
    retention: 15d
    retentionSize: 40GB
    resources:
      requests:
        cpu: 500m
        memory: 2Gi
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: nfs-client
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi

grafana:
  persistence:
    enabled: true
    storageClassName: nfs-client
    size: 5Gi

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: nfs-client
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 5Gi
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  --values values.yaml

kubectl -n monitoring get pods,pvc
kubectl -n monitoring get prometheus,alertmanager

스토리지가 없다면 먼저 쿠버네티스 NFS 프로비저닝을 준비합니다. PVC가 Pending이면 Pod보다 PVC 이벤트와 StorageClass부터 확인하세요.

Grafana와 Prometheus 접속

처음에는 NodePort로 상시 노출하지 말고 포트포워딩으로 확인합니다.

kubectl -n monitoring port-forward service/monitoring-grafana 3000:80
kubectl -n monitoring get secret monitoring-grafana \
  -o jsonpath='{.data.admin-password}' | base64 -d; echo

Prometheus 화면이 필요하면 Service 이름을 확인한 뒤 포트포워딩합니다.

kubectl -n monitoring get service | grep prometheus
kubectl -n monitoring port-forward service/monitoring-kube-prometheus-prometheus 9090:9090

Status → Targets에서 수집 대상이 UP인지 확인합니다. DOWN이면 ServiceMonitor selector, Service label, 포트 이름, NetworkPolicy 순으로 봅니다.

애플리케이션 메트릭 연결

애플리케이션이 /metrics를 제공한다면 Service의 포트에 이름을 붙이고 ServiceMonitor로 수집합니다.

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: api
  namespace: monitoring
  labels:
    release: monitoring
spec:
  namespaceSelector:
    matchNames: ["production"]
  selector:
    matchLabels:
      app: api
  endpoints:
    - port: metrics
      path: /metrics
      interval: 30s

chart의 selector 설정에 따라 release label이 필요할 수 있습니다. 적용 후 Prometheus Targets에서 새 대상이 발견됐는지 확인합니다.

알림 규칙 만들기

대시보드만 보고 있으면 사람이 자리를 비운 순간의 장애를 놓칩니다. PrometheusRule로 최소한의 노드·파드 알림을 추가합니다.

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: librat-operations
  namespace: monitoring
  labels:
    release: monitoring
spec:
  groups:
    - name: kubernetes-operations
      rules:
        - alert: NodeNotReady
          expr: kube_node_status_condition{condition="Ready",status="true"} == 0
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "노드 {{ $labels.node }}가 Ready가 아닙니다"
        - alert: PodCrashLooping
          expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
          for: 15m
          labels:
            severity: warning

Alertmanager의 이메일·Slack 같은 수신 채널은 Secret으로 관리하고 테스트 알림을 실제로 받아봐야 합니다.

운영 체크리스트

  • Prometheus PVC 사용량이 retentionSize에 가까워지는가
  • 모든 node-exporter와 kube-state-metrics target이 UP인가
  • Grafana 대시보드가 실제 cluster·namespace label을 사용하고 있는가
  • Alertmanager 알림이 담당자에게 도착하는가
  • chart 업그레이드 전에 values와 CRD 변경사항을 확인했는가

Helm 삭제 시 PVC와 CRD가 자동으로 모두 정리되는 것은 아닙니다. 특히 운영 데이터를 가진 PVC는 삭제 전에 보존 정책과 백업을 먼저 확인하세요.

참고: kube-prometheus-stack 공식 README, Kubernetes 관측성 개요