13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] k8s 모니터링

  • [k8s] OpenTelemetry K8s 마이그레이션: Prometheus 공존 전략과 함정

    [k8s] OpenTelemetry K8s 마이그레이션: Prometheus 공존 전략과 함정

    OpenTelemetry K8s 마이그레이션: Prometheus 공존 전략과 함정

    요즘 Prometheus에서 OpenTelemetry K8s로 마이그레이션을 고민하는 분들이 정말 많아요. 저도 홈랩이랑 사내 Kubernetes(쿠버네티스, 컨테이너 오케스트레이션) 환경을 굴리면서 비슷한 고민을 꽤 오래 했거든요. 기존 Prometheus(프로메테우스, 메트릭 수집 시스템)는 익숙하고 강력한데, 로그와 트레이스(trace, 분산 추적)까지 한 방향으로 정리하려고 보면 슬슬 한계가 보이더라고요. 특히 K8s 모니터링이 메트릭 중심으로만 굳어져 있으면 장애 원인 추적이 길어지고, 팀마다 도구가 갈라지는 순간 운영 피로도가 확 올라갑니다.

    처음엔 저도 “Prometheus 잘 쓰고 있는데 굳이 바꿔야 하나?” 싶었어요. 근데 실제로 OpenTelemetry(오픈텔레메트리, 통합 관측성 표준)를 붙여보니, 이건 단순히 수집기 하나 바꾸는 작업이 아니더군요. 옵저버빌리티 전환의 기준을 다시 세우는 일에 가깝습니다. 그래서 이번 글에서는 OpenTelemetry K8s 마이그레이션을 할 때 어떤 순서로 접근해야 덜 망가지는지, 어디서 많이 삽질하는지, 그리고 Prometheus를 완전히 버리기보다 어떻게 현실적으로 공존시킬지 제 경험 기준으로 풀어볼게요.

    Prometheus 중심 구조에서 OpenTelemetry Collector 중심 구조로 전환되는 전체 흐름을 한눈에 보여주는 이미지입니다.

    왜 지금 OpenTelemetry K8s 마이그레이션 이야기가 많을까

    쉽게 말해, 예전에는 메트릭(metrics, 수치형 운영 데이터)만 잘 봐도 운영이 됐어요. CPU, 메모리, 요청 수, 에러율 정도만 봐도 웬만한 장애는 잡혔거든요. 그런데 마이크로서비스가 늘어나고, 서비스 간 호출이 복잡해지면 그걸로는 부족합니다. 에러율이 올라간 건 알겠는데 어디서부터 꼬였는지를 찾는 시간이 너무 오래 걸려요.

    OpenTelemetry는 바로 이 지점을 건드립니다. 메트릭, 로그(logs, 로그 데이터), 트레이스까지 한 모델로 가져가려고 하죠. 여기서 중요한 포인트가 하나 있습니다. OpenTelemetry는 Prometheus의 완전한 대체재라기보다, 수집과 전송의 표준화 계층으로 이해하는 게 맞습니다. 저도 처음엔 이걸 헷갈려서 설계를 잘못 잡았었는데, Prometheus가 잘하던 영역과 OpenTelemetry가 잘하는 영역이 미묘하게 달라요.

    • Prometheus: pull 기반 메트릭 수집, PromQL(프로메스큐엘, Prometheus 질의 언어), 알림 규칙에 강합니다.
    • OpenTelemetry: 메트릭, 로그, 트레이스의 표준화된 수집과 변환, 다양한 백엔드 전송에 강해요.
    • Collector: 수집기이자 중간 파이프라인입니다. 여기서 필터링, 배치, 리소스 태깅을 처리하죠.

    그래서 Prometheus에서 OpenTelemetry K8s로 마이그레이션은 보통 “Prometheus 삭제”가 아니라, “수집 구조를 Collector 중심으로 재편하고 필요한 부분만 점진 전환”으로 가야 안전합니다.

    개념 먼저 정리: Prometheus와 OpenTelemetry는 어떻게 다른가

    저도 처음엔 용어가 너무 많아서 헷갈렸어요. Operator(오퍼레이터, 쿠버네티스 앱 관리 자동화), Exporter(익스포터, 특정 시스템 메트릭 노출기), Receiver(리시버, 수집 입력), Processor(프로세서, 데이터 가공기), Exporter는 또 OpenTelemetry 안에서도 다른 뜻으로 쓰이거든요. 여기서 한 번 깔끔하게 정리해볼게요.

    항목 Prometheus 중심 구조 OpenTelemetry 중심 구조
    수집 방식 주로 pull pull + push 혼합 가능
    주요 대상 메트릭 메트릭, 로그, 트레이스
    표준화 도구 중심 벤더 중립 표준
    가공 처리 제한적 Collector에서 풍부하게 처리
    전환 난이도 익숙함 설계 이해가 필요해요

    쉽게 말해 이런 느낌입니다.

    1. Prometheus는 메트릭 수집과 조회에 특화된 도구예요.
    2. OpenTelemetry는 데이터를 어떻게 모으고, 어떤 속성(attribute, 속성값)을 붙이고, 어디로 보낼지 표준화합니다.
    3. Kubernetes 환경에서는 OpenTelemetry Collector가 사실상 핵심이죠.

    여기서 독자분들이 가장 많이 오해하는 부분이 있어요. OpenTelemetry를 도입한다고 해서 PromQL 기반 대시보드나 알림을 바로 버릴 필요는 없습니다. 저도 이 부분을 무리하게 한 번에 바꾸려다가 롤백했었어요. 기존 운영 체계를 존중하면서 단계별로 옮겨야 합니다.

    마이그레이션 전에 먼저 결정해야 할 4가지

    실제로 써보니까, 기술보다 먼저 정해야 하는 건 운영 기준이었어요. 이걸 안 정하면 설정은 돌아가도 팀이 힘들어집니다.

    1. 최종 백엔드가 무엇인지 정하기

    Collector는 중간 계층이죠. 결국 메트릭과 트레이스를 어디에 저장하고 조회할지 정해야 해요. 기존 Prometheus를 유지할지, OTLP(OTLP, OpenTelemetry Protocol) 수신 가능한 백엔드를 붙일지, 로그 저장소와 어떻게 나눌지 먼저 결정해야 합니다.

    2. 어떤 신호(signal)부터 옮길지 정하기

    메트릭부터 갈지, 애플리케이션 트레이스부터 붙일지, 노드/파드 수준 K8s 모니터링부터 정리할지 우선순위를 잡아야 해요. 제 경험상 가장 무난한 순서는 이렇습니다.

    1. 인프라 메트릭 유지
    2. Collector 배포
    3. 애플리케이션 트레이스 추가
    4. 메트릭 라우팅 정리
    5. 로그 연계 검토

    3. 라벨(label)과 리소스 속성(attribute) 기준 통일

    이게 진짜 중요합니다. Prometheus 쪽 label과 OpenTelemetry 쪽 resource attribute가 섞이면 쿼리와 대시보드가 다 꼬여요. namespace, pod, service, cluster 같은 공통 키를 먼저 합의하세요.

    4. 샘플링(sampling, 일부만 수집) 전략 정하기

    트레이스는 전부 모으면 부담이 커져요. 특히 K8s에서 서비스 수가 많아지면 수집량이 금방 늘어요. 처음부터 100% 수집을 고집하기보다, 핵심 서비스 기준으로 시작하는 게 현실적입니다.

    OpenTelemetry K8s 마이그레이션에서 Collector 구성도

    DaemonSet 또는 Deployment 형태의 Collector가 어떤 데이터를 받고 어디로 보내는지 설명하는 구성 이미지입니다.

    실전 구현: Kubernetes에 OpenTelemetry Collector 배포하기

    이제 실제 구성을 봐볼게요. 여기서는 가장 많이 쓰는 패턴인 Collector를 Kubernetes에 배포하고, Prometheus scrape 대상 일부를 Collector로 옮기는 방식을 기준으로 설명하겠습니다. 특정 배포 도구를 강제하진 않을게요. Helm(헬름, 쿠버네티스 패키지 매니저)을 쓰든 매니페스트를 쓰든 핵심 구조는 비슷하거든요.

    1. 기본 Collector 설정 예시

    아래 예시는 개념 설명용으로 단순화한 구성입니다. 실제 운영에서는 인증, 리소스 제한, 백엔드 주소, 필터링 규칙을 환경에 맞춰 넣어야 해요.

    receivers:
      otlp:
        protocols:
          grpc:
          http:
      prometheus:
        config:
          scrape_configs:
            - job_name: 'kubernetes-pods'
              kubernetes_sd_configs:
                - role: pod
              relabel_configs:
                - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
                  action: keep
                  regex: true
    
    processors:
      batch:
      memory_limiter:
        check_interval: 1s
        limit_percentage: 75
        spike_limit_percentage: 15
      resource:
        attributes:
          - key: deployment.environment
            value: homelab
            action: upsert
    
    exporters:
      debug: {}
      otlp:
        endpoint: otel-backend.example.local:4317
        tls:
          insecure: true
    
    service:
      pipelines:
        metrics:
          receivers: [prometheus, otlp]
          processors: [memory_limiter, batch, resource]
          exporters: [debug, otlp]
        traces:
          receivers: [otlp]
          processors: [memory_limiter, batch, resource]
          exporters: [debug, otlp]

    여기서 핵심은 세 가지예요.

    • receivers: 데이터를 어디서 받을지 정의합니다.
    • processors: 배치 처리, 메모리 제한, 공통 속성 추가를 담당해요.
    • exporters: 어디로 보낼지 정의합니다.

    처음엔 debug exporter를 꼭 켜두세요. 저도 이걸 안 켜고 한참 헤맸어요. 데이터가 안 보일 때 수집이 안 되는 건지, 가공이 잘못된 건지, 전송이 막힌 건지 구분이 안 되거든요.

    2. Kubernetes 리소스 예시

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: otel-collector
      namespace: observability
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: otel-collector
      template:
        metadata:
          labels:
            app: otel-collector
        spec:
          containers:
            - name: otel-collector
              image: otel/opentelemetry-collector:latest
              args:
                - "--config=/conf/otel-collector-config.yaml"
              ports:
                - containerPort: 4317
                - containerPort: 4318
              volumeMounts:
                - name: config
                  mountPath: /conf
          volumes:
            - name: config
              configMap:
                name: otel-collector-config

    실무에서는 DaemonSet(데몬셋, 노드마다 하나씩 배포)도 많이 써요. 노드 단위 수집이나 에이전트 성격이 강하면 DaemonSet이 자연스럽고, 중앙 수집기면 Deployment가 편합니다. 둘 중 뭐가 정답이다, 이건 없어요. 수집 대상과 트래픽 경로를 보고 정해야 합니다.

    3. 애플리케이션에서 OTLP로 보내기

    애플리케이션이 OpenTelemetry SDK를 지원한다면 OTLP endpoint를 Collector로 맞추면 돼요. 언어별 설정은 다르지만 원리는 비슷합니다.

    export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector.observability.svc.cluster.local:4318
    export OTEL_SERVICE_NAME=my-api
    export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=prod,k8s.namespace.name=default

    여기서 중요한 포인트! 애플리케이션마다 서비스 이름 규칙이 제각각이면 나중에 대시보드가 정말 난장판이 돼요. 저도 처음엔 서비스명이 코드 저장소 이름, 배포명, 제품명으로 다 달라서 정리하느라 고생했네요 ㅎㅎ

    Prometheus를 바로 걷어내지 말고 공존 기간을 두세요

    이건 경험에서 나온 조언이에요. 옵저버빌리티 전환을 할 때 가장 위험한 패턴이 “이번 분기 안에 다 바꾸자”예요. 겉보기엔 속도가 나는데, 운영팀만 죽어납니다. 알람 공백이 생기고, 대시보드 신뢰도가 떨어지고, 결국 새 체계가 욕을 먹게 돼요.

    제가 추천하는 건 다음과 같은 병행 운영이에요.

    1. 기존 Prometheus 알림과 대시보드는 유지합니다.
    2. OpenTelemetry Collector로 동일한 메트릭 일부를 병행 수집해요.
    3. 핵심 서비스에만 트레이스를 먼저 붙입니다.
    4. 장애 대응 시 새 데이터가 실제로 도움이 되는지 검증해요.
    5. 검증이 끝난 뒤에만 대시보드와 알림을 전환합니다.

    이 방식이 느려 보이지만, 실제로는 제일 빨아요. 왜냐면 롤백 비용이 낮거든요.

    ⚠️ 실제로 많이 겪는 함정과 트러블슈팅

    여기부터는 제가 직접 해보니 자주 부딪히는 문제들이에요. OpenTelemetry K8s 마이그레이션에서 대부분 여기서 시간 써요.

    1. 라벨과 속성 이름이 서로 달라서 쿼리가 깨짐

    Prometheus의 `job`, `instance`, `namespace`와 OpenTelemetry resource attribute가 1:1로 안 맞는 경우가 많아요. 그 결과 대시보드가 비어 보이거나, 같은 서비스가 여러 이름으로 나뉘어 보이죠.

    해결: 공통 키 매핑 표를 먼저 만드세요. 운영팀, 개발팀이 같이 보는 문서가 있어야 해요.

    2. Collector가 만능인 줄 알고 모든 변환을 몰아넣음

    처음엔 저도 그랬어요. 필터링, 이름 변경, 태깅, 라우팅, 샘플링을 Collector 하나에 계속 추가하다 보면 설정이 금방 복잡해져요. 그러면 장애 시 디버깅이 힘들어요.

    해결: Processor는 최소한으로 시작하고, 꼭 필요한 것만 추가하세요. 먼저 배치, 메모리 제한, 공통 속성 정도로 출발하는 게 좋아요.

    3. 트레이스 수집량 폭증

    마이크로서비스 호출이 많으면 생각보다 데이터가 빠르게 늘어나요. 특히 개발 환경에서 무심코 다 켜두면 저장소와 네트워크 부담이 커질 수 있어요.

    해결: 전면 수집보다 핵심 API부터 시작하세요. 에러 구간 위주로 샘플링하거나, 특정 네임스페이스부터 적용하는 식이 현실적입니다.

    4. Prometheus scrape와 OTLP push를 동시에 붙였는데 중복 메트릭 발생

    이거 꽤 흔해요. 같은 애플리케이션 메트릭이 Prometheus scrape 경로와 OTLP 경로 둘 다 들어와서 그래프가 이상해질 수 있어요.

    해결: 신호별 소유권을 정하세요. 예를 들어 애플리케이션 메트릭은 OTLP, 인프라 메트릭은 기존 scrape처럼 명확히 나누는 거예요.

    5. Kubernetes 메타데이터가 기대만큼 안 붙음

    pod, node, namespace 정보가 자동으로 다 붙을 거라 기대했는데, 실제로는 배포 방식이나 권한 설정에 따라 부족할 수 있어요.

    해결: 서비스 계정 권한, 리소스 탐지 방식, Collector 배치 위치를 같이 점검하세요. 특히 K8s 메타데이터 enrich(강화)가 안 되면 트러블슈팅 난이도가 확 올라가요.

    OpenTelemetry K8s 마이그레이션 함정과 트러블슈팅 이미지

    실제 마이그레이션에서 자주 발생하는 문제 지점을 강조한 트러블슈팅 시각 자료입니다.

    검증은 이렇게 하시면 돼요

    구성이 적용됐다고 끝이 아니에요. 드디어 됐다! 싶었는데 실제로는 일부 서비스만 보이고, 속성 누락이 있고, 중복 수집이 있는 경우가 많거든요. 저는 아래 순서로 검증해요.

    1. Collector 로그에서 수신과 전송 여부를 확인합니다.
    2. 기존 Prometheus 수치와 새 파이프라인 수치를 큰 흐름 기준으로 비교해요.
    3. 트레이스 한 건을 선택해서 서비스 간 호출 연결이 보이는지 확인합니다.
    4. namespace, pod, service 이름이 일관되게 붙는지 확인해요.
    5. 장애 상황을 일부러 만들어서 실제 분석 시간이 줄어드는지 봅니다.

    간단한 확인 명령 예시는 이런 식이에요.

    kubectl get pods -n observability
    kubectl logs -n observability deploy/otel-collector
    kubectl port-forward -n observability deploy/otel-collector 4318:4318

    그리고 Prometheus 메트릭을 계속 보는 환경이라면, 병행 구간에서는 아래 체크리스트가 유용해요.

    • 기존 알림 규칙이 그대로 동작하는가
    • OpenTelemetry 경로로 들어온 메트릭의 이름과 단위가 일관적인가
    • 트레이스에서 서비스 호출 병목 구간이 눈에 띄는가
    • 운영자가 새 쿼리 모델을 이해할 수 있는가

    이 검증을 해보면 단순히 “데이터가 들어온다”보다 중요한 게 보여요. 문제를 더 빨리 찾을 수 있느냐가 진짜 기준이거든요.

    OpenTelemetry K8s 마이그레이션 결과 대시보드 이미지

    메트릭 그래프와 분산 추적 결과가 함께 보이는 검증 단계의 대시보드 이미지를 배치할 위치입니다.

    결과적으로 무엇이 좋아졌나

    제가 느낀 가장 큰 변화는 장애 대응 대화가 바뀌었다는 점이에요. 예전에는 “CPU는 정상인데 왜 느리지?”에서 한참 머물렀다면, OpenTelemetry 도입 뒤에는 “어느 서비스 호출에서 지연이 시작됐는지”를 더 빨리 볼 수 있었어요. 이거 진짜 편하더라고요.

    물론 Prometheus 자체의 가치가 줄어든 건 아니에요. 여전히 K8s 모니터링에서 메트릭은 기본 중의 기본이고, 알림과 시계열 분석은 아주 중요합니다. 다만 옵저버빌리티 전환 관점에서는 메트릭 중심 운영에서 컨텍스트 중심 운영으로 넘어가는 느낌이 분명히 있어요.

    비교 항목 전환 전 전환 후
    장애 감지 메트릭 경보 중심 메트릭 + 트레이스 조합
    원인 추적 로그를 따로 뒤짐 서비스 호출 흐름 기준 탐색
    운영 표준 도구별 설정 분산 Collector 중심 파이프라인 정리
    확장성 메트릭 중심 다양한 신호 통합 가능

    정리: 성공 전략은 “점진 전환”입니다

    이번 글의 핵심을 한 줄로 줄이면 이거예요. Prometheus에서 OpenTelemetry K8s로 마이그레이션할 때는 도구 교체가 아니라 운영 모델 전환으로 접근해야 해요. 저도 처음엔 설정 파일만 맞추면 끝날 줄 알았는데, 실제로는 라벨 체계, 샘플링 기준, 공존 기간 설계가 훨씬 중요했어요.

    정리해보면 성공 전략은 이래요.

    • Prometheus를 바로 버리지 말고 공존 기간을 둬요.
    • 메트릭보다 먼저 데이터 모델과 속성 체계를 정리합니다.
    • Collector는 단순하게 시작하고 점진적으로 확장해요.
    • 트레이스는 핵심 서비스부터 붙입니다.
    • 검증 기준은 “수집 여부”가 아니라 “문제 해결 속도”로 잡으세요.

    혹시 지금 OpenTelemetry 도입을 검토 중인데 너무 복잡해 보여서 멈춰 계셨다면, 저라면 제일 먼저 Collector 하나 띄우고, 가장 중요한 서비스 한 개에만 트레이스 붙여보는 것부터 권할게요. 그 한 번이 전체 방향을 많이 보여주거든요.

    다음 글에서는 Kubernetes 환경에서 OpenTelemetry Collector를 DaemonSet과 Deployment 중 어떤 패턴으로 나누는 게 좋은지, 그리고 운영 중 설정이 비대해질 때 어떻게 분리하는지 다뤄볼 거예요. 이전 글에서 다룬 Prometheus 알림 설계 원칙과 같이 보시면 훨씬 연결이 잘 될 거라고 생각해요.

    Prometheus와 OpenTelemetry 점진 전환 전략 요약 이미지

    마이그레이션 단계, 주의사항, 검증 포인트를 한 장으로 정리한 요약 이미지가 들어갈 위치입니다.

    자주 묻는 질문

    Q1. OpenTelemetry를 도입하면 Prometheus는 없어도 되나요?

    반드시 그렇진 않아요. 특히 기존 PromQL 쿼리, 대시보드, 알림 체계가 잘 돌아간다면 당분간 공존하는 편이 안전합니다.

    Q2. K8s 모니터링은 메트릭부터 옮겨야 하나요?

    상황에 따라 다르지만, 보통은 인프라 메트릭은 유지하고 애플리케이션 트레이스부터 붙여보는 방식이 체감 효과가 커요.

    Q3. 가장 큰 함정은 무엇인가요?

    제가 보기엔 라벨과 속성 체계를 통일하지 않고 시작하는 거예요. 나중에 대시보드와 검색 조건이 전부 어긋나거든요.

    Q4. 옵저버빌리티 전환의 성공 기준은 뭔가요?

    새 도구가 예뻐 보이는지가 아니라, 장애가 났을 때 원인 찾는 시간이 줄었는지가 핵심이에요. 결국 운영은 그걸로 평가받거든요.

  • [k8s] OpenTelemetry K8s 모니터링, 비용 효율적인 구축 전략

    [k8s] OpenTelemetry K8s 모니터링, 비용 효율적인 구축 전략

    OpenTelemetry K8s 모니터링, 비용 효율적인 구축 전략

    안녕하세요, 13년차의 서버실 주인장입니다. 😎

    요즘 Kubernetes(쿠버네티스) 환경에서 애플리케이션을 운영하는 건 거의 기본이 되었죠. 근데 이 복잡한 환경을 제대로 모니터링하는 게 정말 쉽지 않더라고요. 특히 OpenTelemetry K8s 모니터링은 분산 시스템의 가시성(Observability)을 확보하는 데 필수적인데, 이걸 어떻게 구축해야 할지 막막한 분들이 많으실 거예요.

    비용 문제도 무시할 수 없죠. 상용 모니터링 솔루션은 비싸고, 직접 구축하려니 삽질이 이만저만이 아니거든요. 😅

    오늘은 제가 직접 Kubernetes 모니터링을 OpenTelemetry로 구축하면서 겪었던 삽질과, 어떻게 하면 비용 효율적인 구축 전략을 가져갈 수 있는지 제 경험을 바탕으로 이야기해보려 합니다. 초기엔 저도 뭐가 뭔지 헷갈렸는데, 결국 해내고 나니 뿌듯하더라고요. 함께 가시죠! 💪

    OpenTelemetry를 활용한 Kubernetes 모니터링 아키텍처는 위 그림처럼 구성할 수 있습니다. 데이터를 수집하고 백엔드로 보내는 과정이 깔끔하죠.

    개념 설명: OpenTelemetry, K8s 모니터링의 핵심

    자, 그럼 핵심 개념부터 간단히 짚고 넘어갈까요?

    • Observability(옵저버빌리티): 시스템 내부 상태를 외부에서 추론할 수 있는 능력입니다. 주로 Metrics(메트릭), Logs(로그), Traces(트레이스) 세 가지 기둥으로 구성되거든요. 이 세 가지를 제대로 봐야 시스템에서 무슨 일이 일어나는지 파악할 수 있죠.
    • OpenTelemetry(오픈텔레메트리): 이 옵저버빌리티 데이터를 수집하고, 처리하고, 내보내는 표준화된 프레임워크입니다. 벤더 종속성을 줄여주는 엄청난 장점이 있어요. 예전에는 각 모니터링 솔루션마다 에이전트를 다르게 심고 그랬었는데, OpenTelemetry 덕분에 한 번만 계측(Instrumentation)하면 다양한 백엔드로 데이터를 보낼 수 있게 된 거죠. 이게 진짜 편하더라고요!
    • Kubernetes 모니터링: K8s 클러스터 내의 Pod(파드), Node(노드), Deployment(디플로이먼트) 등의 상태와 성능을 지속적으로 관찰하는 활동입니다. CPU 사용량, 메모리, 네트워크 트래픽부터 애플리케이션 로그, 에러 트레이스까지 다 포함되거든요.
    • 비용 분석: 모니터링 솔루션은 데이터 수집량에 따라 비용이 천차만별입니다. 특히 클라우드 환경에서는 데이터 전송량, 저장량, 쿼리량 등에 따라 과금되기 때문에, 불필요한 데이터를 줄이고 효율적으로 관리하는 전략이 정말 중요하더라고요. 놓치면 배보다 배꼽이 더 커질 수 있거든요.

    실전 구현: OpenTelemetry Collector와 백엔드 구축

    이제 본격적으로 OpenTelemetry Collector를 K8s에 배포하고, 데이터를 수집하는 방법을 알아볼게요. 저는 비용 효율성을 위해 Prometheus(프로메테우스) + Grafana(그라파나) 조합으로 메트릭을, Loki(로키)로 로그를, Jaeger(예거)로 트레이스를 수집하는 방법을 선호합니다. 다 오픈소스라서 초기 비용 부담이 적거든요. 제 홈랩에서도 이 조합으로 잘 쓰고 있습니다. 👍

    먼저 OpenTelemetry Collector를 DaemonSet(데몬셋)으로 배포해서 각 노드에서 데이터를 수집하도록 설정합니다. 이게 가장 일반적이고 안정적인 방법이에요.

    # opentelemetry-collector-daemonset.yaml
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: otel-collector
      namespace: monitoring
      labels:
        app: otel-collector
    spec:
      selector:
        matchLabels:
          app: otel-collector
      template:
        metadata:
          labels:
            app: otel-collector
        spec:
          serviceAccountName: otel-collector
          containers:
          - name: otel-collector
            image: otel/opentelemetry-collector:0.87.0 # 최신 안정 버전 확인 필요합니다. 공식 도커 허브를 참고하세요!
            command: ["--config=/conf/otel-collector-config.yaml"]
            volumeMounts:
            - name: otel-collector-config-vol
              mountPath: /conf
            - name: host-proc
              mountPath: /proc
              readOnly: true
            - name: host-sys
              mountPath: /sys
              readOnly: true
            securityContext:
              privileged: true # 노드 메트릭 수집을 위해 필요할 수 있습니다. 보안에 유의하세요.
          volumes:
          - name: otel-collector-config-vol
            configMap:
              name: otel-collector-config
          - name: host-proc
            hostPath:
              path: /proc
          - name: host-sys
            hostPath:
              path: /sys
    

    다음은 ConfigMap(컨피그맵)으로 OpenTelemetry Collector의 설정을 정의합니다. 여기서 중요한 건 어떤 데이터를 수집해서 어디로 보낼지 정의하는 부분이에요. Receivers, Processors, Exporters가 핵심이죠.

    # opentelemetry-collector-config.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: otel-collector-config
      namespace: monitoring
    data:
      otel-collector-config.yaml: |
        receivers:
          otlp:
            protocols:
              grpc:
              http:
          prometheus:
            config:
              scrape_configs:
                - job_name: 'kubernetes-nodes'
                  scrape_interval: 15s
                  kubernetes_sd_configs:
                    - role: node
                  relabel_configs:
                    - action: labelmap
                      regex: __meta_kubernetes_node_label_(.+)
                    - target_label: __address__
                      replacement: kubernetes.default.svc:443
                    - source_labels: [__meta_kubernetes_node_name]
                      regex: (.+)
                      target_label: __metrics_path__
                      replacement: /api/v1/nodes/${1}/proxy/metrics
                - job_name: 'kubernetes-pods'
                  kubernetes_sd_configs:
                    - role: pod
                  relabel_configs:
                    - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
                      action: keep
                      regex: true
                    - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
                      action: replace
                      target_label: __metrics_path__
                      regex: (.+)
                    - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
                      action: replace
                      regex: ([^:]+)(?::\d+)?;(\d+)
                      target_label: __address__
                      replacement: $1:$2
                    - action: labelmap
                      regex: __meta_kubernetes_pod_label_(.+)
                    - source_labels: [__meta_kubernetes_namespace]
                      action: replace
                      target_label: kubernetes_namespace
                    - source_labels: [__meta_kubernetes_pod_name]
                      action: replace
                      target_label: kubernetes_pod_name
        
        processors:
          batch:
            send_batch_size: 1000
            timeout: 5s
          memory_limiter:
            limit_mib: 200
            spike_limit_mib: 50
          resourcedetection:
            detectors: [env, system, kubernetes]
            timeout: 2s
            kubernetes:
              pod_association:
                - from: cgroup
                - from: resource_attribute
                  key: k8s.pod.uid
          attributes:
            actions:
              - key: host.name
                action: delete
              - key: host.id
                action: delete
              - key: os.type
                action: delete
        
        exporters:
          prometheus:
            endpoint: "0.0.0.0:8889" # Prometheus가 이 엔드포인트를 스크래핑하여 메트릭 수집
          prometheusremotewrite:
            endpoint: "http://prometheus-server.monitoring.svc.cluster.local:9090/api/v1/write" # Prometheus Remote Write API
          otlp/logs:
            endpoint: "loki.monitoring.svc.cluster.local:3100" # Loki OTLP/HTTP Endpoint
            tls:
              insecure: true # 개발 환경에서만 사용하세요. 프로덕션에서는 TLS 구성이 필요합니다.
          otlp/traces:
            endpoint: "jaeger-collector.monitoring.svc.cluster.local:14250" # Jaeger gRPC Endpoint
            tls:
              insecure: true # 개발 환경에서만 사용하세요. 프로덕션에서는 TLS 구성이 필요합니다.
    
        service:
          pipelines:
            metrics:
              receivers: [otlp, prometheus]
              processors: [resourcedetection, attributes, batch, memory_limiter]
              exporters: [prometheus, prometheusremotewrite] # prometheus는 메트릭 노출, prometheusremotewrite는 원격 Prometheus로 전송
            logs:
              receivers: [otlp]
              processors: [resourcedetection, attributes, batch, memory_limiter]
              exporters: [otlp/logs]
            traces:
              receivers: [otlp]
              processors: [resourcedetection, attributes, batch, memory_limiter]
              exporters: [otlp/traces]
    

    여기서 exporters 부분을 보면 Prometheus, Loki, Jaeger로 데이터를 보내도록 설정한 걸 볼 수 있죠. 각 백엔드에 맞게 엔드포인트를 지정해주면 됩니다. 특히 processors 섹션에서 attributes를 사용해서 불필요한 메트릭 속성들을 제거하는 게 비용 효율적인 모니터링에 큰 도움이 되더라고요. 클라우드에서 데이터 전송량이나 저장량 줄이는 데 효과 만점입니다. 💡

    OpenTelemetry Collector와 모니터링 백엔드 상세 구성도

    OpenTelemetry Collector와 모니터링 백엔드 간의 상세 데이터 흐름 구성도입니다. 이 그림을 보면서 각 컴포넌트가 어떻게 연결되는지 쉽게 이해할 수 있을 거예요.

    주의사항/트러블슈팅: 삽질 피하기! ⚠️

    제가 이 부분에서 삽질을 좀 많이 했었습니다. 여러분은 이런 실수 안 하시길 바라면서 몇 가지 중요한 주의사항과 해결법을 공유해드릴게요. 멘토의 조언이라고 생각해주세요! 😉

    • ⚠️ 권한 문제: OpenTelemetry Collector가 노드 메트릭을 제대로 수집하려면 host-proc, host-sys 마운트와 privileged: true 설정이 필요할 수 있거든요. 보안상 민감한 부분이니 필요한 최소한의 권한만 부여하는 게 중요해요. 처음엔 권한 부족으로 메트릭이 안 들어와서 한참 헤맸습니다.
    • ⚠️ 설정 파일 오타: YAML 파일은 스페이스 하나에도 민감하죠. 특히 ConfigMap에 data 아래에 otel-collector-config.yaml: | 부분의 들여쓰기를 조심하세요. 오타 하나 때문에 Collector가 시작도 안 되는 경우가 허다하거든요. kubectl logs로 Collector Pod의 로그를 꼭 확인하세요.
    • ⚠️ 네트워크 문제: 백엔드(Prometheus, Loki, Jaeger)의 서비스 이름과 포트가 정확한지 확인해야 합니다. 특히 K8s 클러스터 내에서 service.namespace.svc.cluster.local 형태로 접근하는 게 일반적이에요. 방화벽이나 NetworkPolicy(네트워크 정책) 때문에 통신이 안 되는 경우도 많으니 kubectl exec로 Collector Pod에 들어가서 curl 등으로 연결 테스트를 해보는 게 좋습니다.
    • 💡 데이터 과부하: OpenTelemetry Collector의 memory_limiter와 batch 프로세서를 적절히 설정해서 Collector가 과도한 리소스를 사용하거나, 데이터 전송에 병목이 생기는 걸 방지해야 합니다. 저도 한 번 Collector가 메모리 폭주해서 노드가 비정상적으로 동작하는 바람에 새벽에 호출된 적이 있습니다… 😅

    검증/결과: 모니터링 대시보드 확인

    이제 모든 설정이 끝났으니, 제대로 동작하는지 확인해볼 시간입니다! 🎉 드디어 됐다! 하고 외칠 준비 되셨죠?

    1. 먼저 Grafana(그라파나)에 접속해서 Prometheus 데이터 소스를 추가하고, Kubernetes 노드/파드 메트릭 대시보드를 임포트해보세요. 저는 보통 Node Exporter Full이나 Kubernetes / Kubelet 대시보드를 사용합니다.
    2. 로그는 Loki에 쌓인 데이터를 Grafana의 Explore(탐색) 기능으로 확인하거나, Loki 전용 대시보드를 만들어 볼 수 있습니다. logcli 같은 도구로도 확인 가능하고요.
    3. 트레이스는 Jaeger UI에 접속해서 애플리케이션에서 보낸 트레이스가 잘 수집되는지 확인합니다. 서비스 이름과 오퍼레이션 이름으로 검색해보면 되겠죠.

    OpenTelemetry K8s 모니터링 Grafana 대시보드 예시

    OpenTelemetry로 수집한 Kubernetes 메트릭을 Grafana 대시보드에서 시각화한 모습입니다. 이렇게 한눈에 시스템 상태를 파악할 수 있으면 얼마나 든든한지 몰라요!

    마무리: 비용 효율과 미래를 위한 전략

    오늘은 OpenTelemetry K8s 모니터링을 비용 효율적으로 구축하는 전략에 대해 제 경험을 공유해드렸습니다.

    가장 중요한 포인트는 OpenTelemetry를 통해 특정 벤더에 종속되지 않고, 오픈소스 백엔드(Prometheus, Grafana, Loki, Jaeger)를 활용하여 초기 구축 비용을 최소화하는 것이었습니다. 이 조합은 특히 홈랩이나 소규모 프로젝트에서 빛을 발하더라고요.

    특히 OpenTelemetry Collector의 processors를 활용하여 불필요한 데이터를 필터링하고, 샘플링(Sampling) 전략을 적용하는 것이 클라우드 환경에서 비용 분석 및 절감에 큰 영향을 미친다는 점을 꼭 기억해주세요. 제가 이 부분에서 시행착오를 많이 겪었거든요. 데이터 양을 줄이는 게 진짜 중요합니다!

    Kubernetes 모니터링은 한 번 구축했다고 끝이 아닙니다. 지속적으로 데이터를 분석하고, 대시보드를 개선하며, 새로운 요구사항에 맞춰 시스템을 확장해나가야 하거든요. OpenTelemetry는 앞으로도 옵저버빌리티 분야에서 핵심적인 역할을 할 것이 분명합니다. 여러분의 환경에 맞춰 최적의 비용 효율적인 구축 전략을 찾아보시길 바랍니다. 다음 기회에 심화 내용을 다뤄볼게요! 😊

    OpenTelemetry를 활용한 비용 효율적인 Kubernetes 모니터링 이점

    OpenTelemetry를 통한 모니터링 구축은 단순히 기술적인 선택을 넘어, 장기적인 관점에서 비용 효율성과 유연성을 확보하는 전략적인 결정이 될 수 있습니다.

  • [k8s] 쿠버네티스 모니터링: Prometheus & Grafana 구축 및 대시보드 활용 가이드

    [k8s] 쿠버네티스 모니터링: Prometheus & Grafana 구축 및 대시보드 활용 가이드

    🚀 쿠버네티스 모니터링, 왜 중요할까요?

    안녕하세요, 13년차의 서버실 주인장입니다. 오늘은 쿠버네티스 모니터링의 핵심이라고 할 수 있는 Prometheus(프로메테우스)와 Grafana(그라파나) 구축 경험을 공유해볼까 합니다. 쿠버네티스 환경을 운영하다 보면 ‘도대체 내 파드는 잘 돌고 있나?’, ‘CPU 사용량이 왜 이렇게 높지?’, ‘메모리 누수가 생긴 건 아닐까?’ 같은 고민을 하게 되죠.

    저도 처음 쿠버네티스를 도입했을 때, 여러 파드들이 여기저기서 돌아다니는데 이걸 어떻게 한눈에 볼 수 있을까 막막했어요. 로그를 일일이 뒤져보는 것도 한계가 있고요. 그때 제 눈을 번쩍 뜨이게 한 것이 바로 Prometheus와 Grafana 조합이었습니다. 이 두 가지 도구 덕분에 제 홈랩의 쿠버네티스 클러스터는 24시간 감시 체제를 갖추게 되었고, 문제가 생기면 빠르게 파악하고 조치할 수 있게 됐죠. 마치 제 서버실에 똑똑한 비서 한 명을 들인 기분이랄까요?

    이번 글에서는 이 강력한 모니터링 스택을 어떻게 구축하고, 어떤 대시보드를 활용하면 좋을지 제 경험을 녹여서 자세히 알려드리겠습니다. 삽질했던 부분들도 솔직하게 공유할 테니, 여러분은 저처럼 헤매지 않으시길 바랍니다! 자, 그럼 시작해볼까요?

    쿠버네티스 환경에서 Prometheus와 Grafana를 이용한 모니터링 시스템의 전체 아키텍처 다이어그램입니다.

    💡 Prometheus와 Grafana, 핵심 개념 파헤치기

    자, 이제 본론으로 들어가서 쿠버네티스 모니터링의 양대 산맥인 Prometheus(프로메테우스)와 Grafana(그라파나)에 대해 좀 더 깊이 있게 알아볼까요? 처음엔 이름도 어렵고, 뭐가 뭔지 헷갈렸는데, 사실 원리만 이해하면 생각보다 간단하더라고요.

    Prometheus (프로메테우스): 지표 수집의 달인

    Prometheus는 오픈 소스 모니터링 시스템으로, 시계열 데이터베이스(Time-series Database, TSDB)를 기반으로 합니다. 쉽게 말해, 시간의 흐름에 따라 변화하는 다양한 지표(Metrics)들을 수집하고 저장하는 데 특화된 도구거든요. 기존의 많은 모니터링 시스템이 에이전트가 데이터를 서버로 밀어 넣는 Push 방식이었다면, Prometheus는 대상으로부터 데이터를 Pull(가져오는) 방식을 사용합니다. 이 방식은 서비스 디스커버리(Service Discovery)와 결합될 때 쿠버네티스 같은 동적인 환경에서 정말 큰 시너지를 내거든요.

    • Metrics (메트릭, 지표 데이터): CPU 사용량, 메모리 사용량, 네트워크 트래픽 등 서버나 애플리케이션의 상태를 나타내는 수치 데이터입니다.
    • Exporters (익스포터): Prometheus가 지표를 가져올 수 있도록 데이터를 노출하는 작은 에이전트예요. 예를 들어, 서버의 OS 지표를 수집하는 Node Exporter나 쿠버네티스 노드/파드의 지표를 수집하는 cAdvisor 같은 것들이죠.
    • Service Discovery (서비스 디스커버리): 쿠버네티스 환경에서는 파드(Pod)가 수시로 생성되고 사라집니다. Prometheus는 이런 변화를 감지해서 자동으로 새로운 모니터링 대상을 찾아냅니다. 정말 편리하더라고요.

    Grafana (그라파나): 시각화의 마법사

    Prometheus가 지표를 열심히 수집하고 저장해놨다면, Grafana는 그 데이터를 멋진 그래프와 대시보드로 시각화해주는 도구입니다. 복잡한 숫자들을 한눈에 알아보기 쉽게 보여주니까, 이상 징후를 빠르게 파악하고 문제 해결에 집중할 수 있게 도와주죠. 처음에는 Grafana UI가 좀 어려웠는데, 몇 번 써보니 이거 진짜 물건이더라고요! 다양한 데이터 소스(Prometheus 외에도 많은 DB를 지원합니다)를 연결해서 대시보드를 만들 수 있고, 커스텀도 자유롭습니다.

    🛠️ 실전! Helm으로 Prometheus & Grafana 배포하기

    이제 이론은 충분히 봤으니, 실제로 쿠버네티스 클러스터에 Prometheus와 Grafana를 배포해보겠습니다. 저는 Helm(헬름)을 이용하는 것을 선호하는데, 복잡한 쿠버네티스 리소스들을 한 번에 쉽게 배포하고 관리할 수 있거든요. 마치 패키지 매니저처럼요!

    사전 준비물

    1. 동작하는 쿠버네티스 클러스터 (저는 홈랩에서 Kubeadm으로 구성한 클러스터를 사용했습니다.)
    2. Helm v3 이상 설치
    3. (선택 사항) PersistentVolume(영구 볼륨)을 위한 StorageClass(스토리지 클래스) 설정 (데이터 유실 방지를 위해 권장합니다)

    Step 1: Helm Repository 추가

    Prometheus와 Grafana를 포함하는 <code>kube-prometheus-stack은 Helm 차트로 제공됩니다. 먼저 Helm 레포지토리를 추가해주세요.

    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    helm repo update

    Step 2: Prometheus 스택 배포

    이제 kube-prometheus-stack을 배포할 차례입니다. 이 차트 안에는 Prometheus, Grafana, Alertmanager(알림 관리자), Kube-State-Metrics(쿠버네티스 상태 지표 수집기), Node Exporter(노드 지표 수집기) 등 쿠버네티스 모니터링에 필요한 모든 것이 한 번에 들어있어서 정말 편합니다. 저는 보통 monitoring 네임스페이스에 배포합니다.

    ⚠️ 중요: 프로덕션 환경에서는 values.yaml 파일을 통해 스토리지 클래스, 리소스 제한, 서비스 타입 등을 반드시 커스터마이징해야 합니다. 저는 홈랩이라 기본 설정으로 진행했지만, 여러분은 꼭 신경 써주세요!

    # values.yaml 파일 예시 (간단하게 스토리지 클래스만 지정)
    # my-prometheus-values.yaml
    
    prometheus:
      prometheusSpec:
        storageSpec:
          volumeClaimTemplate:
            spec:
              storageClassName: my-storage-class # 본인의 StorageClass 이름으로 변경
              resources:
                requests:
                  storage: 10Gi
    
    grafana:
      persistence:
        enabled: true
        storageClassName: my-storage-class # 본인의 StorageClass 이름으로 변경
        size: 5Gi
    

    이제 위 values.yaml 파일을 적용하여 배포합니다.

    helm install prometheus prometheus-community/kube-prometheus-stack \
      --namespace monitoring --create-namespace \
      -f my-prometheus-values.yaml # 커스터마이징한 values.yaml 파일 적용

    배포가 완료되면 kubectl get pods -n monitoring 명령어로 파드들이 잘 떠 있는지 확인해보세요. 모든 파드가 Running 상태라면 성공입니다! 🎉

    Step 3: Grafana 접속 및 초기 설정

    Grafana는 기본적으로 ClusterIP 타입의 서비스로 배포됩니다. 외부에서 접속하려면 Ingress(인그레스, 외부 트래픽 진입점)를 설정하거나, 간단하게 포트 포워딩(Port-forwarding)을 이용할 수 있어요. 저는 테스트를 위해 포트 포워딩을 자주 사용합니다.

    kubectl port-forward svc/prometheus-grafana 3000:80 -n monitoring

    이제 웹 브라우저에서 http://localhost:3000으로 접속해보세요. 초기 로그인 정보는 다음과 같습니다.

    • User (사용자): admin
    • Password (비밀번호): prom-operator (또는 kubectl get secret prometheus-grafana -n monitoring -o jsonpath='{.data.admin-password}' | base64 --decode 명령어로 확인)

    로그인 후에는 비밀번호 변경을 요청할 겁니다. 안전하게 변경해주세요!

    Grafana에서 Prometheus 데이터 소스를 추가하는 설정 화면입니다.

    📊 나만의 쿠버네티스 대시보드 만들기 & 활용하기

    Grafana에 접속했다면 이제 Prometheus 데이터를 시각화할 차례예요. kube-prometheus-stack 덕분에 Prometheus 데이터 소스는 이미 설정되어 있을 겁니다. 혹시 없다면, Configuration > Data Sources에서 Prometheus를 추가하고 URL을 http://prometheus-kube-prometheus-prometheus.monitoring.svc.cluster.local:9090 (네임스페이스와 서비스 이름에 따라 다를 수 있음)으로 설정하면 됩니다.

    기본 대시보드 활용하기

    kube-prometheus-stack은 기본적으로 여러 유용한 대시보드들을 Grafana에 자동으로 임포트해줍니다. 왼쪽 메뉴에서 Dashboards > Manage로 이동해보세요. 아마 Kubernetes / Compute Resources, Node Exporter Full 같은 대시보드들을 볼 수 있을 겁니다. 저도 처음엔 이 대시보드들만으로도 충분히 모니터링이 가능해서 정말 편하더라고요.

    Grafana Labs 공유 대시보드 임포트하기

    만약 더 다양한 대시보드를 원한다면, Grafana Labs 웹사이트(https://grafana.com/grafana/dashboards/)에서 다른 사람들이 공유한 대시보드를 임포트할 수 있습니다. 예를 들어, Node Exporter Full 대시보드(ID: 1860)나 Kubernetes Cluster Overview(ID: 12150) 같은 것들이 인기가 많죠.

    1. Grafana 좌측 메뉴에서 + > Import를 클릭합니다.
    2. Import via grafana.com dashboard 칸에 대시보드 ID (예: 1860)를 입력하고 Load를 클릭합니다.
    3. 대시보드 이름, 폴더를 설정하고, Prometheus 데이터 소스를 선택한 후 Import를 클릭합니다.

    짜잔! 멋진 대시보드가 눈앞에 펼쳐질 겁니다. 🤩

    나만의 대시보드 커스터마이징

    기존 대시보드를 활용하는 것도 좋지만, 특정 애플리케이션이나 서비스에 특화된 대시보드 구축은 필수입니다. 저는 주로 복제(Duplicate) 기능을 이용해서 기존 대시보드를 복사한 다음, 필요한 패널(Panel)을 추가하거나 수정하는 방식으로 커스터마이징합니다. PromQL(프로메테우스 쿼리 언어)을 조금만 익히면 원하는 지표를 자유자재로 뽑아낼 수 있거든요.

    Prometheus와 Grafana를 통해 구현된 쿠버네티스 클러스터 모니터링 대시보드 예시입니다.

    ⚠️ 삽질 대잔치! 트러블슈팅 경험담

    인프라 엔지니어의 삶은 삽질의 연속이죠. 저도 Prometheus & Grafana 구축 과정에서 몇 번의 삽질을 경험했어요. 여러분은 이런 문제들을 미리 알고 피하시길 바랍니다.

    1. PersistentVolumeClaim (PVC) Pending 문제

    증상: Prometheus나 Grafana 파드가 Pending 상태에서 벗어나지 못하고, PVC가 Pending으로 남아있을 때입니다.

    원인: 대부분 StorageClass가 없거나, 잘못 지정되었을 때 발생합니다. Prometheus는 데이터를 저장하기 위해 영구 스토리지를 써야 하는데, 이를 위한 StorageClass가 없으면 볼륨을 프로비저닝할 수 없거든요.

    해결: 클러스터에 NFS CSI Driver나 Longhorn 같은 동적 프로비저너를 설치하고, 해당 StorageClass를 values.yaml에 올바르게 지정해주세요. 저는 처음에 이 부분을 놓쳐서 한참 헤맸습니다. 🤦‍♂️

    2. 리소스 부족으로 인한 OOMKilled

    증상: Prometheus 파드가 자꾸 재시작되면서 OOMKilled(Out Of Memory Killed) 오류가 발생합니다.

    원인: Prometheus는 수집하는 지표의 양이 많아질수록 메모리 사용량이 늘어나요. 기본 설정된 리소스 제한(Resource Limits)이 클러스터 규모에 비해 너무 낮을 때 발생하는 거죠.

    해결: values.yaml에서 Prometheus 파드의 resources.requests와 resources.limits를 적절히 늘려주세요. 특히 memory 부분을 여유 있게 설정하는 게 중요합니다. 너무 많이 늘리면 다른 파드에 영향을 줄 수 있으니, 모니터링하면서 점진적으로 조정하는 것을 추천합니다.

    3. Prometheus가 타겟을 찾지 못하는 문제

    증상: Grafana 대시보드에서 데이터가 보이지 않거나, Prometheus UI의 Targets 페이지에서 특정 파드가 DOWN 상태로 표시될 때입니다.

    원인: Prometheus의 서비스 디스커버리 설정이 잘못되었거나, 파드에 올바른 레이블(Label)이 지정되지 않았을 때, 혹은 네트워크 정책(Network Policy) 등으로 인해 Prometheus가 파드의 익스포터에 접근하지 못할 때 발생합니다.

    해결:

    • 해당 파드에 Prometheus가 찾을 수 있는 annotations나 labels가 잘 붙어있는지 확인합니다. (예: prometheus.io/scrape: "true")
    • ServiceMonitor 또는 PodMonitor 리소스가 올바르게 정의되어 있는지 확인합니다.
    • 네트워크 정책이 Prometheus 파드에서 대상 파드로의 트래픽을 허용하는지 검토합니다.

    제가 직접 커스텀 애플리케이션을 모니터링할 때 이 문제로 고생 좀 했어요. 애플리케이션 파드에 어노테이션을 빼먹어서 그랬더라고요. ㅎㅎ

    ✅ 구축 결과 확인 및 다음 단계 제안

    이제 여러분의 쿠버네티스 클러스터는 Prometheus와 Grafana라는 강력한 모니터링 시스템을 갖추게 되었습니다. Grafana 대시보드를 통해 노드의 CPU/메모리 사용량, 파드의 상태, 네트워크 트래픽 등 다양한 지표들을 한눈에 볼 수 있을 겁니다. 문제가 발생하면 즉시 알 수 있고, 미리 예방할 수도 있게 되는 거죠. 정말 뿌듯하지 않나요? 🎉

    저도 처음 이 대시보드를 보면서 ‘드디어 됐다!’ 싶었던 기억이 생생하네요. 덕분에 제 홈랩 클러스터가 훨씬 더 안정적으로 운영되고 있습니다.

    다음 단계로 나아가기

    여기서 멈추지 마세요! 쿠버네티스 모니터링은 계속 발전해야 합니다. 몇 가지 다음 단계를 제안해봅니다.

    • Alertmanager(알림 관리자) 설정: Prometheus가 수집한 지표를 기반으로 알림(Alert)을 생성하고, 이를 Slack, 이메일, PagerDuty 등으로 전송하도록 설정해보세요. 저는 슬랙으로 알림을 받는데, 긴급 상황 발생 시 정말 유용합니다.
    • Custom Exporter 개발: 여러분의 특정 애플리케이션에서만 나오는 커스텀 지표를 수집하고 싶다면, 직접 익스포터를 개발해보는 것도 좋은 경험입니다. Python이나 Go 언어로 쉽게 만들 수 있어요.
    • 장기 지표 저장 (Long-term Storage): Prometheus는 기본적으로 로컬 스토리지를 써요. 장기간 지표를 보관하고 싶다면 Thanos(타노스)나 Cortex(코텍스) 같은 솔루션을 연동하여 스케일 아웃 및 장기 보관 기능을 추가할 수 있습니다.

    Prometheus 및 Grafana 기반 쿠버네티스 모니터링 시스템의 주요 이점과 활용 방안을 요약한 인포그래픽입니다.

    맺음말: 13년차 엔지니어의 조언

    쿠버네티스 모니터링은 클러스터 운영의 핵심이자, 인프라 엔지니어의 역량을 보여주는 중요한 부분입니다. 처음에는 어렵게 느껴질 수 있지만, 이렇게 직접 구축하고 활용해보면서 얻는 경험은 그 어떤 이론보다 값지다고 생각합니다. 저도 13년차 엔지니어이지만, 여전히 새로운 기술을 배우고 직접 손으로 만져보면서 배우는 것이 가장 즐겁고 효과적하더라고요.

    오늘 제가 공유한 내용이 여러분의 쿠버네티스 여정에 작은 도움이 되었기를 바랍니다. 혹시 진행 중에 궁금한 점이나 막히는 부분이 있다면 언제든지 댓글로 남겨주세요. 제가 아는 선에서 최대한 도와드리겠습니다. 다음에는 Alertmanager 설정이나 Custom Exporter 개발 경험에 대해서도 다뤄볼 예정이니 기대해주세요!

    다음 글에서 또 만나요! ✋