Skip to content

필사 모드: NVIDIA GPU Operator 완벽 가이드: 구성요소, 설치, KubeVirt GPU 패스스루까지 총정리

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

1. GPU Operator 소개

1.1 GPU Operator란?

NVIDIA GPU Operator는 Kubernetes 클러스터에서 GPU를 활용하기 위해 필요한 **모든 소프트웨어 컴포넌트의 설치, 설정, 관리를 자동화**하는 Kubernetes Operator이다. Kubernetes의 Operator Framework를 기반으로, GPU 워크로드 실행에 필요한 드라이버, 런타임, 디바이스 플러그인, 모니터링 도구 등을 **Day-0 프로비저닝**부터 **Day-2 운영**까지 일관되게 관리한다.

전통적으로 Kubernetes에서 GPU를 사용하려면 다음과 같은 작업을 **각 노드마다 수동으로** 수행해야 했다:

1. NVIDIA 드라이버 설치 (커널 버전에 맞는 정확한 버전)

2. NVIDIA Container Toolkit 설치 및 Container Runtime 설정

3. NVIDIA Device Plugin 배포

4. 모니터링 도구 (DCGM Exporter) 설치

5. Node Feature Discovery 배포

GPU Operator는 이 모든 과정을 **ClusterPolicy**라는 단일 Custom Resource Definition(CRD)으로 선언적(declarative)으로 관리한다.

1.2 왜 GPU Operator가 필요한가?

수동 GPU 드라이버 설치 방식에는 다음과 같은 심각한 운영 문제가 있다:

| 문제점 | 수동 관리 | GPU Operator |

| ---------------------- | --------------------------------------- | ------------------------------- |

| **드라이버 설치** | 각 노드 SSH 접속 후 수동 설치 | DaemonSet으로 자동 배포 |

| **커널 업데이트 대응** | 커널 업데이트 시 드라이버 재컴파일 필요 | Pre-compiled 드라이버 자동 매칭 |

| **버전 일관성** | 노드별 드라이버 버전 불일치 위험 | ClusterPolicy로 버전 통일 |

| **신규 노드 추가** | 프로비저닝 스크립트 유지보수 필요 | 라벨 기반 자동 감지 및 설치 |

| **모니터링** | 별도 설정 필요 | DCGM Exporter 자동 배포 |

| **GPU 공유** | MIG/Time-Slicing 수동 설정 | ConfigMap 기반 선언적 설정 |

| **업그레이드** | 노드 드레인 후 수동 업데이트 | Rolling Update 지원 |

1.3 지원 환경

**지원 OS:**

| OS | 버전 |

| ------------------------ | ----------------------- |

| Ubuntu | 20.04, 22.04, 24.04 LTS |

| Red Hat Enterprise Linux | 8.x, 9.x |

| CentOS Stream | 8, 9 |

| Rocky Linux | 8.x, 9.x |

| SUSE Linux Enterprise | 15 SP4+ |

**지원 GPU:**

| GPU 세대 | 모델 예시 | MIG 지원 |

| ------------ | ------------------ | ------------- |

| Turing | T4, RTX 2080 | X |

| Ampere | A100, A30, A10, A2 | O (A100, A30) |

| Hopper | H100, H200 | O |

| Ada Lovelace | L40, L40S, L4 | X |

| Blackwell | B100, B200, GB200 | O |

**지원 Kubernetes 버전:** v1.25 이상 (권장: v1.28+)

**지원 Container Runtime:** containerd, CRI-O

1.4 아키텍처 개요

┌─────────────────────────────────────────────────────────────────────┐

│ Kubernetes Control Plane │

│ ┌──────────────────────────────────────────────────────────────┐ │

│ │ GPU Operator Controller │ │

│ │ (Deployment in gpu-operator namespace) │ │

│ │ │ │

│ │ ┌────────────────┐ ┌─────────────────────────────────┐ │ │

│ │ │ ClusterPolicy │───▶│ Reconciliation Loop │ │ │

│ │ │ (CRD) │ │ - Watch GPU Nodes │ │ │

│ │ └────────────────┘ │ - Deploy DaemonSets │ │ │

│ │ │ - Manage Lifecycle │ │ │

│ │ └─────────────────────────────────┘ │ │

│ └──────────────────────────────────────────────────────────────┘ │

└─────────────────────────────────────────────────────────────────────┘

┌──────────────┼──────────────┐

▼ ▼ ▼

┌──────────────────┐ ┌──────────────┐ ┌──────────────────┐

│ GPU Worker #1 │ │ GPU Worker #2│ │ GPU Worker #3 │

│ │ │ │ │ │

│ ┌──────────────┐ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ │ NFD │ │ │ │ NFD │ │ │ │ NFD │ │

│ │ (Node Feature│ │ │ │ │ │ │ │ │ │

│ │ Discovery) │ │ │ └──────────┘ │ │ └──────────────┘ │

│ └──────────────┘ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ ┌──────────────┐ │ │ │ GFD │ │ │ │ GFD │ │

│ │ GFD │ │ │ │ │ │ │ │ │ │

│ │ (GPU Feature │ │ │ └──────────┘ │ │ └──────────────┘ │

│ │ Discovery) │ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ └──────────────┘ │ │ │ Driver │ │ │ │ Driver │ │

│ ┌──────────────┐ │ │ │ │ │ │ │ │ │

│ │ NVIDIA Driver│ │ │ └──────────┘ │ │ └──────────────┘ │

│ │ (DaemonSet) │ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ └──────────────┘ │ │ │ Toolkit │ │ │ │ Toolkit │ │

│ ┌──────────────┐ │ │ │ │ │ │ │ │ │

│ │ Container │ │ │ └──────────┘ │ │ └──────────────┘ │

│ │ Toolkit │ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ └──────────────┘ │ │ │ Device │ │ │ │ Device │ │

│ ┌──────────────┐ │ │ │ Plugin │ │ │ │ Plugin │ │

│ │ Device Plugin│ │ │ └──────────┘ │ │ └──────────────┘ │

│ └──────────────┘ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ ┌──────────────┐ │ │ │ DCGM │ │ │ │ DCGM │ │

│ │ DCGM Exporter│ │ │ │ Exporter │ │ │ │ Exporter │ │

│ └──────────────┘ │ │ └──────────┘ │ │ └──────────────┘ │

│ ┌──────────────┐ │ │ ┌──────────┐ │ │ ┌──────────────┐ │

│ │ MIG Manager │ │ │ │ MIG Mgr │ │ │ │ MIG Manager │ │

│ └──────────────┘ │ │ └──────────┘ │ │ └──────────────┘ │

│ │ │ │ │ │

│ ╔════════════╗ │ │ ╔══════════╗ │ │ ╔════════════╗ │

│ ║ NVIDIA GPU ║ │ │ ║ NVIDIA ║ │ │ ║ NVIDIA GPU ║ │

│ ║ (A100) ║ │ │ ║ GPU(H100)║ │ │ ║ (T4) ║ │

│ ╚════════════╝ │ │ ╚══════════╝ │ │ ╚════════════╝ │

└──────────────────┘ └──────────────┘ └──────────────────┘

GPU Operator Controller는 ClusterPolicy CRD를 감시(watch)하며, GPU가 탑재된 워커 노드를 자동으로 감지하여 필요한 모든 컴포넌트를 DaemonSet 형태로 배포한다. 노드에 `feature.node.kubernetes.io/pci-10de.present=true` 라벨이 있으면 NVIDIA GPU가 존재하는 것으로 인식한다.

2. 7대 핵심 구성요소 상세 분석

GPU Operator는 GPU 워크로드 실행에 필요한 전체 소프트웨어 스택을 7개의 핵심 컴포넌트로 구성한다. 각 컴포넌트는 DaemonSet으로 배포되며, 서로 의존 관계를 가진다.

2.1 NVIDIA Driver (nvidia-driver-daemonset)

NVIDIA Driver DaemonSet은 GPU 하드웨어와 통신하기 위한 **커널 모듈(kernel module)**을 각 GPU 노드에 자동으로 설치한다. 이것은 GPU Operator의 가장 기초적이고 핵심적인 컴포넌트이다.

**주요 기능:**

- NVIDIA 커널 모듈 (`nvidia.ko`, `nvidia-modeset.ko`, `nvidia-uvm.ko`) 자동 빌드 및 로드

- 호스트 커널 버전에 맞는 드라이버 자동 매칭

- Pre-compiled 드라이버와 Run-compiled 드라이버 지원

- 드라이버 버전 관리 및 업그레이드

**Pre-compiled vs Run-compiled:**

| 특성 | Pre-compiled | Run-compiled |

| ------------------ | ------------------------------- | ------------------------------- |

| **빌드 시간** | 없음 (이미 빌드됨) | 노드에서 10-20분 소요 |

| **커널 호환성** | 특정 커널 버전에 매칭 | 모든 커널 버전 지원 |

| **노드 부팅 시간** | 빠름 | 느림 |

| **지원 OS** | Ubuntu (주로) | 대부분의 Linux |

| **설정** | `kernelModuleType: precompiled` | `kernelModuleType: runcompiled` |

**ClusterPolicy에서 Driver 설정 예시:**

apiVersion: nvidia.com/v1

kind: ClusterPolicy

metadata:

name: cluster-policy

spec:

driver:

enabled: true

repository: nvcr.io/nvidia

image: driver

version: '560.35.03'

kernelModuleType: auto # auto | precompiled | runcompiled

manager:

env:

- name: ENABLE_AUTO_DRAIN

value: 'true'

rdma:

enabled: false

licensingConfig:

nlsEnabled: false

configMapName: ''

> **주의:** 호스트에 이미 NVIDIA 드라이버가 설치되어 있는 경우 `driver.enabled=false`로 설정해야 한다. 두 드라이버가 충돌하면 GPU가 정상 작동하지 않는다.

2.2 NVIDIA Container Toolkit (nvidia-container-toolkit)

NVIDIA Container Toolkit은 Container Runtime(containerd, CRI-O)이 **컨테이너 내부에서 GPU에 접근할 수 있도록** 연결하는 브릿지 역할을 한다.

**핵심 동작 원리:**

┌─────────────────────────────────────────────────────┐

│ Container Creation Flow │

│ │

│ kubelet │

│ │ │

│ ▼ │

│ containerd/CRI-O │

│ │ │

│ ▼ │

│ ┌─────────────────────────────────────┐ │

│ │ NVIDIA Container Runtime Hook │ │

│ │ (nvidia-container-runtime-hook) │ │

│ │ │ │

│ │ 1. OCI spec 수정 │ │

│ │ 2. GPU 디바이스 마운트 │ │

│ │ 3. NVIDIA 라이브러리 주입 │ │

│ │ 4. 환경변수 설정 │ │

│ └─────────────────────────────────────┘ │

│ │ │

│ ▼ │

│ ┌─────────────────────────────────────┐ │

│ │ libnvidia-container │ │

│ │ - GPU 디바이스 노드 바인딩 │ │

│ │ - CUDA 라이브러리 마운트 │ │

│ │ - Driver 라이브러리 마운트 │ │

│ └─────────────────────────────────────┘ │

│ │ │

│ ▼ │

│ Container (with GPU access) │

│ /dev/nvidia0, /dev/nvidiactl, ... │

└─────────────────────────────────────────────────────┘

