1. 목적
GPU 사용률 기반 Pod AutoScaling을 구현하기 위해 메트릭 수집 및 모니터링 도구로 Prometheus와 Grafana를 선택했다.
단, 특정 GPU 서비스만 사용하기 위해서 namespace와 nodepool 설정이 추가적으로 들어간다.
2. 구성
GPU 메트릭을 수집하기 위한 Prometheus를 Kubernetes 환경에 구성하는 방식은 크게 2가지가 있다.
- kube-prometheus-stack
- Standalone Prometheus (Operator 미사용, 직접 prometheus.yml 관리)
수동 설정이 필요한 Standalone과 달리, kube-prometheus-stack은 지표 수집을 자동화할 수 있어서 kube-prometheus-stack 방식을 선택했다.
# kube-prometheus-stack 워크플로우
[GPU]
↓
[NVIDIA Driver + DCGM] # 메트릭 추출
↓
dcgm-exporter (DaemonSet) # 메트릭을 http 엔드포인트로 노출
↓
Service (ClusterIP) # 개별 exporter Pod에 대한 고정 접근 지점(IP) 제공
↓
ServiceMonitor (CRD) # Prometheus에 수집할 대상을 지정
↓
Prometheus (Operator 관리) # 메트릭 수집, 저장, PromQL 조회
↓
Prometheus Adapter # 데이터를 K8s Custom Metrics API 규격으로 변환
↓
Grafana / Alertmanager / HPA # 시각화, 알림, 오토스케일에 활용
3. 기본 동작 구축
3-1. Helm repository 구성
NVIDIA 및 Prometheus 차트를 배포한다.
- nvidia: GPU 메트릭 추출 도구인 DCGM Exporter 제공
- prometheus-community: 메트릭 수집(Prometheus), 변환(Adapter) 도구 제공
helm repo add nvidia https://nvidia.github.io/gpu-operator
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
3-2. NVIDIA DCGM Exporter 설치
노드에서 GPU 사용량 지표(DCGM_FI_DEV_GPU_UTIL)를 추출한다.
특정 namespace만 사용하는 nodepool에 대한 메트릭만 수집하기 위해서 nodeSelector 에 따로 명시를 했다.
# gpu-operator.yaml
driver:
enabled: false
toolkit:
enabled: false
devicePlugin:
enabled: false
gfd:
enabled: false
dcgmExporter:
serviceMonitor:
enabled: true
additionalLabels:
release: <서비스명>-prometheus
dcgm:
nodeSelector:
nodepool: <노드풀명>
operator:
nodeSelector:
nodepool: <노드풀명>
validator:
nodeSelector:
nodepool: <노드풀명>
node-feature-discovery:
master:
nodeSelector:
nodepool: <노드풀명>
gc:
nodeSelector:
nodepool: <노드풀명>
worker:
nodeSelector:
nodepool: <노드풀명>
helm upgrade --install <서비스명>-dcgm nvidia/gpu-operator -n <네임스페이스> -f gpu-operator.yaml
3-3. Prometheus Stack 설치
수집된 데이터를 저장하고 쿼리할 수 있는 환경을 구축한다.
# prometheus-stack.yaml
grafana:
enabled: true
alertmanager:
enabled: false
prometheus:
prometheusSpec:
serviceMonitorSelectorNilUsesHelmValues: false
nodeSelector:
nodepool: <노드풀명>
prometheusOperator:
nodeSelector:
nodepool: <노드풀명>
kube-state-metrics:
nodeSelector:
nodepool: <노드풀명>
prometheus-node-exporter:
nodeSelector:
nodepool: <노드풀명>
prometheusOperator:
admissionWebhooks:
patch:
nodeSelector:
nodepool: <노드풀명>
- grafana.enabled: 그라파나를 사용하는 경우에는 true, 사용하지 않는 경우에는 false.
helm upgrade --install <서비스명>-prometheus prometheus-community/kube-prometheus-stack -n <서비스 네임스페이스> -f prometheus-stack.yaml
3-4. Prometheus Adapter 설정 및 설치
Prometheus Adapter 설정 파일을 생성(prometheus-adapter.yaml)한다.
prometheus:
url: http://<prometheus-service-name>.<namespace>.svc.cluster.local
port: 9090
nodeSelector:
nodepool: <서비스 노드풀명>
rules:
custom:
- seriesQuery: 'DCGM_FI_DEV_GPU_UTIL{exported_pod!=""}'
resources:
overrides:
exported_namespace: {resource: "namespace"}
exported_pod: {resource: "pod"}
name:
matches: "DCGM_FI_DEV_GPU_UTIL"
as: "gpu_utilization"
metricsQuery: 'sum(<<.Series>>{<<.LabelMatchers>>}) by (<<.GroupBy>>)'
- url: <prometheus-service-name>는 Helm 배포 시 생성된 Prometheus Service 이름 참고(예: <release-name>-kube-prom-prometheus)
- seriesQuery: 'exported_pod' 라벨이 있는 DCGM 메트릭만 필터링하여 데이터 처리 효율 증가
- resources.overrides: Prometheus의 라벨(exported_pod)을 K8s의 리소스(pod)로 매핑하여 HPA가 타겟을 인식하게 함
- metricsQuery: sum(...) by (pod)를 통해 포드별 사용률을 합산하여 정확한 개별 부하 측정
Prometheus Adapter 를 설치해서, Prometheus에 저장된 지표를 Kubernetes API 서버가 이해할 수 있는 custom.metrics.k8s.io 형식으로 변환해 제공한다.
helm upgrade --install prometheus-adapter prometheus-community/prometheus-adapter -n <서비스 네임스페이스> -f prometheus-adapter.yaml
3-5. HPA 리소스 생성
HPA 파일 생성(hpa.yaml)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: hpa-<서비스명>
namespace: <서비스 네임스페이스>
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: <서비스 deployment명>
minReplicas: 1
maxReplicas: 2
metrics:
- type: Pods
pods:
metric:
name: gpu_utilization
target:
type: AverageValue
averageValue: "60"
- type: Pods / AverageValue: GPU는 K8s 표준 자원이 아니므로 %비율(Utilization) 대신 Prometheus가 주는 0~100 사이의 '값' 자체를 기준으로 삼음
- averageValue: "60": GPU 평균 사용률이 60% 이상인 경우 Scale-out.
3-6. 검증
Custom Metrics API 지표를 확인하여 Prometheus Adapter가 데이터를 정상 변환 중인지 확인한다.
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/<서비스 네임스페이스>/pods/*/gpu_utilization" | jq
위 명령 실행 시 숫자가 포함된 JSON 결과가 출력되어야 한다.

HPA 상태를 확인한다.
kubectl get hpa -n <서비스 네임스페이스>
