와탭랩스 블로그 오픈 이벤트 😃
자세히 보기
GPU
2025-08-07
쿠버네티스에서 NVIDIA GPU 모니터링하기 - (1) DCGM-Exporter 지표 수집
쿠버네티스에서 NVIDIA GPU 모니터링하기 (1): DCGM-Exporter 지표 수집

GPU 워크로드를 Kubernetes에서 실행할 때 가장 중요한 것 중 하나는 GPU 성능 모니터링입니다. 이번 글에서는 로컬 minikube 테스트 환경을 기반으로 실제 운영환경에서 NVIDIA GPU를 활성화하고, DCGM-Exporter를 통해 상세한 GPU 메트릭을 수집하는 전체 과정을 단계별로 알아보겠습니다.

gpu 성능 모니터링

최종 목표

  1. minikube 클러스터가 호스트의 NVIDIA GPU를 인식하고, 파드가 GPU를 요청(nvidia.com/gpu: 1)할 수 있도록 설정
  2. DCGM-Exporter를 설치하여 GPU의 온도, 사용률, 메모리 클럭 등 상세한 성능 지표를 Prometheus 형식으로 수집
  3. 커스텀 메트릭 추가를 통해 CUDA 버전, 드라이버 정보 등 운영에 필요한 메타데이터 수집

테스트 환경

이 가이드는 다음 환경에서 테스트되었습니다:

  • 호스트 OS: Ubuntu 24.04
  • Kubernetes: Minikube v1.36.0
  • 컨테이너 드라이버: Docker
  • GPU: NVIDIA GeForce RTX 4060
  • NVIDIA 드라이버: 560.94
  • 필수 도구: kubectl, helm
다른 환경에서도 동작합니다: 이 가이드는 NVIDIA GPU가 있는 대부분의 Linux 환경에서 동작합니다. GPU 모델이나 드라이버 버전이 달라도  원리는 동일합니다.


1단계: Minikube에 GPU 활성화하기

처음에는 복잡한 GPU Operator를 사용하려다 많은 시간을 허비했지만, minikube에는 간단한 방법이 내장되어 있습니다.

# 기존 클러스터가 있다면 완전히 삭제합니다
minikube delete

# --gpus all 플래그와 함께 새 클러스터를 시작합니다
minikube start --driver=docker --gpus=all


💡 --gpu=all 에 대하여

  • -gpus all 플래그는 다음 작업들을 자동으로 처리합니다:
  • minikube 내부 컨테이너 런타임(Docker)이 호스트 GPU 드라이버와 통신하도록 설정
  • 필수적인 nvidia-device-plugin 애드온 자동 활성화
  • GPU 리소스를 Kubernetes API에 등록

설정 확인하기

설치가 완료된 후, 다음 명령어로 노드의 할당 가능한 리소스 목록에 nvidia.com/gpu가 1 이상으로 표시되는지 확인합니다.

kubectl get nodes -o jsonpath='{.items[*].status.allocatable.nvidia\\.com/gpu}'
# 결과: 1 (또는 GPU 개수만큼 출력되어야 함)
# 더 자세한 노드 정보 확인
kubectl describe node minikube | grep -A 5 "Allocatable"


2단계: DCGM-Exporter 설치하기

DCGM-Exporter는 Helm Chart나 GPU Operator로도 설치할 수 있습니다. minikube 환경에서는 과도하게 복잡합니다. 직접 YAML로 설치하는 것이 더 간단하고 이해하기 쉽습니다.

기본 DCGM-Exporter 설치

# dcgm-exporter.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
  labels:
    app.kubernetes.io/name: dcgm-exporter
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: dcgm-exporter
  template:
    metadata:
      labels:
        app.kubernetes.io/name: dcgm-exporter
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9400"
        prometheus.io/path: "/metrics"
    spec:
      containers:
      - name: dcgm-exporter
        image: nvcr.io/nvidia/k8s/dcgm-exporter:4.2.3-4.1.3-ubuntu22.04
        ports:
        - name: metrics
          containerPort: 9400

        # GPU 접근을 위한 권한 설정
        securityContext:
          runAsUser: 0
          capabilities:
            add: ["SYS_ADMIN"]

        # Kubelet GPU 리소스 정보 접근
        volumeMounts:
        - name: pod-gpu-resources
          readOnly: true
          mountPath: /var/lib/kubelet/pod-resources

        # 리소스 제한 (선택사항)
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"

      volumes:
      - name: pod-gpu-resources
        hostPath:
          path: /var/lib/kubelet/pod-resources