**CDI (Container Device Interface) 지원:**

GPU Operator v25.x부터 CDI가 기본 활성화되어, 컨테이너 런타임이 GPU 디바이스를 표준화된 방식으로 인식한다. CDI는 OCI 런타임 hook 방식보다 더 안정적이고 예측 가능한 디바이스 할당을 제공한다.

spec:

toolkit:

enabled: true

version: v1.17.3-ubuntu22.04

cdi:

enabled: true # CDI 활성화 (기본값: true)

default: true # CDI를 기본 디바이스 할당 방식으로 사용

2.3 NVIDIA Device Plugin (nvidia-device-plugin)

NVIDIA Device Plugin은 kubelet에 **GPU를 Kubernetes Extended Resource로 등록**하는 역할을 한다. 이를 통해 Pod이 `nvidia.com/gpu` 리소스를 요청할 수 있게 된다.

**동작 흐름:**

1. Device Plugin이 kubelet의 Device Plugin gRPC 인터페이스에 등록

2. 노드에 있는 GPU 개수를 kubelet에 보고

3. Kubernetes Scheduler가 `nvidia.com/gpu` 리소스 요청이 있는 Pod을 해당 노드에 스케줄링

4. Pod 실행 시 Device Plugin이 할당할 GPU 디바이스 정보를 kubelet에 전달

**Pod에서 GPU 요청 예시:**

apiVersion: v1

kind: Pod

metadata:

name: cuda-test

spec:

restartPolicy: OnFailure

containers:

- name: cuda-test

image: nvcr.io/nvidia/cuda:12.6.0-base-ubuntu22.04

command: ['nvidia-smi']

resources:

limits:

nvidia.com/gpu: 1 # GPU 1개 요청

**Device Plugin이 관리하는 리소스 종류:**

| 리소스 이름 | 설명 | 사용 상황 |

| ------------------------ | --------------------------------- | ------------------------- |

| `nvidia.com/gpu` | 전체 GPU (또는 Time-Slicing 공유) | 기본 GPU 워크로드 |

| `nvidia.com/mig-1g.5gb` | MIG 1g.5gb 인스턴스 | A100 MIG 파티션 |

| `nvidia.com/mig-2g.10gb` | MIG 2g.10gb 인스턴스 | A100 MIG 파티션 |

| `nvidia.com/mig-3g.20gb` | MIG 3g.20gb 인스턴스 | A100 MIG 파티션 |

| `nvidia.com/mig-7g.40gb` | MIG 7g.40gb 인스턴스 | A100 전체 MIG |

| `nvidia.com/gpu.shared` | Time-Slicing 공유 GPU | renameByDefault 활성화 시 |

2.4 NVIDIA DCGM & DCGM Exporter

**DCGM (Data Center GPU Manager)**은 NVIDIA GPU의 상태와 성능을 모니터링하기 위한 도구이며, **DCGM Exporter**는 이 메트릭을 Prometheus 포맷으로 노출하는 Exporter이다.

**주요 수집 메트릭:**

| 메트릭 이름 | 설명 | 단위 |

| -------------------------------- | ----------------------------- | ----- |

| `DCGM_FI_DEV_GPU_UTIL` | GPU 코어 사용률 | % |

| `DCGM_FI_DEV_MEM_COPY_UTIL` | 메모리 대역폭 사용률 | % |

| `DCGM_FI_DEV_GPU_TEMP` | GPU 온도 | C |

| `DCGM_FI_DEV_POWER_USAGE` | 전력 소비량 | W |

| `DCGM_FI_DEV_FB_FREE` | 사용 가능한 프레임버퍼 메모리 | MiB |

| `DCGM_FI_DEV_FB_USED` | 사용 중인 프레임버퍼 메모리 | MiB |

| `DCGM_FI_DEV_SM_CLOCK` | SM 클럭 주파수 | MHz |

| `DCGM_FI_DEV_MEM_CLOCK` | 메모리 클럭 주파수 | MHz |

| `DCGM_FI_DEV_ENC_UTIL` | 인코더 사용률 | % |

| `DCGM_FI_DEV_DEC_UTIL` | 디코더 사용률 | % |

| `DCGM_FI_DEV_PCIE_TX_THROUGHPUT` | PCIe 송신 처리량 | KB/s |

| `DCGM_FI_DEV_PCIE_RX_THROUGHPUT` | PCIe 수신 처리량 | KB/s |

| `DCGM_FI_DEV_XID_ERRORS` | XID 에러 발생 횟수 | count |

| `DCGM_FI_DEV_ECC_SBE_VOL_TOTAL` | Single-bit ECC 에러 (일시적) | count |

| `DCGM_FI_DEV_ECC_DBE_VOL_TOTAL` | Double-bit ECC 에러 (영구적) | count |

**DCGM Exporter 아키텍처:**

┌──────────────┐ ┌───────────────┐ ┌──────────────┐

│ NVIDIA GPU │────▶│ DCGM Daemon │────▶│ DCGM Exporter│

│ (Hardware) │ │ (libdcgm.so) │ │ (:9400/metrics)

└──────────────┘ └───────────────┘ └──────┬───────┘

┌──────────────┐

│ Prometheus │

│ (scrape) │

└──────┬───────┘

┌──────────────┐

│ Grafana │

│ (Dashboard) │

└──────────────┘

**ClusterPolicy 설정:**

spec:

dcgm:

enabled: true # standalone DCGM daemon

dcgmExporter:

enabled: true

version: '3.3.9-3.6.1-ubuntu22.04'

config:

name: 'dcgm-metrics-config' # 커스텀 메트릭 설정

serviceMonitor:

enabled: true # Prometheus ServiceMonitor 자동 생성

interval: '15s'

honorLabels: false

additionalLabels:

monitoring: 'gpu'

2.5 NVIDIA MIG Manager

**MIG (Multi-Instance GPU) Manager**는 NVIDIA Ampere 이상 아키텍처의 GPU(A100, A30, H100 등)에서 하나의 물리 GPU를 **여러 개의 독립적인 GPU 인스턴스로 분할**하는 것을 관리한다.

MIG는 Time-Slicing과 달리 **하드웨어 수준의 메모리 격리와 연산 격리**를 제공한다. 각 MIG 인스턴스는 자체 메모리, 캐시, SM(Streaming Multiprocessor)을 가진다.

**A100 40GB MIG 프로파일:**

| 프로파일 | GPU 슬라이스 | 메모리 | 최대 인스턴스 수 |

| ----------- | ------------ | ----------- | ---------------- |

| `1g.5gb` | 1/7 | 5 GB | 7 |

| `1g.5gb+me` | 1/7 | 5 GB (+MPS) | 1 |

| `1g.10gb` | 1/7 | 10 GB | 4 |

| `2g.10gb` | 2/7 | 10 GB | 3 |

| `3g.20gb` | 3/7 | 20 GB | 2 |

| `4g.20gb` | 4/7 | 20 GB | 1 |

| `7g.40gb` | 7/7 | 40 GB | 1 |

**H100 80GB MIG 프로파일:**

| 프로파일 | GPU 슬라이스 | 메모리 | 최대 인스턴스 수 |

| --------- | ------------ | ------ | ---------------- |

| `1g.10gb` | 1/7 | 10 GB | 7 |

| `1g.20gb` | 1/7 | 20 GB | 4 |

| `2g.20gb` | 2/7 | 20 GB | 3 |

| `3g.40gb` | 3/7 | 40 GB | 2 |

| `4g.40gb` | 4/7 | 40 GB | 1 |

| `7g.80gb` | 7/7 | 80 GB | 1 |

**MIG Manager 동작 원리:**

1. 관리자가 노드에 `nvidia.com/mig.config=<profile>` 라벨 적용

2. MIG Manager가 라벨 변경 감지

3. 기존 GPU 워크로드 자동 종료 (drain)

4. `nvidia-smi mig` 명령으로 MIG 인스턴스 생성/삭제

5. Device Plugin이 새 MIG 인스턴스를 Kubernetes 리소스로 등록

6. 완료 후 `nvidia.com/mig.config.state=success` 라벨 업데이트

2.6 Node Feature Discovery (NFD)

**Node Feature Discovery (NFD)**는 Kubernetes 노드의 하드웨어 특성을 자동으로 감지하고 **노드 라벨로 등록**하는 컴포넌트이다. GPU Operator의 의존성으로, GPU 노드를 식별하는 데 핵심적인 역할을 한다.

**NFD가 생성하는 주요 라벨:**

| 라벨 | 설명 | 예시 값 |

| --------------------------------------------------------- | ----------------------------- | ------------------- |

| `feature.node.kubernetes.io/pci-10de.present` | NVIDIA PCI 디바이스 존재 여부 | `true` |

| `feature.node.kubernetes.io/cpu-cpuid.AVX512F` | CPU AVX-512 지원 | `true` |

| `feature.node.kubernetes.io/kernel-version.full` | 커널 버전 | `5.15.0-91-generic` |

| `feature.node.kubernetes.io/system-os_release.ID` | OS 종류 | `ubuntu` |

| `feature.node.kubernetes.io/system-os_release.VERSION_ID` | OS 버전 | `22.04` |

GPU Operator는 `feature.node.kubernetes.io/pci-10de.present=true` 라벨을 통해 NVIDIA GPU가 장착된 노드를 자동으로 식별하고, 해당 노드에만 GPU 관련 DaemonSet을 배포한다.

> **참고:** 클러스터에 이미 NFD가 설치되어 있다면 GPU Operator 설치 시 `nfd.enabled=false`로 설정하여 중복 배포를 방지해야 한다.

2.7 GPU Feature Discovery (GFD)

**GPU Feature Discovery (GFD)**는 NFD와 유사하지만, **GPU 전용 상세 정보**를 노드 라벨로 등록하는 역할을 한다. GFD는 NVIDIA Driver와 통신하여 GPU 모델, 드라이버 버전, CUDA 버전 등의 정보를 수집한다.

**GFD가 생성하는 주요 라벨:**

| 라벨 | 설명 | 예시 값 |

| ------------------------------- | ------------------------ | ----------------------- |

| `nvidia.com/gpu.product` | GPU 모델명 | `NVIDIA-A100-SXM4-40GB` |

| `nvidia.com/gpu.memory` | GPU 메모리 (MiB) | `40960` |

| `nvidia.com/gpu.count` | GPU 개수 | `4` |

| `nvidia.com/gpu.family` | GPU 아키텍처 패밀리 | `ampere` |

| `nvidia.com/gpu.compute.major` | Compute Capability Major | `8` |

| `nvidia.com/gpu.compute.minor` | Compute Capability Minor | `0` |

| `nvidia.com/cuda.driver.major` | CUDA 드라이버 Major 버전 | `12` |

| `nvidia.com/cuda.driver.minor` | CUDA 드라이버 Minor 버전 | `6` |

| `nvidia.com/cuda.runtime.major` | CUDA Runtime Major 버전 | `12` |

| `nvidia.com/cuda.runtime.minor` | CUDA Runtime Minor 버전 | `6` |

| `nvidia.com/mig.capable` | MIG 지원 여부 | `true` |

| `nvidia.com/gpu.replicas` | Time-Slicing 레플리카 수 | `4` |

| `nvidia.com/mig.strategy` | MIG 전략 | `single` |

