- Published on
NVIDIA GPU Operator 완전 정복 — 설치·배포부터 MIG 분할 설정까지
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 들어가며 — GPU 노드 셋업의 지옥에서 벗어나기
- GPU Operator는 무엇을 배포하는가
- 설치 — Helm 차트 하나로
- 검증 — 파드에서 GPU가 보이는가
- MIG — 한 장의 GPU를 하드웨어 수준에서 쪼개기
- MIG 전략 — single vs mixed
- MIG 적용 — 노드 라벨 하나로
- 커스텀 프로필 — 한 장 안에서 크기 섞기
- 운영 주의사항 — 미리 알면 장애가 아닌 것들
- 마치며
- 참고 자료
들어가며 — GPU 노드 셋업의 지옥에서 벗어나기
쿠버네티스 클러스터에 GPU 노드를 수동으로 붙여본 사람은 압니다. NVIDIA 드라이버를 커널 버전에 맞춰 설치하고, container toolkit을 깔고, 런타임 설정을 바꾸고, 디바이스 플러그인을 배포하고, 모니터링 익스포터를 붙이고 — 이 다섯 층의 버전 궁합이 하나라도 어긋나면 파드는 GPU를 못 봅니다. 노드가 10대면 이 작업이 10번, 커널 업데이트가 오면 또 처음부터입니다.
NVIDIA GPU Operator는 이 전체 스택을 쿠버네티스 오퍼레이터 패턴으로 자동화합니다. 관리자는 Helm 차트 하나를 설치하고, 원하는 상태를 선언하면, 오퍼레이터가 각 노드에 필요한 컴포넌트를 컨테이너로 배포하고 계속 조정(reconcile)합니다. 이 글은 설치부터 검증, 그리고 A100/H100급 GPU의 킬러 기능인 MIG(Multi-Instance GPU) 분할 설정까지를 실제 명령어와 함께 다룹니다. 쿠버네티스 기초가 필요하다면 이 사이트의 쿠버네티스 놀이터에서 먼저 감을 잡고 오셔도 좋습니다.
GPU Operator는 무엇을 배포하는가
오퍼레이터를 설치하면 gpu-operator 네임스페이스에 다음 오퍼랜드(operand)들이 데몬셋 형태로 깔립니다. 각각이 수동 셋업 시대에 손으로 하던 일 하나씩에 대응합니다.
- NVIDIA Driver (컨테이너화) — 호스트에 드라이버를 직접 깔지 않고 컨테이너로 커널 모듈을 로드합니다. 커널 업데이트 대응이 극적으로 쉬워집니다.
- NVIDIA Container Toolkit — 컨테이너 런타임이 GPU를 파드에 노출할 수 있게 합니다.
- Device Plugin —
nvidia.com/gpu리소스를 쿠버네티스 스케줄러에 광고합니다. - GPU Feature Discovery(GFD) — GPU 모델·메모리·MIG 상태를 노드 라벨로 게시해 노드 셀렉터로 쓸 수 있게 합니다.
- DCGM Exporter — GPU 사용률·메모리·온도·전력을 프로메테우스 메트릭으로 내보냅니다.
- MIG Manager — 이 글의 주인공. 노드 라벨을 감시하다가 MIG 파티션을 실제로 적용합니다.
- Validator — 각 단계가 정상 동작하는지 검증하는 잡을 돌립니다.
설치 — Helm 차트 하나로
전제 조건은 세 가지입니다: NVIDIA GPU가 달린 노드, 지원되는 컨테이너 런타임(containerd 등), 그리고 Node Feature Discovery(오퍼레이터가 기본으로 함께 설치).
# 1) NVIDIA Helm 저장소 등록
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
# 2) 설치 (버전은 문서에서 최신 확인 — 이 글 기준 v26.3.3)
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.3
환경에 따라 자주 쓰는 변형 두 가지:
# 노드에 드라이버가 이미 설치되어 있다면 (DGX OS, 직접 설치 등)
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.3 \
--set driver.enabled=false
# container toolkit까지 이미 있다면
# --set toolkit.enabled=false 를 추가
설치 상태 확인:
kubectl get pods -n gpu-operator
# driver-daemonset, container-toolkit, device-plugin, dcgm-exporter,
# gpu-feature-discovery, operator-validator 가 모두 Running/Completed 이면 정상
검증 — 파드에서 GPU가 보이는가
가장 확실한 검증은 GPU를 요청하는 테스트 파드입니다.
apiVersion: v1
kind: Pod
metadata:
name: gpu-smoke-test
spec:
restartPolicy: Never
containers:
- name: nvidia-smi
image: nvidia/cuda:12.4.1-base-ubuntu22.04
command: ['nvidia-smi']
resources:
limits:
nvidia.com/gpu: 1
kubectl apply -f gpu-smoke-test.yaml
kubectl logs gpu-smoke-test
# nvidia-smi 출력에 GPU 모델이 보이면 성공
GFD가 붙여준 노드 라벨도 확인해 두면 노드 셀렉터를 짤 때 유용합니다.
kubectl get node <노드이름> -o jsonpath='{.metadata.labels}' | jq . | grep nvidia
# nvidia.com/gpu.product, nvidia.com/gpu.memory, nvidia.com/gpu.count 등
MIG — 한 장의 GPU를 하드웨어 수준에서 쪼개기
A100/H100 같은 데이터센터 GPU는 한 장이 너무 큽니다. 작은 추론 워크로드 하나가 80GB GPU를 통째로 점유하면 나머지 용량은 놀게 됩니다. **MIG(Multi-Instance GPU)**는 Ampere 세대부터 지원되는 기능으로, GPU 한 장을 최대 7개의 하드웨어 격리된 인스턴스로 분할합니다.
핵심은 "하드웨어 격리"입니다. 각 MIG 인스턴스는 자기 몫의 SM(연산 유닛), L2 캐시, 메모리 대역폭을 물리적으로 배정받습니다. 시분할(time-slicing)과의 결정적 차이가 여기 있습니다 — 시분할은 여러 파드가 GPU를 번갈아 쓰므로 한 파드의 폭주가 다른 파드의 지연으로 번지지만, MIG는 옆 인스턴스가 무엇을 하든 내 성능이 보장됩니다. 멀티테넌트 클러스터, 추론 서빙, 학생/팀별 GPU 할당에 MIG가 선호되는 이유입니다.
프로필 이름은 <GI 개수>g.<메모리>gb 형식입니다. 예를 들어 H100 80GB 한 장은 대표적으로 이렇게 쪼갤 수 있습니다:
프로필 인스턴스 수(최대) 용도 감각
1g.10gb ×7 소형 추론 7개
2g.20gb ×3 중형 추론/실험 3개
3g.40gb ×2 중대형 학습 2개
7g.80gb ×1 분할 없이 통째로
(혼합도 가능: 예 — 3g.40gb 1개 + 2g.20gb 1개 + 1g.10gb 2개)
A100 40GB라면 같은 원리로 1g.5gb×7, 2g.10gb×3, 3g.20gb×2 … 형태가 됩니다. 정확한 조합 규칙은 GPU 모델마다 다르므로 NVIDIA MIG 사용자 가이드의 프로필 표를 기준으로 삼으세요.
MIG 전략 — single vs mixed
GPU Operator에서 MIG를 쓰려면 설치 시 **전략(strategy)**부터 정합니다. 이 선택이 쿠버네티스에 리소스가 광고되는 방식을 바꿉니다.
- single — 노드의 모든 GPU가 MIG로, 전부 같은 프로필로 쪼개집니다. 리소스는 익숙한
nvidia.com/gpu이름 그대로 광고되고, 개수만 늘어납니다(예: H100 1장 →nvidia.com/gpu: 7). 파드 스펙을 바꿀 필요가 없어 도입이 가장 쉽습니다. - mixed — 노드 안에서 서로 다른 프로필(심지어 MIG 미적용 GPU)이 공존합니다. 리소스가 프로필별 이름으로 광고됩니다(예:
nvidia.com/mig-1g.10gb,nvidia.com/mig-3g.40gb). 유연하지만 파드가 프로필을 명시해야 합니다.
# single 전략으로 설치
helm install --wait gpu-operator \
-n gpu-operator --create-namespace \
nvidia/gpu-operator \
--version=v26.3.3 \
--set mig.strategy=single
# 클라우드(GKE/EKS 등)처럼 재부팅이 필요한 환경이라면 추가:
# --set migManager.env[0].name=WITH_REBOOT \
# --set-string migManager.env[0].value=true
이미 설치된 클러스터에서 전략만 바꾸려면 ClusterPolicy를 패치합니다:
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
--type='json' \
-p='[{"op":"replace", "path":"/spec/mig/strategy", "value":"mixed"}]'
MIG 적용 — 노드 라벨 하나로
MIG Manager의 동작 원리는 우아할 정도로 단순합니다. nvidia.com/mig.config 노드 라벨을 감시하다가, 라벨이 바뀌면 그 프로필을 하드웨어에 적용합니다.
# H100 노드를 1g.10gb 7개로 분할
kubectl label nodes <노드이름> nvidia.com/mig.config=all-1g.10gb --overwrite
기본 제공 프로필에는 all-disabled(MIG 끄기), all-1g.10gb, all-2g.20gb, all-3g.40gb, all-balanced(여러 크기를 균형 있게 혼합) 등이 있습니다. 적용 과정은 라벨로 추적합니다:
kubectl get node <노드이름> -o jsonpath='{.metadata.labels}' | jq . | grep mig
# nvidia.com/mig.config.state 가
# pending → (필요시 rebooting) → success 로 바뀌면 완료
success 후 리소스를 확인하면 분할 결과가 보입니다:
kubectl describe node <노드이름> | grep -A5 'Allocatable'
# single 전략: nvidia.com/gpu: 7 (라벨의 gpu.product 에 MIG-1g.10gb 표기)
# mixed 전략: nvidia.com/mig-1g.10gb: 7 처럼 프로필별 리소스
mixed 전략에서 파드는 이렇게 특정 프로필을 요청합니다:
resources:
limits:
nvidia.com/mig-1g.10gb: 1
커스텀 프로필 — 한 장 안에서 크기 섞기
기본 프로필로 부족하면(예: "GPU 0번만 3g+1g+1g 혼합, 나머지는 MIG 끄기") ConfigMap으로 직접 정의합니다.
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-mig-config
namespace: gpu-operator
data:
config.yaml: |
version: v1
mig-configs:
all-disabled:
- devices: all
mig-enabled: false
inference-mix:
- devices: [0]
mig-enabled: true
mig-devices:
"1g.10gb": 5
"2g.20gb": 1
- devices: [1, 2, 3]
mig-enabled: false
# MIG Manager가 이 ConfigMap을 쓰도록 ClusterPolicy 패치
kubectl patch clusterpolicies.nvidia.com/cluster-policy \
--type='json' \
-p='[{"op":"replace", "path":"/spec/migManager/config/name", "value":"custom-mig-config"}]'
# 노드에 커스텀 프로필 적용
kubectl label nodes <노드이름> nvidia.com/mig.config=inference-mix --overwrite
참고로 v26.3.0부터는 MIG Manager가 시작 시 NVML로 노드의 하드웨어를 조회해 가능한 프로필 목록을 런타임에 자동 생성해 노드별 ConfigMap으로 써 줍니다. 새 GPU 모델이 나와도 기본 프로필 목록을 기다릴 필요가 없어졌습니다.
운영 주의사항 — 미리 알면 장애가 아닌 것들
- 재구성은 파괴적 작업입니다. MIG Manager는 프로필을 바꾸기 전에 해당 GPU의 모든 파드(디바이스 플러그인·DCGM·GFD 포함)를 중지합니다. 사용자 워크로드가 도는 노드라면 먼저 cordon + drain 하는 것이 안전한 운영 절차입니다.
- 클라우드에서는 재부팅이 필요할 수 있습니다. 일부 CSP 환경은 MIG 모드 전환에 노드 재부팅이 필요합니다 — 위의
WITH_REBOOT설정이 그 대응입니다.mig.config.state가rebooting을 거치는 것이 정상 흐름입니다. - 파드는 인스턴스를 넘을 수 없습니다. MIG 인스턴스 하나가 파드 하나의 상한입니다. 7g 프로필이 필요한 대형 학습이 올 수 있다면 mixed 전략이나 별도 노드풀을 준비하세요. 인스턴스 간 NVLink P2P도 불가입니다.
- 상태가
pending에서 멈추면 MIG Manager 파드 로그부터 보세요. 흔한 원인: 라벨 오타(존재하지 않는 프로필 이름), 해당 GPU가 지원하지 않는 프로필 조합, 아직 GPU를 물고 있는 파드. - 모니터링은 DCGM으로. DCGM Exporter는 MIG 인스턴스 단위 메트릭을 내보내므로, 프로메테우스에서 인스턴스별 사용률·메모리를 그대로 볼 수 있습니다. "쪼갰는데 놀고 있는" 인스턴스를 찾는 것이 MIG 운영의 후반전입니다.
- 시분할과의 선택 기준: 격리·예측 가능성이 필요하면 MIG, 오버서브스크립션(더 많은 파드를 어떻게든 태우기)이 목적이고 간섭을 감수할 수 있으면 time-slicing — 두 기능은 목적이 다릅니다.
마치며
GPU Operator는 "GPU 노드 셋업"이라는 반복 노동을 선언형 리소스 하나로 바꿔 놓았고, MIG Manager는 그 위에서 값비싼 GPU의 활용률 문제를 라벨 한 줄로 다루게 해 줍니다. 요약하면: Helm으로 설치하고, 전략(single/mixed)을 정하고, nvidia.com/mig.config 라벨로 분할하고, mig.config.state로 확인하고, DCGM으로 관찰한다 — 이 다섯 문장이 전부입니다. 나머지는 여러분의 워크로드에 맞는 프로필을 찾는 일이고, 그것은 모니터링 데이터가 알려줄 것입니다.
리눅스·쿠버네티스 기본기를 함께 다지고 싶다면 리눅스 터미널과 쿠버스트로넛 퀴즈도 활용해 보세요.