GPU 워크로드를 Kubernetes에서 실행할 때 가장 중요한 것 중 하나는 GPU 성능 모니터링입니다. 이번 글에서는 로컬 minikube 테스트 환경을 기반으로 실제 운영환경에서 NVIDIA GPU를 활성화하고, DCGM-Exporter를 통해 상세한 GPU 메트릭을 수집하는 전체 과정을 단계별로 알아보겠습니다.
이 가이드는 다음 환경에서 테스트되었습니다:
다른 환경에서도 동작합니다: 이 가이드는 NVIDIA GPU가 있는 대부분의 Linux 환경에서 동작합니다. GPU 모델이나 드라이버 버전이 달라도 원리는 동일합니다.
처음에는 복잡한 GPU Operator를 사용하려다 많은 시간을 허비했지만, minikube에는 간단한 방법이 내장되어 있습니다.
# 기존 클러스터가 있다면 완전히 삭제합니다
minikube delete
# --gpus all 플래그와 함께 새 클러스터를 시작합니다
minikube start --driver=docker --gpus=all
💡 --gpu=all 에 대하여
-gpus all
플래그는 다음 작업들을 자동으로 처리합니다:nvidia-device-plugin
애드온 자동 활성화설정 확인하기
설치가 완료된 후, 다음 명령어로 노드의 할당 가능한 리소스 목록에 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"
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
메트릭 엔드포인트 접근
# 포트 포워딩으로 로컬에서 접근
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 메트릭 형식 이해하기
왜 커스텀 메트릭이 필요할까?
기본 메트릭(전체 목록 확인) 외에도 실제 운영환경에서는 상황에 따라 필요한 지표가 달라 질 수 있습니다. 예로들어 아래와 같이 GPU 장치의 메타데이터, 네트워크 부하에 대한 모니터링이 필요한 상황이 있습니다. 이경우 기본 메트릭 외에 추가적인 지표 수집을 해야합니다.
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
새로운 메트릭 테스트
# 포트 포워딩
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
이제 GPU 메트릭 수집이 완료되었으니, 다음 포스팅에서는 다음의 내용에 대해 다뤄보겠습니다.