**GFD 라벨 활용 - nodeSelector 예시:**

apiVersion: v1

kind: Pod

metadata:

name: a100-workload

spec:

nodeSelector:

nvidia.com/gpu.product: 'NVIDIA-A100-SXM4-40GB'

nvidia.com/gpu.memory: '40960'

containers:

- name: training

image: my-training:latest

resources:

limits:

nvidia.com/gpu: 4

2.8 컴포넌트 관계 다이어그램 및 요약

**컴포넌트 배포 순서 (의존성 체인):**

NFD (Node Feature Discovery)

└──▶ GPU Feature Discovery (GFD)

└──▶ NVIDIA Driver

└──▶ NVIDIA Container Toolkit

└──▶ NVIDIA Device Plugin

└──▶ DCGM / DCGM Exporter

└──▶ MIG Manager (MIG 지원 GPU만)

└──▶ Validator (검증)

**컴포넌트별 역할 요약 테이블:**

| 컴포넌트 | DaemonSet 이름 | 역할 | 네임스페이스 |

| ------------- | ------------------------------------ | -------------------------- | -------------- |

| NFD | `node-feature-discovery-worker` | 노드 하드웨어 라벨링 | `gpu-operator` |

| GFD | `gpu-feature-discovery` | GPU 상세 정보 라벨링 | `gpu-operator` |

| Driver | `nvidia-driver-daemonset` | GPU 커널 모듈 설치 | `gpu-operator` |

| Toolkit | `nvidia-container-toolkit-daemonset` | Container Runtime GPU 연동 | `gpu-operator` |

| Device Plugin | `nvidia-device-plugin-daemonset` | GPU 리소스 kubelet 등록 | `gpu-operator` |

| DCGM | `nvidia-dcgm` | GPU 메트릭 수집 데몬 | `gpu-operator` |

| DCGM Exporter | `nvidia-dcgm-exporter` | Prometheus 메트릭 노출 | `gpu-operator` |

| MIG Manager | `nvidia-mig-manager` | MIG 파티션 관리 | `gpu-operator` |

| Validator | `nvidia-operator-validator` | 전체 스택 검증 | `gpu-operator` |

3. 설치 가이드 (Helm 기반)

3.1 사전 요구사항

3.1.1 하드웨어 요구사항

- NVIDIA GPU가 장착된 워커 노드 (Turing 아키텍처 이상 권장)

- PCIe 3.0 이상 슬롯

- IOMMU 지원 (KubeVirt GPU Passthrough 사용 시)

3.1.2 소프트웨어 요구사항

kubectl 및 helm 설치 확인

kubectl version --client

helm version

Kubernetes 클러스터 접근 확인

kubectl get nodes

Container Runtime 확인 (containerd 또는 CRI-O)

kubectl get nodes -o wide

3.1.3 Nouveau 드라이버 비활성화

GPU Operator의 Driver DaemonSet이 NVIDIA 드라이버를 로드하려면, 오픈소스 Nouveau 드라이버가 비활성화되어 있어야 한다.

nouveau 모듈 로드 여부 확인

lsmod | grep nouveau

nouveau 비활성화 (필요한 경우)

cat <<EOF | sudo tee /etc/modprobe.d/blacklist-nouveau.conf

blacklist nouveau

options nouveau modeset=0

EOF

initramfs 재생성

sudo update-initramfs -u

재부팅

sudo reboot

> **참고:** GPU Operator v25.x부터는 Driver DaemonSet이 Nouveau 모듈을 자동으로 언로드하려고 시도하지만, 일부 환경에서는 수동 비활성화가 필요할 수 있다.

3.1.4 Pod Security Admission 설정

GPU Operator는 privileged 권한이 필요한 컨테이너를 실행하므로, 네임스페이스에 적절한 PSA 라벨이 필요하다.

gpu-operator 네임스페이스에 PSA 라벨 설정

kubectl create namespace gpu-operator

kubectl label namespace gpu-operator \

pod-security.kubernetes.io/enforce=privileged

3.2 Helm Repo 추가 및 기본 설치

NVIDIA Helm repository 추가

helm repo add nvidia https://helm.ngc.nvidia.com/nvidia

helm repo update

사용 가능한 버전 확인

helm search repo nvidia/gpu-operator --versions

기본 설치 (최신 버전)

helm install gpu-operator \

-n gpu-operator --create-namespace \

nvidia/gpu-operator \

--version=v25.10.1 \

--wait

**설치 확인:**

GPU Operator Pod 상태 확인

kubectl get pods -n gpu-operator

기대 출력 (정상 상태):

NAME READY STATUS RESTARTS AGE

gpu-operator-xxxxx 1/1 Running 0 5m

gpu-feature-discovery-xxxxx 1/1 Running 0 4m

nvidia-container-toolkit-daemonset-xxxxx 1/1 Running 0 4m

nvidia-cuda-validator-xxxxx 0/1 Completed 0 3m

nvidia-dcgm-exporter-xxxxx 1/1 Running 0 4m

nvidia-device-plugin-daemonset-xxxxx 1/1 Running 0 4m

nvidia-driver-daemonset-xxxxx 1/1 Running 0 4m

nvidia-operator-validator-xxxxx 1/1 Running 0 3m

node-feature-discovery-gc-xxxxx 1/1 Running 0 5m

node-feature-discovery-master-xxxxx 1/1 Running 0 5m

node-feature-discovery-worker-xxxxx 1/1 Running 0 5m

3.3 ClusterPolicy CRD 설정 상세

GPU Operator의 모든 설정은 **ClusterPolicy** CRD를 통해 관리된다. Helm chart의 `values.yaml`이 ClusterPolicy를 생성한다.

apiVersion: nvidia.com/v1

kind: ClusterPolicy

metadata:

name: cluster-policy

spec:

─────────────────────────────────────────────────────

1. NVIDIA Driver 설정

─────────────────────────────────────────────────────

driver:

enabled: true

repository: nvcr.io/nvidia

image: driver

version: '560.35.03'

kernelModuleType: auto # auto | precompiled | runcompiled

manager:

env:

- name: ENABLE_AUTO_DRAIN

value: 'true'

- name: DRAIN_USE_FORCE

value: 'false'

- name: DRAIN_POD_SELECTOR_LABEL

value: ''

rdma:

enabled: false

useHostMofed: false

licensingConfig:

nlsEnabled: false

configMapName: ''

─────────────────────────────────────────────────────

2. NVIDIA Container Toolkit 설정

─────────────────────────────────────────────────────

toolkit:

enabled: true

version: v1.17.3-ubuntu22.04

env:

- name: CONTAINERD_CONFIG

value: /etc/containerd/config.toml

- name: CONTAINERD_SOCKET

value: /run/containerd/containerd.sock

─────────────────────────────────────────────────────

3. CDI (Container Device Interface) 설정

─────────────────────────────────────────────────────

cdi:

enabled: true

default: true

─────────────────────────────────────────────────────

4. Device Plugin 설정

─────────────────────────────────────────────────────

devicePlugin:

enabled: true

version: v0.17.0

config:

name: '' # Time-Slicing/MIG ConfigMap 이름

default: '' # 기본 설정 키

env:

- name: PASS_DEVICE_SPECS

value: 'true'

- name: DEVICE_LIST_STRATEGY

value: 'envvar'

─────────────────────────────────────────────────────

5. DCGM & DCGM Exporter 설정

─────────────────────────────────────────────────────

dcgm:

enabled: true

dcgmExporter:

enabled: true

version: '3.3.9-3.6.1-ubuntu22.04'

config:

name: '' # 커스텀 메트릭 ConfigMap

serviceMonitor:

enabled: true

interval: '15s'

─────────────────────────────────────────────────────

6. MIG Manager 설정

─────────────────────────────────────────────────────

migManager:

enabled: true

env:

- name: WITH_REBOOT

value: 'false'

─────────────────────────────────────────────────────

7. MIG 전략 설정

─────────────────────────────────────────────────────

mig:

strategy: single # single | mixed

─────────────────────────────────────────────────────

8. Node Feature Discovery 설정

─────────────────────────────────────────────────────

nodeFeatureDiscovery:

enabled: true

─────────────────────────────────────────────────────

9. GPU Feature Discovery 설정

─────────────────────────────────────────────────────

gfd:

enabled: true

version: v0.17.0

─────────────────────────────────────────────────────

10. Sandbox Workloads (KubeVirt 연동)

─────────────────────────────────────────────────────

sandboxWorkloads:

enabled: false # KubeVirt 사용 시 true

defaultWorkload: container # container | vm-passthrough | vm-vgpu

─────────────────────────────────────────────────────

11. Validator 설정

─────────────────────────────────────────────────────

validator:

plugin:

env:

- name: WITH_WORKLOAD

value: 'true'

3.4 values.yaml 커스터마이징 예제

**프로덕션 환경 values.yaml 예시:**

production-values.yaml

드라이버가 호스트에 이미 설치된 경우

driver:

enabled: false

Container Toolkit

toolkit:

enabled: true

Device Plugin + Time-Slicing 설정

devicePlugin:

config:

name: 'time-slicing-config'

default: 'tesla-t4'

DCGM Exporter + ServiceMonitor

dcgmExporter:

serviceMonitor:

enabled: true

interval: '15s'

additionalLabels:

release: prometheus

NFD가 이미 설치된 경우

nfd:

enabled: false

MIG 설정 (A100/H100 사용 시)

mig:

strategy: mixed

Node affinity - GPU 노드에만 배포

daemonsets:

tolerations:

- key: nvidia.com/gpu

operator: Exists

effect: NoSchedule

**설치 명령어:**

helm install gpu-operator \

-n gpu-operator --create-namespace \

nvidia/gpu-operator \

--version=v25.10.1 \

-f production-values.yaml \

--wait

3.5 에어갭(Air-gapped) 환경 설치

인터넷이 차단된 환경에서는 모든 컨테이너 이미지를 Private Registry로 미러링해야 한다.

1. 필요한 이미지 목록 확인

helm template gpu-operator nvidia/gpu-operator \

--version=v25.10.1 | grep "image:" | sort -u

2. 이미지 미러링 (예: Harbor)

PRIVATE_REGISTRY="harbor.internal.company.com/nvidia"

주요 이미지 목록

IMAGES=(

"nvcr.io/nvidia/driver:560.35.03-ubuntu22.04"

"nvcr.io/nvidia/k8s-device-plugin:v0.17.0"

"nvcr.io/nvidia/gpu-feature-discovery:v0.17.0"

"nvcr.io/nvidia/cloud-native/dcgm:3.3.9-1-ubuntu22.04"

"nvcr.io/nvidia/k8s/dcgm-exporter:3.3.9-3.6.1-ubuntu22.04"

"nvcr.io/nvidia/cloud-native/k8s-mig-manager:v0.9.0"

"nvcr.io/nvidia/k8s/container-toolkit:v1.17.3-ubuntu22.04"

"nvcr.io/nvidia/cloud-native/gpu-operator-validator:v25.10.1"

"registry.k8s.io/nfd/node-feature-discovery:v0.16.6"

)

for img in "${IMAGES[@]}"; do

이미지 이름 추출

name=$(echo $img | sed 's|.*/||')

docker pull $img

docker tag $img ${PRIVATE_REGISTRY}/${name}

