
1. 왜 GPU 노드에는 기본 HPA를 사용할 수 없는가?
Kubernetes의 기본 Horizontal Pod Autoscaler (HPA)는 Metrics Server로부터 CPU와 메모리 사용량만 수집합니다. 하지만 딥러닝 추론(Inference)이나 학습(Training) 워크로드는 CPU가 한가하더라도 GPU 연산 자원이 고갈되어 서비스가 지연되는 경우가 빈번합니다. 이러한 문제를 해결하기 위해서는 NVIDIA DCGM(Data Center GPU Manager)과 Prometheus Adapter를 연동하여 Custom Metrics를 생성하고, 이를 HPA가 인식하도록 설정해야 합니다. 본 글에서는 Python 기반 클라이언트가 이 자원을 어떻게 소비하는지 이해하고, 인프라 단에서 이를 해결하는 전략을 다룹니다.
2. 기본 메트릭 vs 커스텀 GPU 메트릭의 차이 분석
오토스케일링 결정의 기준이 되는 메트릭의 종류와 그 차이점을 분석합니다.
| 구분 | 기본 HPA (Metrics Server) | 커스텀 HPA (Prometheus + DCGM) |
|---|---|---|
| 수집 데이터 | CPU Core, RAM Usage | GPU Utilization, GPU Memory, Temperature |
| 확장 정확도 | 낮음 (GPU 병목 감지 불가) | 매우 높음 (실제 연산 부하 반영) |
| 설정 복잡도 | 낮음 (기본 내장) | 높음 (Exporter 및 Adapter 설치 필요) |
| 반응 속도 | 중간 | 빠름 (Prometheus 스크래핑 주기 조절 가능) |
| 해결 과제 | 불필요한 리소스 낭비 발생 | 정교한 PromQL 쿼리 작성 능력 필요 |
3. 실무 적용을 위한 7가지 Sample Example (설정 및 파이썬 코드)
아래 예제들은 Prometheus Adapter 설정부터 HPA 정의, 그리고 GPU 부하를 테스트하는 Python 스크립트까지 실무 전체 파이프라인을 포함합니다.
Example 1: NVIDIA DCGM Exporter 설정을 위한 Prometheus ServiceMonitor
GPU 메트릭을 Prometheus가 수집할 수 있도록 경로를 지정하는 YAML 설정입니다.
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: dcgm-exporter
labels:
app: nvidia-dcgm-exporter
spec:
selector:
matchLabels:
app: nvidia-dcgm-exporter
endpoints:
- port: metrics
interval: 10s # 메트릭 수집 주기
Example 2: Prometheus Adapter를 이용한 커스텀 메트릭 규칙 정의
수집된 DCGM_FI_DEV_GPU_UTIL 데이터를 HPA가 읽을 수 있는 gpu_usage_avg 메트릭으로 매핑하는 해결 방법입니다.
rules:
- seriesQuery: '{__name__=~"DCGM_FI_DEV_GPU_UTIL",container!="",pod!=""}'
resources:
overrides:
namespace: {resource: "namespace"}
pod: {resource: "pod"}
name:
matches: "DCGM_FI_DEV_GPU_UTIL"
as: "gpu_utilization_custom"
metricsQuery: 'sum(<<.Series>>) by (<<.GroupBy>>)'
Example 3: GPU 사용률 기반 HPA 정의 (v2 API)
GPU 사용률이 평균 60%를 초과할 때 파드를 자동으로 확장하는 설정입니다.
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: gpu-serving-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: python-gpu-app
minReplicas: 1
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: gpu_utilization_custom
target:
type: AverageValue
averageValue: "60"
Example 4: Python PyCUDA를 이용한 GPU 부하 시뮬레이션 스크립트
HPA가 정상 작동하는지 확인하기 위해 인위적으로 GPU 연산 부하를 발생시키는 테스트 코드입니다.
import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
from pycuda.compiler import SourceModule
# 대량의 행렬 연산을 통해 GPU 사용률 유도
mod = SourceModule("""
__global__ void heavy_comp(float *dest, float *a, float *b)
{
const int i = threadIdx.x + blockIdx.x * blockDim.x;
for(int j=0; j<10000; j++) {
dest[i] = a[i] * b[i] + j;
}
}
""")
heavy_comp = mod.get_function("heavy_comp")
# 실무 적용 시 데이터 크기를 조절하여 부하 테스트 수행
a = np.random.randn(1024).astype(np.float32)
b = np.random.randn(1024).astype(np.float32)
dest = np.zeros_like(a)
while True:
heavy_comp(drv.Out(dest), drv.In(a), drv.In(b), block=(1024,1,1), grid=(1,1))
Example 5: GPU 메모리 점유율 기반 임계값 설정 해결 방법
연산량은 적지만 모델 크기 때문에 메모리가 부족한 경우를 대비한 메모리 기준 HPA 메트릭 예시입니다.
# metricsQuery 부분 수정
metricsQuery: 'avg(DCGM_FI_DEV_FB_USED) by (<<.GroupBy>>)'
# HPA 설정 시 averageValue: "8000Mi" (8GB 사용 시 확장)
Example 6: Python 클라이언트에서 커스텀 메트릭 호출 및 모니터링
애플리케이션 내부에서 직접 Prometheus 메트릭 서버에 현재 GPU 상태를 질의하는 코드입니다.
import requests
def get_gpu_metric(pod_name):
query = f'gpu_utilization_custom{{pod="{pod_name}"}}'
response = requests.get(f"http://prometheus-k8s:9090/api/v1/query?query={query}")
data = response.json()
return data['data']['result'][0]['value'][1]
print(f"Current Pod GPU Load: {get_gpu_metric('my-python-pod-xyz')}%")
Example 7: 다중 메트릭 결합(CPU + GPU) 전략
CPU 부하와 GPU 부하 중 하나라도 임계치를 넘으면 확장하도록 구성하여 안정성을 극대화합니다.
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Pods
pods:
metric:
name: gpu_utilization_custom
target:
type: AverageValue
averageValue: "50"
4. 전문적 지식: GPU HPA 튜닝 시 주의사항 3가지
- Scaling Dampening (진정기): GPU 워크로드는 부하 변동성이 큽니다.
behavior설정을 통해 너무 빈번한 확장/축소(Thrashing)가 발생하지 않도록stabilizationWindowSeconds를 충분히(예: 300초) 확보하세요. - 메트릭 지연(Metric Latency): Prometheus 수집 주기 + Adapter 변환 주기 + HPA 체크 주기가 합쳐져 약 1~2분의 지연이 발생할 수 있음을 인지하고 임계치를 보수적으로 잡아야 합니다.
- Fractional GPU (MIG): NVIDIA Multi-Instance GPU를 사용한다면 인스턴스별 메트릭 ID가 달라지므로 쿼리에서
UUID대신device식별자를 정확히 그룹화해야 합니다.
5. 결론
GPU 노드에 HPA를 적용하는 것은 단순한 인프라 설정을 넘어, AI 서비스의 가용성을 결정짓는 핵심 해결 방법입니다. Python 개발자는 자신의 코드가 GPU 메모리와 연산 유닛을 어떻게 사용하는지 이해하고, 이를 Prometheus 커스텀 메트릭으로 시각화하여 데이터에 기반한 오토스케일링 전략을 수립해야 합니다.
'Artificial Intelligence > 60. Python' 카테고리의 다른 글
| [PYTHON] A/B Testing vs Multi-Armed Bandit: 모델 업데이트 시 2가지 트래픽 전환 전략 해결 방법 (0) | 2026.04.20 |
|---|---|
| [PYTHON] Serverless AI : AWS Lambda와 GCP Functions의 5가지 추론 레이턴시 해결 방법 (0) | 2026.04.20 |
| [PYTHON] MLOps의 핵심, DVC로 데이터와 모델 버전을 완벽하게 관리하는 7가지 방법 (0) | 2026.04.20 |
| [PYTHON] ONNX 변환 시 프레임워크 간 오퍼레이터 호환성 문제 해결을 위한 7가지 방법 (0) | 2026.04.20 |
| [PYTHON] TensorRT FP16 양자화 오차를 해결하는 3가지 Calibration 데이터 선정 방법 (0) | 2026.04.20 |