---
# 메트릭 접근을 위한 서비스
apiVersion: v1
kind: Service
metadata:
  name: dcgm-exporter
  labels:
    app.kubernetes.io/name: dcgm-exporter
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "9400"
spec:
  type: ClusterIP
  ports:
  - name: metrics
    port: 9400
    targetPort: 9400
  selector:
    app.kubernetes.io/name: dcgm-exporter


배포 및 확인

# 클러스터에 적용
kubectl apply -f dcgm-exporter.yaml

# 파드 상태 확인
kubectl get pods -l app.kubernetes.io/name=dcgm-exporter -w

# 로그 확인 (문제 발생 시)
kubectl logs -l app.kubernetes.io/name=dcgm-exporter


3단계: 메트릭 확인하기

메트릭 엔드포인트 접근

# 포트 포워딩으로 로컬에서 접근
kubectl port-forward svc/dcgm-exporter 8080:9400


메트릭 데이터 확인

# curl로 메트릭 확인
curl <http://127.0.0.1:8080/metrics>

# 특정 메트릭만 필터링
curl -s <http://127.0.0.1:8080/metrics> | grep -E "(GPU_TEMP|GPU_UTIL|POWER_USAGE)"


예상 출력 결과

# HELP DCGM_FI_DEV_GPU_TEMP GPU temperature (in C).
# TYPE DCGM_FI_DEV_GPU_TEMP gauge
DCGM_FI_DEV_GPU_TEMP{device="nvidia0",modelName="NVIDIA GeForce RTX 4060",UUID="GPU-12345..."} 45

# HELP DCGM_FI_DEV_GPU_UTIL GPU utilization (in %).
# TYPE DCGM_FI_DEV_GPU_UTIL gauge
DCGM_FI_DEV_GPU_UTIL{device="nvidia0",modelName="NVIDIA GeForce RTX 4060",UUID="GPU-12345..."} 20

# HELP DCGM_FI_DEV_POWER_USAGE Power draw (in W).
# TYPE DCGM_FI_DEV_POWER_USAGE gauge
DCGM_FI_DEV_POWER_USAGE{device="nvidia0",modelName="NVIDIA GeForce RTX 4060",UUID="GPU-12345..."} 85


📈 Prometheus 메트릭 형식 이해하기

  • HELP: 메트릭에 대한 설명 (예: GPU temperature)
  • TYPE: 메트릭 타입 (counter, gauge, histogram 등)
  • 메트릭 라벨: 시계열 데이터를 구분하는 키-값 쌍
  • : 실제 측정값 (기본 30초 간격으로 업데이트)

4단계: 커스텀 메트릭 추가하기


왜 커스텀 메트릭이 필요할까?

기본 메트릭(전체 목록 확인) 외에도 실제 운영환경에서는 상황에 따라 필요한 지표가 달라 질 수 있습니다. 예로들어 아래와 같이 GPU 장치의 메타데이터, 네트워크 부하에 대한 모니터링이 필요한 상황이 있습니다. 이경우 기본 메트릭 외에 추가적인 지표 수집을 해야합니다.

  • CUDA 버전: 애플리케이션 호환성 확인
  • NVIDIA 드라이버 버전: 드라이버 업데이트 관리
  • PCIe 정보: GPU 네트워크 성능 모니터링


ConfigMap을 통한 메트릭 구성

ConfigMap을 통한 메트릭 구성


Step 1: 확장된 메트릭 ConfigMap 생성

# dcgm-exporter-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: dcgm-exporter-metrics
  labels:
    app: dcgm-exporter
    component: metrics-config
data:
  custom-metrics.csv: |
    # 기본 성능 메트릭
    DCGM_FI_DEV_SM_CLOCK,gauge,SM clock frequency (in MHz).
    DCGM_FI_DEV_MEM_CLOCK,gauge,Memory clock frequency (in MHz).
    DCGM_FI_DEV_MEMORY_TEMP,gauge,Memory temperature (in C).
    DCGM_FI_DEV_GPU_TEMP,gauge,GPU temperature (in C).
    DCGM_FI_DEV_GPU_UTIL,gauge,GPU utilization (in %).
    DCGM_FI_DEV_MEM_COPY_UTIL,gauge,Memory utilization (in %).
    DCGM_FI_DEV_ENC_UTIL,gauge,Encoder utilization (in %).
    DCGM_FI_DEV_DEC_UTIL,gauge,Decoder utilization (in %).

    # 메모리 및 전력 메트릭
    DCGM_FI_DEV_FB_FREE,gauge,Framebuffer memory free (in MiB).
    DCGM_FI_DEV_FB_USED,gauge,Framebuffer memory used (in MiB).
    DCGM_FI_DEV_POWER_USAGE,gauge,Power draw (in W).

    # 오류 및 상태 메트릭
    DCGM_FI_DEV_XID_ERRORS,gauge,Value of the last XID error encountered.

    # 디바이스 메타데이터(새로 추가)
    DCGM_FI_DRIVER_VERSION,gauge,Version of the installed NVIDIA driver.
    DCGM_FI_CUDA_DRIVER_VERSION,gauge,CUDA driver version.

    # PCIe 네트워크 메트릭 (새로 추가)
    DCGM_FI_PROF_PCIE_TX_BYTES,gauge,PCIe transmit bytes.
    DCGM_FI_PROF_PCIE_RX_BYTES,gauge,PCIe receive bytes.