docker push ${PRIVATE_REGISTRY}/${name}

done

3. Private Registry를 사용하는 values.yaml 생성

cat <<EOF > airgap-values.yaml

driver:

repository: ${PRIVATE_REGISTRY}

image: driver

version: "560.35.03-ubuntu22.04"

toolkit:

repository: ${PRIVATE_REGISTRY}

devicePlugin:

repository: ${PRIVATE_REGISTRY}

dcgm:

repository: ${PRIVATE_REGISTRY}

dcgmExporter:

repository: ${PRIVATE_REGISTRY}

gfd:

repository: ${PRIVATE_REGISTRY}

migManager:

repository: ${PRIVATE_REGISTRY}

validator:

repository: ${PRIVATE_REGISTRY}

nfd:

image:

repository: ${PRIVATE_REGISTRY}/node-feature-discovery

EOF

4. 에어갭 환경 설치

helm install gpu-operator \

-n gpu-operator --create-namespace \

nvidia/gpu-operator \

--version=v25.10.1 \

-f airgap-values.yaml \

--wait

3.6 검증 방법

nvidia-smi Pod 테스트

nvidia-smi 실행 확인

kubectl run nvidia-smi \

--restart=Never \

--image=nvcr.io/nvidia/cuda:12.6.0-base-ubuntu22.04 \

--overrides='{"spec":{"restartPolicy":"Never","containers":[{"name":"nvidia-smi","image":"nvcr.io/nvidia/cuda:12.6.0-base-ubuntu22.04","command":["nvidia-smi"],"resources":{"limits":{"nvidia.com/gpu":"1"}}}]}}' \

&& kubectl logs nvidia-smi

기대 출력:

+-----------------------------------------------------------------------------------------+

| NVIDIA-SMI 560.35.03 Driver Version: 560.35.03 CUDA Version: 12.6 |

|-------------------------------+----------------------+----------------------+

| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |

| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |

|===============================+======================+======================|

| 0 NVIDIA A100-SXM... On | 00000000:00:1E.0 Off | 0 |

| N/A 32C P0 52W / 400W | 0MiB / 40960MiB | 0% Default |

+-------------------------------+----------------------+----------------------+

정리

kubectl delete pod nvidia-smi

cuda-vectoradd 테스트

cuda-vectoradd-test.yaml

apiVersion: v1

kind: Pod

metadata:

name: cuda-vectoradd

spec:

restartPolicy: OnFailure

containers:

- name: cuda-vectoradd

image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda12.5.0-ubuntu22.04

resources:

limits:

nvidia.com/gpu: 1

kubectl apply -f cuda-vectoradd-test.yaml

kubectl logs cuda-vectoradd

기대 출력:

[Vector addition of 50000 elements]

Copy input data from the host memory to the CUDA device

CUDA kernel launch with 196 blocks of 256 threads

Copy output data from the CUDA device to the host memory

Test PASSED

Done

kubectl delete pod cuda-vectoradd

노드 GPU 리소스 확인

노드별 GPU 리소스 확인

kubectl describe node <gpu-node-name> | grep -A 10 "Capacity:"

기대 출력:

Capacity:

nvidia.com/gpu: 4

Allocatable:

nvidia.com/gpu: 4

Allocated resources:

nvidia.com/gpu 0 4

GPU 관련 라벨 확인

kubectl get node <gpu-node-name> -o json | jq '.metadata.labels | with_entries(select(.key | startswith("nvidia.com")))'

4. GPU 공유 전략

GPU는 비용이 높은 리소스이므로, 여러 워크로드가 하나의 GPU를 공유하는 전략이 중요하다. GPU Operator는 세 가지 GPU 공유 방식을 지원한다.

4.1 Time-Slicing (시분할)

Time-Slicing은 하나의 물리 GPU를 **시간 기반으로 분할**하여 여러 컨테이너가 공유하게 하는 방식이다. CUDA Time-Slicing 메커니즘을 활용하며, 모든 NVIDIA GPU에서 지원된다.

**특징:**

- 하드웨어 수준 격리 없음 (메모리 격리 없음)

- GPU 메모리 OOM 위험 존재

- 모든 NVIDIA GPU 지원 (Turing 이상)

- 설정이 간단하고 유연함

**설정 방법:**

time-slicing-config.yaml

apiVersion: v1

kind: ConfigMap

metadata:

name: time-slicing-config

namespace: gpu-operator

data:

any: |-

version: v1

flags:

migStrategy: none

sharing:

timeSlicing:

renameByDefault: false

failRequestsGreaterThanOne: false

resources:

- name: nvidia.com/gpu

replicas: 4

ConfigMap 생성

kubectl apply -f time-slicing-config.yaml

ClusterPolicy에 ConfigMap 연결

kubectl patch clusterpolicies.nvidia.com/cluster-policy \

-n gpu-operator --type merge \

-p '{"spec": {"devicePlugin": {"config": {"name": "time-slicing-config", "default": "any"}}}}'

Device Plugin DaemonSet 재시작 (ConfigMap 변경 반영)

kubectl rollout restart daemonset/nvidia-device-plugin-daemonset -n gpu-operator

**결과 확인:**

kubectl describe node <gpu-node> | grep nvidia.com/gpu

Time-Slicing 적용 전 (GPU 4개 노드):

nvidia.com/gpu: 4

Time-Slicing 적용 후 (replicas: 4):

nvidia.com/gpu: 16 (4 GPU x 4 replicas)

4.2 MIG (Multi-Instance GPU)

MIG는 NVIDIA Ampere 이상 아키텍처(A100, A30, H100, H200)에서 지원하는 **하드웨어 수준의 GPU 분할** 기술이다.

**MIG 전략:**

| 전략 | 설명 | 사용 사례 |

| -------- | ---------------------------------------- | --------------------------- |

| `single` | 모든 GPU에 동일한 MIG 프로파일 적용 | 균일한 워크로드 |

| `mixed` | 노드별/GPU별 다른 MIG 프로파일 적용 가능 | 다양한 크기의 워크로드 공존 |

**MIG 설정 방법:**

1. GPU Operator 설치 시 MIG 전략 설정

helm install gpu-operator \

-n gpu-operator --create-namespace \

nvidia/gpu-operator \

--version=v25.10.1 \

--set mig.strategy=single

2. MIG 프로파일 적용 (노드 라벨)

kubectl label nodes <gpu-node> nvidia.com/mig.config=all-1g.10gb --overwrite

3. MIG 설정 상태 확인

kubectl get node <gpu-node> -o jsonpath='{.metadata.labels.nvidia\.com/mig\.config\.state}'

출력: success

**커스텀 MIG 프로파일 ConfigMap:**

apiVersion: v1

kind: ConfigMap

metadata:

name: custom-mig-config

namespace: gpu-operator

data:

config.yaml: |

version: v1

mig-configs:

MIG 비활성화

all-disabled:

- devices: all

mig-enabled: false

A100: 7개의 1g.10gb 인스턴스

all-1g.10gb:

- devices: all

mig-enabled: true

mig-devices:

"1g.10gb": 7

A100: 균형 잡힌 혼합 프로파일

balanced:

- devices: all

mig-enabled: true

mig-devices:

"1g.10gb": 2

"2g.20gb": 1

"3g.20gb": 1

H100: 추론 최적화 프로파일

h100-inference:

- devices: all

mig-enabled: true

mig-devices:

"1g.10gb": 4

"3g.40gb": 1

**MIG 리소스 요청 예시:**

apiVersion: v1

kind: Pod

metadata:

name: mig-workload

spec:

containers:

- name: cuda-app

image: nvcr.io/nvidia/cuda:12.6.0-base-ubuntu22.04

command: ['nvidia-smi']

resources:

limits:

nvidia.com/mig-1g.10gb: 1 # MIG 1g.10gb 인스턴스 1개 요청

4.3 vGPU (Virtual GPU)

NVIDIA vGPU는 GPU를 가상화하여 여러 가상 머신에서 공유하는 기술이다. 주로 **KubeVirt 가상 머신** 환경에서 사용되며, NVIDIA의 별도 라이선스(NVIDIA AI Enterprise 또는 vGPU 라이선스)가 필요하다.

**특징:**

- 하드웨어 수준 격리 (메모리, 연산)

- VM 환경에 최적화

- 라이선스 비용 발생

- vGPU Manager 설치 필요

4.4 GPU 공유 전략 비교

| 특성 | Time-Slicing | MIG | vGPU |

| ------------------- | ------------------------ | ------------------------- | --------------------------- |

| **격리 수준** | 없음 (시분할만) | 하드웨어 (메모리+연산) | 하드웨어 (가상화) |

| **메모리 격리** | X | O | O |

| **Fault Isolation** | X | O | O |

| **지원 GPU** | 모든 NVIDIA GPU | A100, A30, H100, H200 | vGPU 지원 GPU |

| **최대 분할 수** | 설정에 따라 무제한 | GPU별 상이 (최대 7) | GPU별 상이 |

| **성능 오버헤드** | Context Switching | 최소 | 가상화 오버헤드 |

| **라이선스** | 무료 | 무료 | 유료 (NVIDIA AI Enterprise) |

| **설정 복잡도** | 낮음 | 중간 | 높음 |

| **사용 사례** | 개발/테스트, 가벼운 추론 | 프로덕션 추론, 멀티테넌트 | VM 기반 워크로드 |

| **QoS 보장** | X | O | O |

5. KubeVirt와 GPU Operator 통합

5.1 KubeVirt 소개

**KubeVirt**는 Kubernetes 위에서 가상 머신(VM)을 관리할 수 있게 하는 프로젝트이다. 전통적인 VM 워크로드를 Kubernetes의 선언적 관리 체계 안에서 운영할 수 있으며, `VirtualMachine`과 `VirtualMachineInstance`라는 Custom Resource를 통해 VM을 관리한다.

KubeVirt와 GPU Operator를 통합하면, 가상 머신에 물리 GPU를 직접 할당(Passthrough)하거나 가상 GPU(vGPU)를 할당할 수 있다. 이는 다음과 같은 시나리오에서 유용하다:

- Windows VM에서 GPU 기반 렌더링/AI 워크로드 실행

- GPU 드라이버가 컨테이너 환경을 지원하지 않는 레거시 애플리케이션

- VM 수준의 보안 격리가 필요한 워크로드

- GPU 기반 VDI (Virtual Desktop Infrastructure)

**GPU Operator의 KubeVirt 워크로드 타입:**

┌─────────────────────────────────────────────────────────────────┐

│ GPU Operator Workload Types │

│ │

│ ┌──────────────┐ ┌──────────────────┐ ┌──────────────────┐ │

│ │ container │ │ vm-passthrough │ │ vm-vgpu │ │

│ │ (기본값) │ │ │ │ │ │

│ │ │ │ │ │ │ │

│ │ ▪ NVIDIA │ │ ▪ VFIO Manager │ │ ▪ vGPU Manager │ │

│ │ Driver │ │ ▪ Sandbox Device │ │ ▪ vGPU Device │ │

│ │ ▪ Container │ │ Plugin │ │ Manager │ │

│ │ Toolkit │ │ │ │ ▪ Sandbox Device │ │

│ │ ▪ Device │ │ │ │ Plugin │ │

│ │ Plugin │ │ │ │ │ │

