DATA GROUND 로고DATA GROUND
DevOps

[Prometheus] node-exporter에서 노드별 메트릭 수집하기

S.H. Yoo
마지막 업데이트: 2024-04-15

Kubernetes 클러스터에서 node-exporter를 DaemonSet으로 구성하고 Prometheus 설정을 통해 노드별 메트릭을 정확히 구분하는 방법을 정리합니다.

작성일: 2024-04-15작성자: S.H. Yoo마지막 업데이트: 2024-04-15

목적

여러 개의 노드로 구성된 Kubernetes 클러스터에서는
노드별 자원 모니터링이 필수적입니다.

이를 위해 워커 노드 구성 시
추가로 metric 서버(node-exporter) 를 설치해야 하며,
각 노드의 CPU, 메모리, 디스크 등의 정보를 개별적으로 수집할 수 있어야 합니다.

하지만 단순히 Service 하나로 묶어 배포할 경우
노드별 구분이 되지 않는 문제가 발생합니다.


node-exporter 구성 방식

DaemonSet을 사용하는 이유

node-exporter는
각 노드에서 반드시 하나씩 실행되어야 하는 에이전트입니다.

따라서 Kubernetes에서는
노드 수에 따라 자동으로 Pod가 생성되는
DaemonSet 방식이 가장 적합합니다.


node-exporter DaemonSet 예시

아래는 CPU, 메모리 등의 노드 자원 정보를 수집하는
node-exporter 구성 예시입니다.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9100
---
apiVersion: v1
kind: Service
metadata:
  name: node-exporter-service
  namespace: monitoring
spec:
  type: ClusterIP
  selector:
    app: node-exporter
  ports:
    - protocol: TCP
      port: 9100
      targetPort: 9100

이렇게 구성하면
node-exporter는 DaemonSet으로 모든 노드에 배포되며,
Service를 통해 하나의 엔드포인트로 접근할 수 있습니다.


문제점: 노드 구분 불가

Service 하나로 묶어 배포할 경우
Prometheus에서는 다음과 같이 metric을 수집하게 됩니다.

node_memory_AnonHugePages_bytes{instance="localhost:9100",job="node"}

이 경우:

  • instance 값이 모두 동일
  • 실제로는 여러 노드에서 수집된 메트릭임에도
  • 어떤 노드의 값인지 구분 불가

즉, 모든 node-exporter Pod가
하나의 서버처럼 인식되는 문제가 발생합니다.


특정 노드 값 받는 방법

이 문제를 해결하려면
Prometheus가 Pod 단위로 node-exporter를 직접 탐색하도록 설정해야 합니다.

이를 위해 kubernetes_sd_configs를 사용합니다.


기존 prometheus.yml 설정

global:
  scrape_interval: 10s

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: ["localhost:9090"]

  - job_name: "node"
    static_configs:
      - targets: ["node-export-service.monitoring.svc:8080"]

위 방식은
Service 단위 접근이기 때문에
노드 구분이 불가능합니다.


kubernetes_sd_configs 적용

핵심 변경 포인트

  • Service 기반 수집 → Pod 기반 수집
  • 특정 namespace + 특정 label을 가진 Pod만 선택
  • instance 라벨을 노드 이름으로 치환

변경된 prometheus.yml 설정

global:
  scrape_interval: 10s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
            - monitoring

    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app]
        action: keep
        regex: node-exporter

      - source_labels: [__meta_kubernetes_pod_node_name]
        target_label: instance

설정 설명

kubernetes_sd_configs

  • Kubernetes API를 통해 Pod 정보를 자동 탐색
  • role: pod → Pod 단위 수집
  • namespaces → monitoring 네임스페이스만 대상

relabel_configs

  • __meta_kubernetes_pod_label_app

    • Pod의 app label 값이 node-exporter인 Pod만 수집
  • __meta_kubernetes_pod_node_name

    • Pod가 실행 중인 노드 이름을 가져옴
    • 해당 값을 instance 라벨로 설정

이렇게 설정하면
Prometheus에서 각 메트릭이 노드 이름 기준으로 구분됩니다.


마무리하며

node-exporter를 DaemonSet으로 구성하는 것만으로는
노드별 메트릭 구분이 완벽하지 않습니다.

Prometheus 설정에서
Pod 단위 수집 + relabel 설정을 함께 적용해야
실제 운영에 필요한 노드별 모니터링이 가능합니다.

이 구조는:

  • 대규모 클러스터
  • 자동 스케일링 환경
  • 실무 모니터링 시스템

에서 거의 표준적으로 사용되는 패턴입니다.

마지막 업데이트: 2024-04-15

당신이 관심있을 만한 글