Step 2: ConfigMap 배포

kubectl apply -f dcgm-exporter-config.yaml


Step 3: DaemonSet 업데이트

# dcgm-exporter-enhanced.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: dcgm-exporter
  labels:
    app.kubernetes.io/name: dcgm-exporter
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: dcgm-exporter
  template:
    metadata:
      labels:
        app.kubernetes.io/name: dcgm-exporter
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9400"
    spec:
      nodeSelector:
        kubernetes.io/hostname: minikube

      # 볼륨 정의: ConfigMap과 호스트 경로
      volumes:
      - name: pod-gpu-resources
        hostPath:
          path: /var/lib/kubelet/pod-resources
      - name: metrics-config-volume
        configMap:
          name: dcgm-exporter-metrics
          defaultMode: 0644

      containers:
      - name: dcgm-exporter
        image: nvcr.io/nvidia/k8s/dcgm-exporter:4.2.3-4.1.3-ubuntu22.04

        # 커스텀 메트릭 파일 사용
        args:
        - "-f"
        - "/etc/dcgm-exporter/custom-metrics.csv"
        - "-c"
        - "3000"  # 수집 간격 (ms)

        ports:
        - name: metrics
          containerPort: 9400

        securityContext:
          runAsUser: 0
          capabilities:
            add: ["SYS_ADMIN"]

        # 볼륨 마운트
        volumeMounts:
        - name: pod-gpu-resources
          mountPath: /var/lib/kubelet/pod-resources
          readOnly: true
        - name: metrics-config-volume
          mountPath: /etc/dcgm-exporter/custom-metrics.csv
          subPath: custom-metrics.csv  # 파일로 마운트
          readOnly: true

        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"

---
apiVersion: v1
kind: Service
metadata:
  name: dcgm-exporter
  labels:
    app.kubernetes.io/name: dcgm-exporter
spec:
  type: ClusterIP
  ports:
  - name: metrics
    port: 9400
    targetPort: 9400
  selector:
    app.kubernetes.io/name: dcgm-exporter


Step 4: 업데이트 적용

# 기존 DaemonSet 삭제 (ConfigMap 변경사항 적용을 위해)
kubectl delete daemonset dcgm-exporter --ignore-not-found

# 새로운 구성 적용
kubectl apply -f dcgm-exporter-enhanced.yaml

# 배포 상태 확인
kubectl get pods -l app.kubernetes.io/name=dcgm-exporter -w


5단계: 확장된 메트릭 확인

새로운 메트릭 테스트

# 포트 포워딩
kubectl port-forward svc/dcgm-exporter 8080:9400

# CUDA 및 드라이버 버전 메트릭 확인
curl -s <http://127.0.0.1:8080/metrics> | grep -E "(DRIVER_VERSION|CUDA_DRIVER_VERSION)"


예상 출력

# HELP DCGM_FI_DRIVER_VERSION Version of the installed NVIDIA driver.
# TYPE DCGM_FI_DRIVER_VERSION gauge
DCGM_FI_DRIVER_VERSION{gpu="0",UUID="GPU-12345..."} 525.60

# HELP DCGM_FI_CUDA_DRIVER_VERSION CUDA driver version.
# TYPE DCGM_FI_CUDA_DRIVER_VERSION gauge
DCGM_FI_CUDA_DRIVER_VERSION{gpu="0",UUID="GPU-12345..."} 12100


다음 단계: Prometheus & Grafana 연동

이제 GPU 메트릭 수집이 완료되었으니, 다음 포스팅에서는 다음의 내용에 대해 다뤄보겠습니다.

  • Prometheus 설치 및 DCGM-Exporter 연동
  • Grafana 대시보드 구성
  • GPU 성능 알림 설정
  • 실시간 모니터링 대시보드 구축

참고 자료

와탭 모니터링을 무료로 체험해보세요!