│ │ ▪ DCGM │ │ │ │ │ │

│ └──────────────┘ └──────────────────┘ └──────────────────┘ │

│ │

│ nvidia.com/gpu.workload.config=container | vm-passthrough | │

│ vm-vgpu │

└─────────────────────────────────────────────────────────────────┘

> **중요:** 하나의 GPU 워커 노드는 한 가지 타입의 GPU 워크로드만 실행할 수 있다. container, vm-passthrough, vm-vgpu를 동일 노드에서 혼합 실행할 수 없다.

5.2 GPU Passthrough (PCI Passthrough)

GPU Passthrough는 물리 GPU 전체를 KubeVirt 가상 머신에 직접 할당하는 방식이다. VM 내부에서 GPU를 네이티브 성능으로 사용할 수 있지만, GPU 공유는 불가능하다.

5.2.1 Step 1: IOMMU/VT-d 활성화

**BIOS 설정:**

- Intel: VT-d (Intel Virtualization Technology for Directed I/O) 활성화

- AMD: AMD-Vi / IOMMU 활성화

**커널 파라미터 추가:**

Intel CPU

sudo sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="intel_iommu=on iommu=pt /' /etc/default/grub

AMD CPU

sudo sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="amd_iommu=on iommu=pt /' /etc/default/grub

GRUB 업데이트 및 재부팅

sudo update-grub

sudo reboot

IOMMU 활성화 확인

dmesg | grep -i iommu

출력 예: DMAR: IOMMU enabled

5.2.2 Step 2: VFIO 드라이버 모듈 로드

vfio-pci 모듈 로드

sudo modprobe vfio-pci

부팅 시 자동 로드 설정

echo "vfio-pci" | sudo tee /etc/modules-load.d/vfio-pci.conf

확인

lsmod | grep vfio

5.2.3 Step 3: GPU Operator 설치 (Sandbox Workloads 활성화)

GPU Operator 설치 시 sandboxWorkloads 활성화

helm install gpu-operator \

-n gpu-operator --create-namespace \

nvidia/gpu-operator \

--version=v25.10.1 \

--set sandboxWorkloads.enabled=true \

--set sandboxWorkloads.defaultWorkload=vm-passthrough

또는 기존 설치에 패치

kubectl patch clusterpolicies.nvidia.com/cluster-policy \

-n gpu-operator --type merge \

-p '{"spec": {"sandboxWorkloads": {"enabled": true, "defaultWorkload": "vm-passthrough"}}}'

5.2.4 Step 4: GPU 노드 라벨링

GPU Passthrough용 워커 노드 라벨링

kubectl label node <gpu-node> \

nvidia.com/gpu.workload.config=vm-passthrough --overwrite

라벨 확인

kubectl get node <gpu-node> -o jsonpath='{.metadata.labels.nvidia\.com/gpu\.workload\.config}'

출력: vm-passthrough

이 라벨을 적용하면 GPU Operator가 해당 노드에 NVIDIA Driver 대신 **VFIO Manager**와 **Sandbox Device Plugin**을 배포한다.

5.2.5 Step 5: GPU PCI ID 확인

GPU의 PCI Vendor/Device ID 확인

lspci -nn | grep -i nvidia

출력 예: 00:1e.0 3D controller [0302]: NVIDIA Corporation GA102GL [A10] [10DE:2236]

Vendor: 10DE, Device: 2236

IOMMU Group 확인

find /sys/kernel/iommu_groups/ -type l | sort -t '/' -k5 -n | \

while read line; do

echo "IOMMU Group $(echo $line | awk -F'/' '{print $5}'):"

lspci -nns $(basename $line)

done | grep -A1 NVIDIA

5.2.6 Step 6: KubeVirt CR에 GPU 디바이스 등록

kubevirt-cr-gpu-passthrough.yaml

apiVersion: kubevirt.io/v1

kind: KubeVirt

metadata:

name: kubevirt

namespace: kubevirt

spec:

configuration:

developerConfiguration:

featureGates:

- GPU

- DisableMDEVConfiguration

permittedHostDevices:

pciHostDevices:

- externalResourceProvider: true

pciVendorSelector: '10DE:2236' # NVIDIA A10

resourceName: nvidia.com/GA102GL_A10

kubectl apply -f kubevirt-cr-gpu-passthrough.yaml

5.2.7 Step 7: VirtualMachine에서 GPU 할당

vm-gpu-passthrough.yaml

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

name: gpu-vm

namespace: default

spec:

running: true

template:

metadata:

labels:

kubevirt.io/vm: gpu-vm

spec:

domain:

cpu:

cores: 4

memory:

guest: 16Gi

devices:

disks:

- name: rootdisk

disk:

bus: virtio

- name: cloudinitdisk

disk:

bus: virtio

gpus:

- deviceName: nvidia.com/GA102GL_A10

name: gpu1

resources:

requests:

memory: 16Gi

volumes:

- name: rootdisk

dataVolume:

name: ubuntu-dv

- name: cloudinitdisk

cloudInitNoCloud:

userData: |

#cloud-config

password: ubuntu

chpasswd: { expire: false }

ssh_pwauth: true

packages:

- build-essential

- linux-headers-$(uname -r)

runcmd:

- echo "GPU VM is ready"

kubectl apply -f vm-gpu-passthrough.yaml

VM 상태 확인

kubectl get vmi gpu-vm

VM 콘솔 접속

virtctl console gpu-vm

VM 내부에서 GPU 확인 (NVIDIA 드라이버 설치 후)

nvidia-smi

5.2.8 전체 GPU Passthrough 설정 플로우

┌─────────────────────────────────────────────────────────────────┐

│ GPU Passthrough 설정 전체 플로우 │

│ │

│ 1. BIOS: IOMMU/VT-d 활성화 │

│ │ │

│ ▼ │

│ 2. Kernel: intel_iommu=on iommu=pt │

│ │ │

│ ▼ │

│ 3. Module: vfio-pci 로드 │

│ │ │

│ ▼ │

│ 4. GPU Operator: sandboxWorkloads.enabled=true │

│ │ │

│ ▼ │

│ 5. Node Label: nvidia.com/gpu.workload.config=vm-passthrough │

│ │ │

│ ▼ │

│ 6. GPU Operator 자동 배포: │

│ ├── VFIO Manager (GPU를 vfio-pci에 바인딩) │

│ └── Sandbox Device Plugin (GPU 리소스 노출) │

│ │ │

│ ▼ │

│ 7. KubeVirt CR: permittedHostDevices에 GPU 등록 │

│ │ │

│ ▼ │

│ 8. VirtualMachine: spec.domain.devices.gpus 설정 │

│ │ │

│ ▼ │

│ 9. VM 내부: NVIDIA 드라이버 수동 설치 │

│ │ │

│ ▼ │

│ 10. nvidia-smi 확인 및 CUDA 워크로드 실행 │

└─────────────────────────────────────────────────────────────────┘

5.3 vGPU with KubeVirt

vGPU는 하나의 물리 GPU를 여러 개의 가상 GPU로 분할하여 여러 VM에서 공유하는 방식이다. GPU Passthrough와 달리 하나의 GPU를 여러 VM에서 동시에 사용할 수 있다.

5.3.1 사전 요구사항

- NVIDIA AI Enterprise 라이선스 또는 vGPU 라이선스

- vGPU를 지원하는 GPU (A100, A10, A30, A16, L40, L4, T4 등)

- Ampere 이상: SR-IOV 기반 vGPU

- Turing/Volta: NVIDIA vGPU Manager

5.3.2 vGPU Manager 이미지 빌드

NVIDIA vGPU Manager는 라이선스가 필요하여 공개 레지스트리에서 제공되지 않는다. NVIDIA Licensing Portal에서 vGPU 소프트웨어를 다운로드하고 컨테이너 이미지를 직접 빌드해야 한다.

1. NVIDIA Licensing Portal에서 vGPU Manager 다운로드

https://ui.licensing.nvidia.com/software

2. vGPU Manager 컨테이너 이미지 빌드

export PRIVATE_REGISTRY="registry.internal.company.com/nvidia"

export VGPU_HOST_DRIVER_VERSION="560.35.06"

export OS_TAG="ubuntu22.04"

GPU Operator 소스 클론

git clone https://github.com/NVIDIA/gpu-operator.git

cd gpu-operator

vGPU Manager 이미지 빌드

VGPU_HOST_DRIVER_VERSION=${VGPU_HOST_DRIVER_VERSION} \

IMAGE_NAME=${PRIVATE_REGISTRY}/vgpu-manager \

OS_TAG=${OS_TAG} \

make build-vgpu-manager

3. 이미지 Push

docker push ${PRIVATE_REGISTRY}/vgpu-manager:${VGPU_HOST_DRIVER_VERSION}-${OS_TAG}

5.3.3 GPU Operator에 vGPU 설정

Private Registry 접근을 위한 Secret 생성

kubectl create secret docker-registry vgpu-registry-secret \

-n gpu-operator \

--docker-server=${PRIVATE_REGISTRY} \

--docker-username=<username> \

--docker-password=<password>

vGPU 지원으로 GPU Operator 설치

helm install gpu-operator \

-n gpu-operator --create-namespace \

nvidia/gpu-operator \

--version=v25.10.1 \

--set sandboxWorkloads.enabled=true \

--set sandboxWorkloads.defaultWorkload=vm-vgpu \

--set vgpuManager.enabled=true \

--set vgpuManager.repository=${PRIVATE_REGISTRY} \

--set vgpuManager.image=vgpu-manager \

--set vgpuManager.version="${VGPU_HOST_DRIVER_VERSION}-${OS_TAG}" \

--set vgpuManager.imagePullSecrets[0]=vgpu-registry-secret

5.3.4 vGPU 타입 설정

vGPU 노드 라벨 설정

kubectl label node <gpu-node> \

nvidia.com/gpu.workload.config=vm-vgpu --overwrite

vGPU 프로파일 설정

kubectl label node <gpu-node> \

nvidia.com/vgpu.config=A10-4Q --overwrite

**사용 가능한 vGPU 타입 (A10 예시):**

| vGPU 타입 | 프레임버퍼 | 최대 인스턴스 | 사용 사례 |

| --------- | ---------- | ------------- | ---------------- |

| A10-1B | 1 GB | 16 | VDI (기본) |

| A10-2B | 2 GB | 8 | VDI (향상) |

| A10-1Q | 1 GB | 16 | 3D 디자인 (기본) |

| A10-2Q | 2 GB | 8 | 3D 디자인 |

| A10-4Q | 4 GB | 4 | AI/ML 추론 |

| A10-6Q | 6 GB | 3 | AI/ML 학습 |

| A10-8Q | 8 GB | 2 | 고성능 AI |

| A10-12Q | 12 GB | 1 | 최대 성능 |

| A10-4C | 4 GB | 4 | CUDA Compute |

| A10-6C | 6 GB | 3 | CUDA Compute |

| A10-8C | 8 GB | 2 | CUDA Compute |

**커스텀 vGPU 설정 ConfigMap:**

apiVersion: v1

kind: ConfigMap

metadata:

name: vgpu-devices-config

namespace: gpu-operator

data:

config.yaml: |

version: v1

vgpu-configs:

A10-4Q:

- devices: all

vgpu-devices:

"A10-4Q": 4

A10-mixed:

- devices: all

vgpu-devices:

"A10-4Q": 2

"A10-6Q": 1

A10-inference:

- devices: [0, 1]

vgpu-devices:

"A10-4Q": 4

- devices: [2, 3]

vgpu-devices:

"A10-8Q": 2

5.3.5 KubeVirt CR에 vGPU 등록

kubevirt-cr-vgpu.yaml

apiVersion: kubevirt.io/v1

kind: KubeVirt

metadata:

name: kubevirt

namespace: kubevirt

spec:

configuration:

developerConfiguration:

featureGates:

- GPU

- DisableMDEVConfiguration # GPU Operator가 mdev를 관리하므로 KubeVirt의 mdev 관리 비활성화

permittedHostDevices:

mediatedDevices:

- externalResourceProvider: true

mdevNameSelector: 'NVIDIA A10-4Q'

resourceName: nvidia.com/NVIDIA_A10-4Q

- externalResourceProvider: true

mdevNameSelector: 'NVIDIA A10-6Q'

resourceName: nvidia.com/NVIDIA_A10-6Q

- externalResourceProvider: true

mdevNameSelector: 'NVIDIA A10-8Q'

resourceName: nvidia.com/NVIDIA_A10-8Q

kubectl apply -f kubevirt-cr-vgpu.yaml

5.3.6 VirtualMachine에서 vGPU 할당

vm-vgpu.yaml

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

name: vgpu-vm

namespace: default

spec:

running: true

template:

metadata:

labels:

kubevirt.io/vm: vgpu-vm

spec:

domain:

cpu:

cores: 4

memory:

guest: 8Gi

devices:

disks:

- name: rootdisk

disk:

bus: virtio

gpus:

- deviceName: nvidia.com/NVIDIA_A10-4Q

name: vgpu1

resources:

requests:

memory: 8Gi

volumes:

- name: rootdisk

dataVolume:

name: ubuntu-dv

5.4 KubeVirt + GPU Operator ClusterPolicy 통합 설정

GPU Passthrough와 vGPU를 모두 지원하는 종합적인 ClusterPolicy 설정:

apiVersion: nvidia.com/v1

kind: ClusterPolicy

metadata:

name: cluster-policy

spec:

Container 워크로드용 드라이버 (container 노드에 배포)

driver:

enabled: true

version: '560.35.03'

Sandbox Workloads 활성화 (KubeVirt 연동 핵심)

sandboxWorkloads:

enabled: true

defaultWorkload: container # 기본은 container, 노드 라벨로 오버라이드

vGPU Manager (vm-vgpu 노드에 배포)

vgpuManager:

enabled: true

repository: 'registry.internal.company.com/nvidia'

image: vgpu-manager

version: '560.35.06-ubuntu22.04'

imagePullSecrets:

- vgpu-registry-secret

vGPU Device Manager

vgpuDeviceManager:

enabled: true

config:

name: 'vgpu-devices-config'

default: 'A10-4Q'

VFIO Manager (vm-passthrough 노드에 배포)

vfioManager:

enabled: true

Sandbox Device Plugin

sandboxDevicePlugin:

enabled: true

Container 워크로드 공통

toolkit:

enabled: true

devicePlugin:

enabled: true

dcgm:

enabled: true

dcgmExporter:

enabled: true

gfd:

enabled: true

nodeFeatureDiscovery:

enabled: true

**노드 라벨링으로 워크로드 타입 지정:**

Container 워크로드용 GPU 노드

kubectl label node gpu-worker-1 nvidia.com/gpu.workload.config=container

GPU Passthrough용 GPU 노드

kubectl label node gpu-worker-2 nvidia.com/gpu.workload.config=vm-passthrough

vGPU용 GPU 노드

kubectl label node gpu-worker-3 nvidia.com/gpu.workload.config=vm-vgpu

5.5 VM 내부에서 GPU 사용 확인

GPU Passthrough 또는 vGPU가 할당된 VM 내부에서 NVIDIA 드라이버를 설치하고 GPU 사용을 확인한다.

> **주의:** GPU Operator는 KubeVirt VM 내부에 NVIDIA 드라이버를 자동 설치하지 않는다. VM 내부의 드라이버는 사용자가 직접 설치해야 한다.

VM 콘솔 접속

virtctl console gpu-vm

VM 내부에서 NVIDIA 드라이버 설치 (Ubuntu)

sudo apt-get update

sudo apt-get install -y linux-headers-$(uname -r)

GPU Passthrough의 경우: 데이터센터 드라이버 설치

wget https://us.download.nvidia.com/tesla/560.35.03/NVIDIA-Linux-x86_64-560.35.03.run

sudo bash NVIDIA-Linux-x86_64-560.35.03.run --silent

vGPU의 경우: vGPU Guest 드라이버 설치 (NVIDIA Licensing Portal에서 다운로드)

sudo bash NVIDIA-Linux-x86_64-560.35.06-grid.run --silent

GPU 확인

nvidia-smi

CUDA 워크로드 테스트

sudo apt-get install -y nvidia-cuda-toolkit

cat <<'EOF' > hello_cuda.cu

#include <stdio.h>

__global__ void hello() { printf("Hello from GPU!\n"); }

int main() { hello<<<1,1>>>(); cudaDeviceSynchronize(); return 0; }

EOF

nvcc hello_cuda.cu -o hello_cuda

./hello_cuda

출력: Hello from GPU!

5.6 Live Migration with GPU 제약사항

KubeVirt는 VM의 Live Migration(무중단 이전)을 지원하지만, GPU가 할당된 VM에는 다음과 같은 제약이 있다:

| 제약사항 | GPU Passthrough | vGPU |

| ------------------ | ----------------------------------- | ----------------------------------- |

| **Live Migration** | 지원 안 됨 | 제한적 지원 (NVIDIA vGPU Migration) |

| **원인** | PCIe 디바이스 직접 할당은 이전 불가 | vGPU 상태 전송이 필요 |

| **대안** | Cold Migration (VM 중지 후 이전) | NVIDIA vGPU Migration 라이선스 필요 |

| **Node Drain** | evictionStrategy 설정 필요 | evictionStrategy 설정 필요 |

GPU VM의 evictionStrategy 설정

apiVersion: kubevirt.io/v1

kind: VirtualMachine

metadata:

name: gpu-vm

spec:

template:

spec:

evictionStrategy: None # GPU VM은 Live Migration 불가이므로 None 또는 External

domain:

devices:

gpus:

- deviceName: nvidia.com/GA102GL_A10

name: gpu1

6. 모니터링 및 Observability

6.1 DCGM Exporter -> Prometheus -> Grafana 파이프라인

┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐

│ GPU Node #1 │ │ GPU Node #2 │ │ GPU Node #3 │

│ │ │ │ │ │

│ ┌─────────────┐ │ │ ┌─────────────┐ │ │ ┌─────────────┐ │

│ │DCGM Exporter│ │ │ │DCGM Exporter│ │ │ │DCGM Exporter│ │

│ │ :9400 │ │ │ │ :9400 │ │ │ │ :9400 │ │

│ └──────┬──────┘ │ │ └──────┬──────┘ │ │ └──────┬──────┘ │

└────────┼────────┘ └────────┼────────┘ └────────┼────────┘

│ │ │

└───────────┬───────────┘───────────────────────┘

┌──────────────────┐

│ Prometheus │

│ (ServiceMonitor) │

│ scrape :9400 │

└────────┬─────────┘

┌──────────────────┐

│ Grafana │

│ Dashboard #12239│

│ (NVIDIA DCGM │

│ Exporter) │

└──────────────────┘

6.2 주요 GPU 메트릭 테이블

| 카테고리 | 메트릭 이름 | 설명 | 타입 | 임계값 (예시) |

| ------------ | -------------------------------- | -------------------------- | ------- | ---------------------------- |

| **연산** | `DCGM_FI_DEV_GPU_UTIL` | GPU 코어 사용률 | gauge | 경고: 90% 초과 |

| **연산** | `DCGM_FI_DEV_SM_CLOCK` | SM 클럭 주파수 (MHz) | gauge | - |

| **메모리** | `DCGM_FI_DEV_MEM_COPY_UTIL` | 메모리 대역폭 사용률 | gauge | 경고: 95% 초과 |

| **메모리** | `DCGM_FI_DEV_FB_FREE` | 사용 가능 프레임버퍼 (MiB) | gauge | 경고: 1024 미만 |

| **메모리** | `DCGM_FI_DEV_FB_USED` | 사용 중 프레임버퍼 (MiB) | gauge | - |

| **온도** | `DCGM_FI_DEV_GPU_TEMP` | GPU 온도 (C) | gauge | 경고: 85 초과, 위험: 90 초과 |

| **전력** | `DCGM_FI_DEV_POWER_USAGE` | 전력 소비 (W) | gauge | 경고: TDP의 90% 초과 |

| **에러** | `DCGM_FI_DEV_XID_ERRORS` | XID 에러 수 | counter | 경고: 0 초과 |

| **에러** | `DCGM_FI_DEV_ECC_SBE_VOL_TOTAL` | Single-bit ECC 에러 | counter | 경고: 100 초과 |

| **에러** | `DCGM_FI_DEV_ECC_DBE_VOL_TOTAL` | Double-bit ECC 에러 | counter | 위험: 0 초과 |

| **PCIe** | `DCGM_FI_DEV_PCIE_TX_THROUGHPUT` | PCIe 송신 (KB/s) | gauge | - |

| **PCIe** | `DCGM_FI_DEV_PCIE_RX_THROUGHPUT` | PCIe 수신 (KB/s) | gauge | - |

| **인코더** | `DCGM_FI_DEV_ENC_UTIL` | 인코더 사용률 | gauge | - |

| **디코더** | `DCGM_FI_DEV_DEC_UTIL` | 디코더 사용률 | gauge | - |

| **프로세스** | `DCGM_FI_DEV_GPU_UTIL_SAMPLES` | GPU 사용률 샘플 수 | counter | - |

6.3 ServiceMonitor 설정

Prometheus Operator와 연동하기 위한 ServiceMonitor 설정:

servicemonitor-dcgm.yaml

apiVersion: monitoring.coreos.com/v1

kind: ServiceMonitor

metadata:

name: nvidia-dcgm-exporter

namespace: gpu-operator

labels:

app: nvidia-dcgm-exporter

release: prometheus # Prometheus Operator의 serviceMonitorSelector에 맞춰야 함

spec:

selector:

matchLabels:

app: nvidia-dcgm-exporter

namespaceSelector:

matchNames:

- gpu-operator

endpoints:

- port: gpu-metrics

interval: 15s

honorLabels: true

path: /metrics

relabelings:

- sourceLabels: [__meta_kubernetes_pod_node_name]

targetLabel: node

- sourceLabels: [__meta_kubernetes_namespace]

targetLabel: namespace

**ClusterPolicy에서 ServiceMonitor 자동 생성:**

spec:

dcgmExporter:

enabled: true

serviceMonitor:

enabled: true

interval: '15s'

honorLabels: true

additionalLabels:

release: prometheus # Prometheus Operator 라벨 매칭

6.4 Grafana 대시보드

Grafana에서 NVIDIA DCGM Exporter 공식 대시보드를 사용할 수 있다.

**대시보드 Import:**

1. Grafana 웹 UI 접속

2. **Dashboards** > **Import** 클릭

3. Dashboard ID `12239` 입력 (NVIDIA DCGM Exporter Dashboard)

4. Prometheus 데이터 소스 선택

5. **Import** 클릭

**대시보드에서 표시되는 주요 패널:**

- GPU 사용률 (%) - 시계열 그래프

- GPU 메모리 사용량 (MiB) - 시계열 그래프

- GPU 온도 (C) - 게이지

- 전력 소비 (W) - 시계열 그래프

- PCIe 처리량 - 시계열 그래프

- ECC 에러 카운트 - 카운터 패널

- GPU별 상세 정보 테이블

6.5 Alert 규칙 예제

gpu-alerts.yaml

apiVersion: monitoring.coreos.com/v1

kind: PrometheusRule

metadata:

name: gpu-alerts

namespace: gpu-operator

labels:

release: prometheus

spec:

groups:

- name: gpu-health

rules:

GPU 온도 경고 (85도 이상)

- alert: GPUTemperatureHigh

expr: DCGM_FI_DEV_GPU_TEMP > 85

for: 5m

labels:

severity: warning

annotations:

summary: 'GPU 온도 경고 ({{ $labels.gpu }})'

description: >

노드 {{ $labels.node }}의 GPU {{ $labels.gpu }}

온도가 {{ $value }}C입니다. (임계값: 85C)

GPU 온도 위험 (90도 이상)

- alert: GPUTemperatureCritical

expr: DCGM_FI_DEV_GPU_TEMP > 90

for: 2m

labels:

severity: critical

annotations:

summary: 'GPU 온도 위험 ({{ $labels.gpu }})'

description: >

노드 {{ $labels.node }}의 GPU {{ $labels.gpu }}

온도가 {{ $value }}C입니다. 즉시 확인이 필요합니다.

GPU 메모리 부족 경고

- alert: GPUMemoryAlmostFull

expr: (DCGM_FI_DEV_FB_USED / (DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE)) * 100 > 95

for: 5m

labels:

severity: warning

annotations:

summary: 'GPU 메모리 부족 ({{ $labels.gpu }})'

description: >

노드 {{ $labels.node }}의 GPU {{ $labels.gpu }}

메모리 사용률이 {{ $value | printf "%.1f" }}%입니다.

Double-bit ECC 에러 발생 (즉시 경고)

- alert: GPUDoublebitECCError

expr: DCGM_FI_DEV_ECC_DBE_VOL_TOTAL > 0

for: 0m

labels:

severity: critical

annotations:

summary: 'GPU Double-bit ECC 에러 ({{ $labels.gpu }})'

description: >

노드 {{ $labels.node }}의 GPU {{ $labels.gpu }}에서

교정 불가능한 Double-bit ECC 에러가 감지되었습니다.

GPU 하드웨어 교체를 검토하세요.

GPU 사용률 장기 과부하

- alert: GPUHighUtilization

expr: DCGM_FI_DEV_GPU_UTIL > 95

for: 30m

labels:

severity: warning

annotations:

summary: 'GPU 장기 과부하 ({{ $labels.gpu }})'

description: >

노드 {{ $labels.node }}의 GPU {{ $labels.gpu }}가

30분 이상 95% 이상 사용률을 유지하고 있습니다.

XID 에러 발생

- alert: GPUXidError

expr: increase(DCGM_FI_DEV_XID_ERRORS[5m]) > 0

for: 0m

labels:

severity: warning

annotations:

summary: 'GPU XID 에러 발생 ({{ $labels.gpu }})'

description: >

노드 {{ $labels.node }}의 GPU {{ $labels.gpu }}에서

XID 에러가 발생했습니다. dmesg 로그를 확인하세요.

- name: gpu-operator-health

rules:

GPU Operator Pod 비정상

- alert: GPUOperatorPodNotReady

expr: |

kube_pod_status_ready{namespace="gpu-operator", condition="true"} == 0

for: 10m

labels:

severity: warning

annotations:

summary: 'GPU Operator Pod 비정상'

description: >

GPU Operator 네임스페이스의 {{ $labels.pod }}

Pod이 10분 이상 Ready 상태가 아닙니다.

kubectl apply -f gpu-alerts.yaml

7. 프로덕션 배포 베스트 프랙티스

7.1 Node Labeling 전략 (GPU 노드 vs CPU 노드)

프로덕션 환경에서는 GPU 노드와 CPU 노드를 명확히 구분하여 관리해야 한다.

GPU 노드 라벨링

kubectl label node gpu-worker-{1..4} \

node-role.kubernetes.io/gpu-worker=""

GPU 용도별 라벨링

kubectl label node gpu-worker-1 gpu-workload=training

kubectl label node gpu-worker-2 gpu-workload=training

kubectl label node gpu-worker-3 gpu-workload=inference

kubectl label node gpu-worker-4 gpu-workload=inference

GPU 세대별 라벨링 (GFD가 자동으로 하지만, 커스텀 라벨도 유용)

kubectl label node gpu-worker-1 gpu-tier=high # A100/H100

kubectl label node gpu-worker-3 gpu-tier=standard # T4/L4

7.2 Taints & Tolerations

GPU 노드에 Taint를 설정하여 GPU 워크로드만 스케줄링되도록 한다.

GPU 노드에 Taint 적용

kubectl taint nodes gpu-worker-{1..4} \

nvidia.com/gpu=present:NoSchedule

**GPU 워크로드 Pod에 Toleration 추가:**

apiVersion: v1

kind: Pod

metadata:

name: gpu-training

spec:

tolerations:

- key: nvidia.com/gpu

operator: Equal

value: present

effect: NoSchedule

nodeSelector:

nvidia.com/gpu.product: 'NVIDIA-A100-SXM4-40GB'

containers:

- name: training

image: my-training:latest

resources:

limits:

nvidia.com/gpu: 4

7.3 ResourceQuota로 GPU 할당량 제한

네임스페이스별로 GPU 사용량을 제한한다.

gpu-resourcequota.yaml

apiVersion: v1

kind: ResourceQuota

metadata:

name: gpu-quota

namespace: ml-team-a

spec:

hard:

requests.nvidia.com/gpu: '8' # 최대 GPU 8개 요청 가능

limits.nvidia.com/gpu: '8' # 최대 GPU 8개 제한

pods: '20' # 최대 Pod 20개

apiVersion: v1

kind: ResourceQuota

metadata:

name: gpu-quota

namespace: ml-team-b

spec:

hard:

requests.nvidia.com/gpu: '4'

limits.nvidia.com/gpu: '4'

pods: '10'

kubectl apply -f gpu-resourcequota.yaml

할당량 확인

kubectl get resourcequota -n ml-team-a

NAME AGE REQUEST LIMIT

gpu-quota 1m requests.nvidia.com/gpu: 2/8 limits.nvidia.com/gpu: 2/8

7.4 PriorityClass 설정

GPU 리소스 부족 시 우선순위가 낮은 워크로드를 Preemption(선점)하기 위해 PriorityClass를 설정한다.

gpu-priority-classes.yaml

프로덕션 학습 작업 (최고 우선순위)

apiVersion: scheduling.k8s.io/v1

kind: PriorityClass

metadata:

name: gpu-production-training

value: 1000000

globalDefault: false

description: '프로덕션 GPU 학습 워크로드'

프로덕션 추론 서비스

apiVersion: scheduling.k8s.io/v1

kind: PriorityClass

metadata:

name: gpu-production-inference

value: 900000

globalDefault: false

description: '프로덕션 GPU 추론 서비스'

개발/실험 워크로드 (낮은 우선순위)

apiVersion: scheduling.k8s.io/v1

kind: PriorityClass

metadata:

name: gpu-development

value: 100000

globalDefault: false

preemptionPolicy: Never # 다른 Pod을 선점하지 않음

description: '개발/실험 GPU 워크로드'

PriorityClass 사용 예시

apiVersion: v1

kind: Pod

metadata:

name: important-training

spec:

priorityClassName: gpu-production-training

containers:

- name: training

image: my-training:latest

resources:

limits:

nvidia.com/gpu: 4

7.5 드라이버 업그레이드 전략

GPU Operator는 드라이버 업그레이드를 위한 Rolling Update를 지원한다.

1. 현재 드라이버 버전 확인

kubectl get clusterpolicy cluster-policy -o jsonpath='{.spec.driver.version}'

2. 드라이버 버전 업그레이드

kubectl patch clusterpolicies.nvidia.com/cluster-policy \

--type merge \

-p '{"spec": {"driver": {"version": "565.57.01"}}}'

3. 업그레이드 진행 상태 확인

kubectl get pods -n gpu-operator -l app=nvidia-driver-daemonset -w

4. 노드별 업그레이드 완료 확인

kubectl get nodes -o custom-columns=\

'NAME:.metadata.name,DRIVER:.metadata.labels.nvidia\.com/cuda\.driver\.major'

**업그레이드 시 주의사항:**

- `ENABLE_AUTO_DRAIN=true` 설정 시 드라이버 업그레이드 전 자동으로 노드를 드레인한다

- 프로덕션 환경에서는 한 번에 한 노드씩 업그레이드하도록 `maxUnavailable: 1`을 설정한다

- 업그레이드 전 GPU 워크로드의 Checkpoint/저장 상태를 확인한다

7.6 Multi-GPU 노드 관리

DGX 같은 Multi-GPU 서버에서는 NVIDIA Fabric Manager와 NVLink/NVSwitch 설정도 고려해야 한다.

Multi-GPU 노드 스케줄링을 위한 Topology 인식

apiVersion: v1

kind: Pod

metadata:

name: multi-gpu-training

spec:

containers:

- name: training

image: nvcr.io/nvidia/pytorch:24.05-py3

env:

- name: NVIDIA_VISIBLE_DEVICES

value: 'all'

- name: NCCL_P2P_LEVEL

value: 'NVL' # NVLink 사용

- name: NCCL_TOPO_DUMP_FILE

value: '/tmp/nccl_topo.xml'

resources:

limits:

nvidia.com/gpu: 8 # 8-GPU 학습

8. 트러블슈팅 가이드

8.1 GPU not detected (드라이버 로딩 실패)

**증상:** `nvidia-driver-daemonset` Pod이 CrashLoopBackOff 또는 Error 상태

1. Driver Pod 로그 확인

kubectl logs -n gpu-operator -l app=nvidia-driver-daemonset --tail=100

2. Nouveau 모듈 충돌 확인

kubectl exec -n gpu-operator -it <driver-pod> -- lsmod | grep nouveau

해결: nouveau 블랙리스트

cat <<EOF | sudo tee /etc/modprobe.d/blacklist-nouveau.conf

blacklist nouveau

options nouveau modeset=0

EOF

sudo update-initramfs -u && sudo reboot

3. 커널 헤더 누락 확인

kubectl logs -n gpu-operator <driver-pod> | grep "kernel headers"

해결: 커널 헤더 설치

sudo apt-get install -y linux-headers-$(uname -r)

4. dmesg에서 GPU 관련 에러 확인

dmesg | grep -i "NVRM\|nvidia\|Xid"

5. GPU 하드웨어 인식 확인

lspci | grep -i nvidia

8.2 nvidia-smi not found in container

**증상:** 컨테이너 내부에서 `nvidia-smi` 명령어를 찾을 수 없음

1. Container Toolkit Pod 상태 확인

kubectl get pods -n gpu-operator -l app=nvidia-container-toolkit-daemonset

2. Device Plugin Pod 상태 확인

kubectl get pods -n gpu-operator -l app=nvidia-device-plugin-daemonset

3. 노드의 GPU 리소스 확인

kubectl describe node <node> | grep "nvidia.com/gpu"

nvidia.com/gpu가 0이면 Device Plugin 문제

4. Pod의 GPU 리소스 요청 확인

kubectl get pod <pod-name> -o yaml | grep -A5 resources

limits에 nvidia.com/gpu가 있는지 확인

5. CDI 설정 확인

kubectl exec -n gpu-operator -it <toolkit-pod> -- \

ls /var/run/cdi/

8.3 CUDA version mismatch

**증상:** CUDA 애플리케이션 실행 시 "CUDA driver version is insufficient" 에러

1. 드라이버의 CUDA 지원 버전 확인

kubectl exec -n gpu-operator -it <driver-pod> -- nvidia-smi

출력의 "CUDA Version" 확인

2. 컨테이너 이미지의 CUDA 버전 확인

kubectl exec -it <app-pod> -- nvcc --version

3. 호환성 확인

드라이버 CUDA 버전 >= 애플리케이션 CUDA 버전이어야 함

예: 드라이버 CUDA 12.6 >= 애플리케이션 CUDA 12.4 (OK)

드라이버 CUDA 12.2 < 애플리케이션 CUDA 12.6 (FAIL)

해결: 드라이버 업그레이드 또는 애플리케이션 CUDA 버전 다운그레이드

8.4 MIG partition 실패

**증상:** `nvidia.com/mig.config.state=failed` 라벨

1. MIG Manager 로그 확인

kubectl logs -n gpu-operator -l app=nvidia-mig-manager --tail=100

2. MIG 상태 확인 (노드에서)

nvidia-smi mig -lgi

nvidia-smi mig -lci

3. GPU에서 실행 중인 프로세스 확인

nvidia-smi pmon -s u -d 1 -c 1

4. MIG 모드 활성화 확인

nvidia-smi -i 0 --query-gpu=mig.mode.current --format=csv

"Enabled"여야 함

5. MIG 설정 재시도

kubectl label node <node> nvidia.com/mig.config=all-disabled --overwrite

잠시 대기 후

kubectl label node <node> nvidia.com/mig.config=all-1g.10gb --overwrite

6. 리부트가 필요한 경우 (특히 클라우드 환경)

ClusterPolicy에서 WITH_REBOOT=true 설정

kubectl patch clusterpolicies.nvidia.com/cluster-policy \

--type merge \

-p '{"spec":{"migManager":{"env":[{"name":"WITH_REBOOT","value":"true"}]}}}'

8.5 KubeVirt VM에서 GPU 인식 안 됨

**증상:** VM 내부에서 `lspci | grep NVIDIA` 출력이 없음

1. 노드 워크로드 라벨 확인

kubectl get node <node> -o jsonpath='{.metadata.labels.nvidia\.com/gpu\.workload\.config}'

vm-passthrough 또는 vm-vgpu여야 함

2. VFIO Manager 또는 vGPU Manager 상태 확인

kubectl get pods -n gpu-operator | grep -E "vfio|vgpu"

3. Sandbox Device Plugin 상태 확인

kubectl get pods -n gpu-operator -l app=nvidia-sandbox-device-plugin-daemonset

4. 노드의 GPU 리소스 확인

kubectl describe node <node> | grep nvidia.com

nvidia.com/GA102GL_A10 또는 nvidia.com/NVIDIA_A10-4Q 등이 있어야 함

5. KubeVirt CR의 permittedHostDevices 확인

kubectl get kubevirt kubevirt -n kubevirt -o yaml | grep -A20 permittedHostDevices

6. VMI 상태 확인

kubectl describe vmi <vm-name>

Events에 GPU 할당 관련 에러 확인

7. IOMMU 그룹 확인 (Passthrough의 경우)

IOMMU 그룹 내 모든 디바이스가 vfio-pci에 바인딩되어야 함

ls /sys/kernel/iommu_groups/*/devices/

8.6 DCGM Exporter 메트릭 누락

**증상:** Prometheus에서 DCGM 메트릭이 수집되지 않음

1. DCGM Exporter Pod 상태 확인

kubectl get pods -n gpu-operator -l app=nvidia-dcgm-exporter

2. DCGM Exporter 메트릭 직접 확인

kubectl port-forward -n gpu-operator svc/nvidia-dcgm-exporter 9400:9400

curl http://localhost:9400/metrics | head -50

3. ServiceMonitor 확인

kubectl get servicemonitor -n gpu-operator

kubectl describe servicemonitor nvidia-dcgm-exporter -n gpu-operator

4. Prometheus 타겟 확인

Prometheus UI > Status > Targets에서 dcgm-exporter 타겟 확인

상태가 "DOWN"이면 네트워크 또는 라벨 매칭 문제

5. ServiceMonitor 라벨이 Prometheus의 serviceMonitorSelector와 일치하는지 확인

kubectl get prometheus -n monitoring -o yaml | grep -A5 serviceMonitorSelector

6. DCGM Exporter 로그 확인

kubectl logs -n gpu-operator -l app=nvidia-dcgm-exporter --tail=50

8.7 진단 명령어 모음

═══════════════════════════════════════════════════════════

GPU Operator 전체 상태 점검 스크립트

═══════════════════════════════════════════════════════════

echo "=== 1. GPU Operator Pod 상태 ==="

kubectl get pods -n gpu-operator -o wide

echo ""

echo "=== 2. ClusterPolicy 상태 ==="

kubectl get clusterpolicy -o jsonpath='{.items[0].status.state}'

echo ""

echo ""

echo "=== 3. GPU 노드 라벨 ==="

kubectl get nodes -o custom-columns=\

'NAME:.metadata.name,GPU_PRESENT:.metadata.labels.feature\.node\.kubernetes\.io/pci-10de\.present,GPU_PRODUCT:.metadata.labels.nvidia\.com/gpu\.product,GPU_COUNT:.metadata.labels.nvidia\.com/gpu\.count,GPU_MEMORY:.metadata.labels.nvidia\.com/gpu\.memory,MIG_CONFIG:.metadata.labels.nvidia\.com/mig\.config,WORKLOAD:.metadata.labels.nvidia\.com/gpu\.workload\.config'

echo ""

echo "=== 4. GPU 리소스 할당 상태 ==="

kubectl describe nodes | grep -A6 "nvidia.com/gpu"

echo ""

echo "=== 5. Driver DaemonSet 상태 ==="

kubectl get ds -n gpu-operator nvidia-driver-daemonset -o wide 2>/dev/null || echo "Driver DaemonSet not found"

echo ""

echo "=== 6. 문제 있는 Pod 확인 ==="

kubectl get pods -n gpu-operator --field-selector=status.phase!=Running,status.phase!=Succeeded

echo ""

echo "=== 7. 최근 이벤트 ==="

kubectl get events -n gpu-operator --sort-by='.lastTimestamp' | tail -20

echo ""

echo "=== 8. Validator 로그 ==="

kubectl logs -n gpu-operator -l app=nvidia-operator-validator --tail=20 2>/dev/null

echo ""

echo "=== 9. ClusterPolicy 전체 설정 ==="

kubectl get clusterpolicy cluster-policy -o yaml

**개별 컴포넌트 디버깅:**

Driver 디버깅

kubectl logs -n gpu-operator -l app=nvidia-driver-daemonset -c nvidia-driver-ctr --tail=100

Toolkit 디버깅

kubectl logs -n gpu-operator -l app=nvidia-container-toolkit-daemonset --tail=100

Device Plugin 디버깅

kubectl logs -n gpu-operator -l app=nvidia-device-plugin-daemonset --tail=100

DCGM Exporter 디버깅

kubectl logs -n gpu-operator -l app=nvidia-dcgm-exporter --tail=100

MIG Manager 디버깅

kubectl logs -n gpu-operator -l app=nvidia-mig-manager --tail=100

Validator 디버깅

kubectl logs -n gpu-operator -l app=nvidia-operator-validator --tail=100

VFIO Manager 디버깅 (KubeVirt Passthrough)

kubectl logs -n gpu-operator -l app=nvidia-vfio-manager --tail=100

vGPU Manager 디버깅

kubectl logs -n gpu-operator -l app=nvidia-vgpu-manager-daemonset --tail=100

9. 참고 자료 (References)

공식 문서

| 리소스 | URL |

| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

| NVIDIA GPU Operator 공식 문서 | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/) |

| GPU Operator 설치 가이드 | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/getting-started.html](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/getting-started.html) |

| GPU Operator with KubeVirt | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-kubevirt.html](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-kubevirt.html) |

| GPU Time-Slicing 가이드 | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html) |

| GPU Operator MIG 가이드 | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-mig.html](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-mig.html) |

| GPU Operator 트러블슈팅 | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/troubleshooting.html](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/troubleshooting.html) |

| NVIDIA DCGM Exporter | [https://github.com/NVIDIA/dcgm-exporter](https://github.com/NVIDIA/dcgm-exporter) |

| NVIDIA MIG User Guide | [https://docs.nvidia.com/datacenter/tesla/mig-user-guide/index.html](https://docs.nvidia.com/datacenter/tesla/mig-user-guide/index.html) |

KubeVirt 관련

| 리소스 | URL |

| -------------------------- | ------------------------------------------------------------------------------------------------------------ |

| KubeVirt 공식 문서 | [https://kubevirt.io/user-guide/](https://kubevirt.io/user-guide/) |

| KubeVirt Host Devices | [https://kubevirt.io/user-guide/compute/host-devices/](https://kubevirt.io/user-guide/compute/host-devices/) |

| KubeVirt GPU Device Plugin | [https://github.com/NVIDIA/kubevirt-gpu-device-plugin](https://github.com/NVIDIA/kubevirt-gpu-device-plugin) |

추가 리소스

| 리소스 | URL |

| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

| GPU Operator GitHub | [https://github.com/NVIDIA/gpu-operator](https://github.com/NVIDIA/gpu-operator) |

| NVIDIA NGC GPU Operator Helm Chart | [https://catalog.ngc.nvidia.com/orgs/nvidia/helm-charts/gpu-operator](https://catalog.ngc.nvidia.com/orgs/nvidia/helm-charts/gpu-operator) |

| DCGM Exporter Grafana Dashboard | [https://grafana.com/grafana/dashboards/12239](https://grafana.com/grafana/dashboards/12239) |

| NVIDIA GPU Telemetry 문서 | [https://docs.nvidia.com/datacenter/cloud-native/gpu-telemetry/latest/](https://docs.nvidia.com/datacenter/cloud-native/gpu-telemetry/latest/) |

| GPU Operator Platform Support | [https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/platform-support.html](https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/platform-support.html) |

현재 단락 (1/1434)

NVIDIA GPU Operator는 Kubernetes 클러스터에서 GPU를 활용하기 위해 필요한 **모든 소프트웨어 컴포넌트의 설치, 설정, 관리를 자동화**하는 Kuberne...

작성 글자: 0원문 글자: 52,173작성 단락: 0/1434