26Z29e

QK·2026년 8월 28일

네. 이번에는 현재 실제 구축 대상을 기준으로 꽤 구체적으로 잡는 게 좋습니다.

기준 환경을 다음처럼 고정하겠습니다.

Kubernetes        1.33
Node OS            RHEL 10.2
GPU                NVIDIA B300 x 8
GPU Node           Bare-metal
NIC                Intel E810
NIC driver         ice
RDMA driver        irdma
Network            bond0 / bond1
bond0              External
bond1              K8s internal + RoCEv2
CNI                Cilium
GPU Operator       26.7.0
Container Runtime  containerd
Storage            별도 K8s cluster의 MinIO AIStor
Network Operator   현재는 설치하지 않음

현재 NVIDIA 공식 문서상 GPU Operator 26.7은 RHEL 10.0/10.1/10.2 + Kubernetes 1.33~1.36을 지원하고, DGX/HGX B300도 지원 GPU 목록에 포함됩니다. 따라서 OS/K8s/GPU 조합 자체는 공식 지원 범위입니다. (NVIDIA Docs)

그리고 중요한 전제 하나:

Intel E810은 GPU Operator가 관리하는 NIC가 아닙니다.

따라서 이번 설치에서 GPU Operator = GPU software stack, ice/irdma = OS/network stack으로 명확히 분리하는 것을 권장합니다.


1. 전체 설치 구조

최종적으로 GPU node는 다음과 같은 구조가 됩니다.

                         GPU Node
                 RHEL 10.2 / K8s 1.33
                         │
        ┌────────────────┴────────────────┐
        │                                 │
   NVIDIA GPU Stack                 Intel Network Stack
        │                                 │
  GPU Operator 26.7                    E810
        │                              │
  ┌─────┼──────────────┐              ice
  │     │              │              irdma
Driver  Toolkit     Device Plugin       │
  │     │              │                │
  │    CDI             │                │
  │                    │                │
DCGM/DCGM Exporter     │          RDMA subsystem
  │                    │                │
  └──────────┬─────────┘                │
             │                          │
          B300 x 8                      │
             │                          │
             └──────────────┬───────────┘
                            │
                         bond1
                            │
                     Cilium + RoCEv2
                            │
                            ▼
                         AIStor

그리고 NVIDIA Network Operator는 현재 E810 환경에서는 넣지 않습니다.


2. 먼저 매우 중요한 결정: GPU Driver를 누가 관리할 것인가?

GPU Operator 26.7에는 두 가지 방법이 있습니다.

방법 A — ClusterPolicy

GPU Operator
   ↓
ClusterPolicy
   ↓
Driver DaemonSet

방법 B — NVIDIADriver CRD

GPU Operator
   ↓
NVIDIADriver CR
   ↓
Driver

26.7에서는 NVIDIADriver CRD를 사용할 수 있고, 특정 node label을 기준으로 서로 다른 driver type/version을 관리할 수도 있습니다. (NVIDIA Docs)

현재는 A를 추천

GPU node가 처음에는 1대이고 B300 x8이라는 homogeneous GPU node라면:

일단 ClusterPolicy + Operator-managed driver

가 가장 단순합니다.

나중에 GPU node가 늘어나고 driver version을 node group별로 분리해야 할 필요가 생기면 NVIDIADriver CRD로 전환/확장하는 것이 좋습니다.


3. 설치 전에 반드시 해야 할 것

저라면 실제 작업을 다음 순서로 진행합니다.

STEP 0  Hardware 확인
STEP 1  RHEL 확인
STEP 2  Kernel 확인
STEP 3  containerd 확인
STEP 4  Kubernetes/Kubespray 확인
STEP 5  Cilium 확인
STEP 6  E810/ice/irdma 확인
STEP 7  bond1 확인
STEP 8  RDMA subsystem 확인
STEP 9  B300 PCIe/NVLink/NVSwitch 확인
STEP 10 BIOS 확인
STEP 11 IOMMU/NUMA 확인
STEP 12 OS package/repository 확인
STEP 13 Air-gap image/package 준비
STEP 14 Node label/taint
STEP 15 GPU Operator 설치
STEP 16 Driver 확인
STEP 17 GPU device plugin 확인
STEP 18 CDI 확인
STEP 19 CUDA test
STEP 20 DCGM/Prometheus 확인
STEP 21 RDMA device plugin
STEP 22 RDMA test

4. STEP 0 — Hardware inventory

GPU node에서 가장 먼저:

hostnamectl
dmidecode -t system
dmidecode -t baseboard
dmidecode -t processor

CPU:

lscpu
numactl -H

PCIe:

lspci -nn
lspci -tv

GPU만:

lspci -nn | grep -i nvidia

NIC:

lspci -nn | grep -Ei 'ethernet|network'

E810:

lspci -nn | grep -i 'Intel.*Ethernet'

5. B300 8장의 PCIe 위치가 중요

8-GPU node라면 단순히:

nvidia-smi

만 확인하면 안 됩니다.

반드시:

nvidia-smi topo -m

를 확인하세요.

예를 들어:

        GPU0 GPU1 GPU2 GPU3 GPU4 GPU5 GPU6 GPU7 NIC0
GPU0     X   NV   NV   NV   SYS  ...
...
NIC0    ...

여기서 NIC가 어느 GPU와 PCIe/NUMA locality를 가지는지가 나중의 GPUDirect RDMA 성능에 매우 중요합니다.

추가:

nvidia-smi topo -m
nvidia-smi -q -i 0

8장 모두:

for i in {0..7}; do
    echo "===== GPU $i ====="
    nvidia-smi -i $i --query-gpu=name,pci.bus_id,uuid,memory.total --format=csv
done

6. HGX B300인지 확인

여기서 한 가지 중요합니다.

사용자가 말한 "B300 8장"이 일반적인 PCIe GPU 8장이 아니라 HGX B300 8-GPU platform이라면 NVSwitch/NVLink topology가 추가됩니다.

확인:

nvidia-smi -q | grep -Ei 'NVSwitch|NVLink'

그리고:

nvidia-smi topo -m

에서 NVLink/NVSwitch 구조를 기록합니다.

이 경우 GPU Operator 설치 자체는 크게 달라지지 않지만, GPU-to-GPU 성능 테스트는 별도의 NVLink/NVSwitch validation이 필요합니다.


7. STEP 1 — RHEL 10.2 확인

cat /etc/redhat-release

cat /etc/os-release

uname -r

uname -m

예상:

Red Hat Enterprise Linux 10.2
x86_64

NVIDIA 공식 support matrix에서 RHEL 10.2 + Kubernetes 1.33은 지원됩니다. (NVIDIA Docs)


8. Kernel 확인

uname -r

rpm -q kernel
rpm -q kernel-core
rpm -q kernel-devel
rpm -q kernel-headers

현재 실행 중 kernel과 development package가 일치해야 합니다.

KVER=$(uname -r)

rpm -q kernel-devel-${KVER}
rpm -q kernel-headers-${KVER}

여기서 실패하면 GPU Operator driver 설치 전에 해결합니다.


9. GCC 확인

GPU driver container가 host kernel module을 build해야 할 경우 중요합니다.

gcc --version
rpm -q gcc

그리고:

rpm -q kernel-devel
rpm -q kernel-headers

RHEL air-gapped 환경에서는 NVIDIA driver container가 필요한 OS package를 가져올 수 있도록 local repository를 준비해야 합니다. NVIDIA 문서가 RHEL 계열에서 필요한 주요 패키지로 kernel-headers, kernel-devel, kernel-core, gcc를 명시합니다. (NVIDIA Docs)


10. STEP 2 — containerd 확인

이건 이번에 반드시 확인해야 합니다.

containerd --version

그리고:

crictl info | jq '.config.containerdEndpoint // .config'

Kubelet:

ps -ef | grep kubelet

GPU Operator 26.7의 공식 지원 runtime 표는 containerd 2.0~2.3을 대상으로 합니다. (NVIDIA Docs)

따라서 만약:

containerd 1.7.x

이면 저는 GPU Operator 설치를 바로 진행하지 않고 containerd부터 정리하겠습니다.

특히 현재 Kubespray에서 containerd 1.x를 사용 중이라면 이 부분이 가장 먼저 확인할 항목입니다.


11. containerd 설정 백업

설치 전:

cp -a /etc/containerd/config.toml \
      /etc/containerd/config.toml.$(date +%Y%m%d)

확인:

containerd config dump | less

그리고 GPU Operator 26.7에서는 CDI가 기본 활성화됩니다. CDI가 container runtime의 native CDI support를 통해 GPU를 container에 주입하는 구조입니다. (NVIDIA Docs)

따라서 containerd의 CDI 관련 동작도 확인해야 합니다.


12. NRI는 처음에는 사용하지 마세요

GPU Operator 26.7에서는 NRI plugin도 지원하지만 NVIDIA 문서상 아직 GA가 아니고 production 사용을 권장하지 않습니다. (NVIDIA Docs)

따라서:

cdi:
  enabled: true
  nriPluginEnabled: false

방향을 권장합니다.

즉:

CDI       ON
NRI       OFF

13. STEP 3 — Kubernetes 확인

kubectl version

Node:

kubectl get nodes -o wide

GPU node가 추가된 후:

kubectl get node <gpu-node> --show-labels

그리고:

kubectl describe node <gpu-node>

에서:

OS Image
Kernel Version
Container Runtime
Kubelet Version
Capacity
Allocatable

을 기록합니다.


14. Kubespray 설정 확인

Kubespray inventory에서 GPU node가 기존 cluster에 정상적으로 들어갔는지 확인합니다.

특히:

container_manager
kube_version
kubelet_config_extra_args

그리고 GPU node에만 적용되는 host configuration이 있는지 확인합니다.

가능하면 GPU node를:

gpu_workers

같은 별도 inventory group으로 관리하세요.

예:

[all]
...
gpu01

[kube_node]
...
gpu01

[gpu_workers]
gpu01

향후:

gpu01
gpu02
gpu03
...

확장이 편해집니다.


15. STEP 4 — Cilium 확인

현재 Cilium을 사용하므로:

cilium status

또는:

kubectl -n kube-system get pods -l k8s-app=cilium -o wide

Cilium version:

cilium version

확인합니다.

그리고 GPU node에서 Cilium agent가 정상인지:

kubectl -n kube-system get pod \
  -l k8s-app=cilium \
  -o wide | grep <gpu-node>

16. bond0 / bond1 확인

cat /proc/net/bonding/bond0
cat /proc/net/bonding/bond1

특히 bond1:

cat /proc/net/bonding/bond1

에서:

Bonding Mode
802.3ad
LACP rate
MII Status
Slave Interface
Aggregator ID
Actor Key
Partner Key

을 기록합니다.

사용자가 말한 것처럼 LACP active-active라면 RDMA와 bonding의 compatibility를 별도로 검증해야 합니다.


17. E810 확인

인터페이스 이름:

ip -br link

예:

eno1
eno2
bond0
bond1

E810 확인:

ethtool -i <e810-port>

중요:

driver: ice
firmware-version:
bus-info:

확인.


18. ice module

modinfo ice | head -30
lsmod | grep '^ice'

필요하면:

modprobe ice

19. irdma 확인

modinfo irdma | head -30

lsmod | grep irdma

로드:

modprobe irdma

확인:

lsmod | grep -E 'ice|irdma'

20. RDMA subsystem

패키지:

rpm -qa | grep -E 'rdma|libibverbs|perftest'

서비스:

systemctl status rdma

장치:

rdma link
rdma dev
ibv_devices
ibv_devinfo

정상이라면 E810의 RDMA device가 보여야 합니다.


21. 여기서 중요한 테스트

GPU Operator 설치 전에 RDMA가 먼저 정상이어야 합니다.

즉:

GPU Operator
        X

먼저

RHEL
 └─ ice
     └─ irdma
         └─ RDMA device

가 정상이어야 합니다.

왜냐하면 GPU Operator가 실패한 것인지 E810 RDMA가 원래 안 되는 것인지 분리해야 하기 때문입니다.


22. STEP 5 — RDMA basic test

가능하다면 E810이 연결된 다른 RDMA node와:

ib_write_bw

를 수행합니다.

예:

Server:

ib_write_bw -d <rdma_device>

Client:

ib_write_bw -d <rdma_device> <server-ip>

이 단계에서 PASS해야 합니다.


23. STEP 6 — BIOS 확인

8-GPU B300 node에서는 BIOS 설정도 상당히 중요합니다.

확인 대상:

Above 4G Decoding
Resizable BAR
SR-IOV
IOMMU
NUMA
PCIe Link Speed
PCIe ASPM
CPU C-states

특히 GPU가 8장인 경우:

Above 4G Decoding = Enabled

는 사실상 필수로 보는 것이 좋습니다.


24. IOMMU

확인:

cat /proc/cmdline

그리고:

dmesg | grep -Ei 'iommu|DMAR'

BIOS에서 IOMMU가 필요한 architecture인지 확인합니다.

GPUDirect RDMA/PCIe device isolation을 고려한다면 이 부분을 나중에 바꾸지 말고 처음부터 표준화하는 것을 추천합니다.


25. NUMA 확인

numactl -H

그리고:

lspci -vv -s <GPU-PCI-address>
lspci -vv -s <E810-PCI-address>

NUMA node:

cat /sys/bus/pci/devices/<PCI>/numa_node

GPU 8장과 NIC의 NUMA 관계를 기록합니다.


26. STEP 7 — 기존 NVIDIA driver 설치 여부

GPU Operator가 driver를 관리할 것이므로 host에 NVIDIA driver를 미리 설치하지 않는 것을 권장합니다.

확인:

rpm -qa | grep -i nvidia

그리고:

lsmod | grep nvidia

만약 이미 설치되어 있다면 먼저 정리 여부를 결정해야 합니다.

현재 계획:

Host
 ├─ ice
 ├─ irdma
 └─ NVIDIA driver 없음

GPU Operator
 └─ NVIDIA driver 관리

입니다.

NVIDIA 공식 설치 문서도 기본 설치에서는 GPU Operator가 driver container, Container Toolkit, Device Plugin, DCGM Exporter 등을 배포한다고 설명합니다. (NVIDIA Docs)


27. Driver kernel module type

GPU Operator 26.7의 기본값은:

driver.kernelModuleType: auto

입니다.

가능한 값:

auto
open
proprietary

NVIDIA 문서상 auto는 GPU와 driver branch에 따라 권장 kernel module type을 선택합니다. (NVIDIA Docs)

B300/Blackwell 계열에서는 저는 일단 auto를 사용하겠습니다.

즉:

--set driver.kernelModuleType=auto

또는 아예 기본값을 사용합니다.


28. 왜 open kernel module을 고려하는가?

GPU Operator 26.7 component matrix에는:

NVIDIA GPU Driver
610.57.04
595.91.07 (Recommended/Default)
580.173.02
535.309.01

등이 표시됩니다. (NVIDIA Docs)

또한 NVIDIA의 최신 driver 설치 문서에서는 RHEL 10에서 nvidia-open 패키지를 지원하고 있습니다. (NVIDIA Docs)

그리고 GPU Operator 26.7의 GDS driver 2.29.4는 Open GPU Kernel module driver가 필요합니다. (NVIDIA Docs)

따라서 향후:

GPUDirect RDMA
GPUDirect Storage
GDS

까지 고려한다면 open kernel module 기반을 우선 검토할 가치가 있습니다.

다만 현재 POC에서는 auto로 시작하는 것이 안전합니다.


29. STEP 8 — Air-gapped 환경 준비

사용자 환경이 air-gapped이므로 이 부분은 상당히 중요합니다.

GPU Operator는 기본적으로:

K8s node
   ↓
GPU Operator images
   ↓
local registry

Driver container
   ↓
RHEL packages
   ↓
local package repository

두 가지가 필요합니다.

NVIDIA 공식 air-gapped 문서도 이 두 가지를 명확히 요구합니다. (NVIDIA Docs)


30. 필요한 local image

GPU Operator 26.7의 주요 component:

gpu-operator
driver
container-toolkit
k8s-device-plugin
dcgm
dcgm-exporter
gpu-feature-discovery
mig-manager
validator
nfd

정확한 image/tag는 반드시:

helm show values nvidia/gpu-operator \
  --version=v26.7.0

와 component matrix를 기준으로 mirror합니다.

26.7의 주요 component version은:

Driver              595.91.07 default/recommended
Container Toolkit   1.20.0
Device Plugin       0.20.0
DCGM Exporter       4.6.0-4.8.3
NFD                 0.19.0
GFD                 0.20.0
MIG Manager         0.15.0
DCGM                4.6.0-1

입니다. (NVIDIA Docs)


31. Air-gap에서는 Driver image가 특히 중요

Driver image는 OS에 따라 tag가 붙습니다.

NVIDIA 문서에서 26.7부터 conventional RHEL/Rocky driver image tag를 OS major version 기반으로 구성하는 방식으로 변경되었습니다. 예를 들어 RHEL 10이면 rhel10 계열을 사용합니다. (NVIDIA Docs)

즉 RHEL 10.2라고 해서:

driver:595....-rhel10.2

식으로 생각하면 안 되고, 26.7에서는 OS major version tag 규칙을 적용해야 합니다.

이 부분은 기존 26.3 기준 작업계획과 달라진 중요한 부분입니다.


32. Local package repository

Driver container가 필요한 경우 최소한 RHEL node의:

kernel-headers
kernel-devel
kernel-core
gcc

가 local repository에서 접근 가능해야 합니다. (NVIDIA Docs)

확인:

dnf repolist

그리고:

dnf list installed kernel-devel
dnf list installed kernel-headers
dnf list installed gcc

air-gap이라면:

RHEL 10.2 repository
      ↓
internal Nexus/Repo
      ↓
GPU node

구조를 만드는 것이 좋습니다.


33. Precompiled Driver 사용 여부

여기서 선택지가 있습니다.

일반 driver container

GPU Operator
 ↓
driver container
 ↓
host kernel headers
 ↓
driver build

Precompiled driver

GPU Operator
 ↓
precompiled driver
 ↓
host kernel에 맞는 image

air-gapped 환경에서는 precompiled driver를 사용할 수 있으면 운영 복잡도가 크게 줄어듭니다.

NVIDIA 문서도 precompiled driver container를 사용하면 driver container가 OS package를 다운로드할 필요가 없어 local package repository가 필요하지 않게 된다고 설명합니다. (NVIDIA Docs)

다만 RHEL 10.2 + 실제 kernel + B300 + 선택 driver branch에 대해 precompiled image가 정확히 제공되는지 확인 후 결정해야 합니다.


34. STEP 9 — GPU node labeling

GPU node를 일반 workload와 분리합니다.

예:

kubectl label node <gpu-node> \
  accelerator=nvidia-b300

그리고:

kubectl label node <gpu-node> \
  gpu=true

확인:

kubectl get node <gpu-node> --show-labels

35. GPU node taint도 권장

GPU node를 GPU workload 전용으로 쓸 예정이라면:

kubectl taint nodes <gpu-node> \
  nvidia.com/gpu=true:NoSchedule

그러면 GPU workload만 toleration을 넣어 들어오게 할 수 있습니다.

단, GPU Operator의 DaemonSet들은 해당 taint를 tolerate하도록 구성되는지 확인해야 합니다.

처음에는 taint 없이 설치하고 정상화한 뒤 taint를 적용하는 방법도 좋습니다.


36. STEP 10 — GPU Operator 설치

먼저 Helm:

helm version

repo:

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

chart 확인:

helm show chart nvidia/gpu-operator \
  --version=v26.7.0

values:

helm show values nvidia/gpu-operator \
  --version=v26.7.0 > gpu-operator-26.7-values.yaml

37. 첫 설치는 최대한 단순하게

현재 환경에서는 다음과 같은 방향을 권장합니다.

helm upgrade --install gpu-operator \
  nvidia/gpu-operator \
  --version=v26.7.0 \
  --namespace gpu-operator \
  --create-namespace \
  --set driver.kernelModuleType=auto \
  --set cdi.enabled=true \
  --set cdi.nriPluginEnabled=false \
  --set dcgmExporter.enabled=true

실제 air-gapped 환경에서는 여기에 internal registry/repository 설정이 추가됩니다.


38. 왜 CDI=true?

GPU Operator 26.7은 CDI가 기본적으로 활성화되어 있습니다.

CDI를 이용하면:

Kubernetes workload
        ↓
container runtime
        ↓
CDI specification
        ↓
GPU device

로 GPU injection을 처리합니다.

NVIDIA 문서도 26.7에서 CDI가 기본/권장 방식이며 native CDI를 사용하는 runtime을 활용한다고 명시합니다. (NVIDIA Docs)

따라서 특별한 이유가 없다면:

CDI를 끄지 마세요.


39. NRI는 false

cdi:
  enabled: true
  nriPluginEnabled: false

NRI는 아직 GA가 아니므로 production 환경에서는 일단 사용하지 않는 것을 권장합니다. (NVIDIA Docs)


40. 설치 후 첫 확인

kubectl get pods -n gpu-operator -o wide

정상적으로는 대략:

gpu-operator
nvidia-driver-daemonset
nvidia-container-toolkit-daemonset
nvidia-device-plugin-daemonset
nvidia-dcgm-exporter
gpu-feature-discovery
node-feature-discovery
nvidia-operator-validator
nvidia-cuda-validator

등이 나타납니다.

NVIDIA 공식 26.7 verification 예제에서도 이와 같은 operand들이 Running이고 CUDA validator는 Completed 상태인 것을 정상으로 봅니다. (NVIDIA Docs)


41. ClusterPolicy 확인

kubectl get clusterpolicy

정상:

NAME            STATUS
cluster-policy  ready

상세:

kubectl describe clusterpolicy cluster-policy

42. 모든 GPU Operator pod 확인

kubectl get pods \
  -n gpu-operator \
  -o wide

그리고:

kubectl get ds -n gpu-operator
kubectl get deploy -n gpu-operator

43. Driver가 정말 설치됐는지

GPU node에서:

lsmod | grep nvidia

그리고:

nvidia-smi

가장 중요합니다.

정상이라면:

+-----------------------------------------------------------------------------+
| NVIDIA-SMI ...
| GPU  Name ...
| 0 B300
| 1 B300
| ...
| 7 B300
+-----------------------------------------------------------------------------+

즉:

8/8 GPU가 보여야 합니다.


44. 8 GPU 정확히 확인

nvidia-smi --list-gpus

그리고:

nvidia-smi \
  --query-gpu=index,name,pci.bus_id,uuid,memory.total \
  --format=csv

정확히 8개인지 확인합니다.


45. GPU 상태

nvidia-smi -q

여기서:

Product Name
GPU UUID
PCI
Firmware
Driver Version
CUDA Version
Power
Temperature
ECC
MIG

등을 확인합니다.

B300 8장을 production에 넣는다면 이 출력은 설치 완료 증적으로 저장해두는 것을 추천합니다.


46. MIG 확인

B300의 workload 설계에 따라 MIG를 사용할 수도 있지만 vLLM에서 8개 GPU를 full GPU로 사용하는 것이 목표라면 처음에는 MIG를 건드리지 않는 것을 추천합니다.

확인:

nvidia-smi -L

그리고:

nvidia-smi mig -lgi

현재 MIG mode가 어떻게 되어 있는지 기록합니다.


47. Kubernetes GPU resource 확인

kubectl get node <gpu-node> \
  -o jsonpath='{.status.capacity.nvidia\.com/gpu}{"\n"}'

예상:

8

allocatable:

kubectl get node <gpu-node> \
  -o jsonpath='{.status.allocatable.nvidia\.com/gpu}{"\n"}'

역시:

8

이어야 합니다.

NVIDIA 공식 verification에서도 nvidia.com/gpu allocatable 값이 물리 GPU 수와 일치하는지를 확인하도록 합니다. (NVIDIA Docs)


48. GPU Feature Discovery 확인

kubectl get node <gpu-node> --show-labels

NVIDIA 관련:

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

여기서:

nvidia.com/gpu
nvidia.com/gpu.product
nvidia.com/gpu.memory
nvidia.com/cuda.*

등의 정보를 확인합니다.


49. CDI 확인

GPU Operator pod:

kubectl get pods -n gpu-operator | grep toolkit

node에서:

ls -l /var/run/cdi/

또는:

find /var/run/cdi -type f -maxdepth 1 -print

CDI spec이 생성되어 있어야 합니다.

가능하면:

nvidia-ctk cdi list

도 확인합니다.

예상되는 NVIDIA CDI device가 나와야 합니다.


50. Container에서 GPU 확인

가장 중요한 실제 test입니다.

간단한 CUDA image를 사용해서:

kubectl run gpu-test \
  --rm -it \
  --restart=Never \
  --image=<internal-cuda-image> \
  --limits='nvidia.com/gpu=1' \
  -- nvidia-smi

air-gap이면 내부 registry의 CUDA image를 사용해야 합니다.

정상:

CUDA container
       ↓
nvidia-smi
       ↓
B300 visible

51. 8 GPU workload 테스트

Pod 하나에:

resources:
  limits:
    nvidia.com/gpu: 8

를 요청해 실제 8 GPU가 한 pod에 모두 전달되는지 테스트합니다.

컨테이너 내부:

nvidia-smi -L

8개가 보여야 합니다.

이것은 향후 vLLM 8-GPU deployment의 기본 validation입니다.


52. CUDA functional test

단순 nvidia-smi만으로는 부족합니다.

CUDA sample 또는 PyTorch container에서:

import torch

print(torch.cuda.is_available())
print(torch.cuda.device_count())

for i in range(torch.cuda.device_count()):
    print(i, torch.cuda.get_device_name(i))

예상:

True
8
B300
B300
...

53. GPU 계산 테스트

PyTorch:

import torch

for i in range(8):
    x = torch.randn((4096,4096), device=f"cuda:{i}")
    y = x @ x
    torch.cuda.synchronize(i)
    print(i, y.mean().item())

목적은:

모든 GPU가 실제 CUDA context를 만들고 연산 가능한가?

입니다.


54. 8 GPU P2P 테스트

8 GPU 시스템에서는 반드시 해야 합니다.

nvidia-smi topo -p2p r
nvidia-smi topo -p2p w

그리고 CUDA P2P sample 또는 NCCL test를 수행합니다.


55. NCCL test

특히 vLLM을 8 GPU로 운영한다면 NCCL test는 GPU Operator 기본 validation보다 훨씬 중요합니다.

예:

all_reduce_perf \
  -b 8 \
  -e 1G \
  -f 2 \
  -g 8

결과:

NCCL
GPU ↔ GPU
NVLink/NVSwitch

가 정상인지 확인합니다.


56. DCGM 확인

kubectl get pods -n gpu-operator \
  | grep dcgm

Exporter:

kubectl get pods -n gpu-operator \
  | grep exporter

DCGM Exporter 기본 port는:

9400

입니다.

NVIDIA DCGM 문서도 exporter의 /metrics에서 DCGM_ 계열 metric이 나오는 것을 확인하도록 안내합니다. (NVIDIA Docs)


57. DCGM metrics 확인

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

다른 terminal:

curl http://127.0.0.1:9400/metrics

그리고:

curl -s http://127.0.0.1:9400/metrics \
  | grep '^DCGM_' \
  | head

58. Prometheus 연결

사용자가 기존 Prometheus를 사용하고 있으므로 여기서는:

GPU Node
   ↓
DCGM Exporter :9400
   ↓
Prometheus
   ↓
Grafana

로 연결합니다.

처음부터 모든 DCGM metric을 가져오기보다:

GPU utilization
GPU memory
GPU power
GPU temperature
PCIe TX/RX
NVLink
ECC
XID

위주로 가져오는 것을 추천합니다.


59. 특히 8 GPU에서는 XID error를 반드시 수집

GPU 장애에서 매우 중요한 metric/log입니다.

노드:

dmesg | grep -i xid

그리고:

journalctl -k | grep -i xid

정상 설치 후:

GPU XID error = 0

을 baseline으로 만들어 놓으세요.


60. GPU Operator validator 확인

kubectl get pods -n gpu-operator \
  | grep validator

상세:

kubectl logs -n gpu-operator \
  <validator-pod>

Validator가 실패하면 application test로 넘어가면 안 됩니다.


61. 여기까지가 GPU Operator 설치 완료 기준

저라면 다음 조건을 모두 만족해야 GPU Operator installation PASS로 판정합니다.

[PASS]

RHEL 10.2
K8s 1.33
containerd supported version
        ↓
B300 x8 detected
        ↓
NVIDIA driver loaded
        ↓
nvidia-smi = 8 GPU
        ↓
nvidia.com/gpu = 8
        ↓
CDI functional
        ↓
CUDA container functional
        ↓
GPU Operator validator PASS
        ↓
DCGM exporter functional
        ↓
Prometheus scraping
        ↓
NCCL 8-GPU test PASS

62. 그리고 이제 RDMA를 붙입니다

여기부터는 GPU Operator와 별도 layer입니다.

현재:

GPU Operator
       │
       └── B300
           
Intel E810
   │
  ice
   │
  irdma
   │
 RDMA subsystem

입니다.


63. 중요한 점: GPU Operator에 RDMA를 넣는 것과 Intel E810 RDMA는 다름

GPU Operator의:

driver.rdma.enabled

NVIDIA driver-side GPUDirect RDMA integration에 관한 설정입니다.

NVIDIADriver CRD에서도:

rdma:
  enabled: false

가 기본값입니다. (NVIDIA Docs)

하지만 이것을:

rdma.enabled=true

한다고 해서:

Intel E810
+
ice
+
irdma

가 설치되는 것이 아닙니다.

따라서 현재는 그 설정을 섣불리 켜지 않는 것을 권장합니다.


64. RDMA Device Plugin

그 다음 단계가:

Host
  irdma
    ↓
RDMA device
    ↓
RDMA Device Plugin
    ↓
Kubernetes resource
    ↓
Pod

입니다.

여기서 Intel E810을 사용하는 만큼 NVIDIA Network Operator의 RDMA Shared Device Plugin을 그대로 적용하지 말고, Intel E810에서 사용할 generic/community RDMA device plugin을 검증해서 선택하는 것이 좋습니다.

이 부분은 GPU Operator 설치와 별도입니다.


65. RDMA Device가 Pod에 들어가는지 확인

최종적으로:

kubectl describe node <gpu-node>

에서 RDMA 관련 resource가 노출되고,

테스트 pod에서 RDMA device가 보이는지:

ls -l /dev/infiniband/

확인합니다.

RoCE는 InfiniBand가 아니지만 Linux RDMA subsystem은 /dev/infiniband/* 인터페이스를 사용할 수 있습니다.


66. RDMA test 순서

반드시:

1. Host RDMA
       ↓
2. Pod RDMA
       ↓
3. Host ↔ Host
       ↓
4. Pod ↔ Pod
       ↓
5. RoCEv2
       ↓
6. PFC/ECN
       ↓
7. GPU memory RDMA

순서로 가세요.

처음부터 GPUDirect를 테스트하면 원인 분리가 안 됩니다.


67. E810/RDMA에서 추가로 저장해야 할 정보

ethtool -i <e810>
ethtool -k <e810>
ethtool -S <e810>

특히:

rx_errors
tx_errors
rx_dropped
tx_dropped
pause
ecn

등의 NIC counters를 benchmark 시작 전에 저장합니다.


68. RoCEv2 확인

rdma link

그리고:

rdma system show

필요하면:

rdma dev show

E810 RDMA device와 Ethernet interface mapping을 기록합니다.


69. bond1 + RDMA는 별도 검증

현재 architecture가:

       bond1
       LACP
      /     \
 E810 port1 E810 port2

라면 일반 IP traffic이 정상인 것만으로 RDMA/LAG가 정상이라고 판단하면 안 됩니다.

따라서:

TCP over bond1
vs
RDMA over bond1

를 각각 측정합니다.


70. 그리고 PFC/ECN

초기 installation에서는:

PFC/ECN을 먼저 변경하지 않는 것

을 권장합니다.

순서는:

GPU Operator
 ↓
RDMA
 ↓
RoCEv2 basic
 ↓
Baseline
 ↓
PFC/ECN
 ↓
성능 비교

입니다.

이렇게 해야 PFC configuration 문제가 GPU/RDMA 문제와 섞이지 않습니다.


71. 설치 완료 후 최종 health check

제가 실제 운영 인수 checklist를 만든다면 다음처럼 합니다.

OS

cat /etc/redhat-release
uname -r

Runtime

containerd --version
crictl info

Kubernetes

kubectl get node
kubectl describe node <gpu-node>

GPU

nvidia-smi
nvidia-smi -L
nvidia-smi topo -m

GPU resource

kubectl get node <gpu-node> \
  -o jsonpath='{.status.allocatable.nvidia\.com/gpu}'

Operator

kubectl get clusterpolicy
kubectl get pods -n gpu-operator

CDI

nvidia-ctk cdi list

DCGM

curl http://127.0.0.1:9400/metrics

NIC

ethtool -i <e810>

RDMA

rdma link
ibv_devices
ibv_devinfo

Bond

cat /proc/net/bonding/bond1

Cilium

cilium status

72. 설치 전/후 비교를 위해 이 정보는 반드시 저장하세요

설치 전에:

mkdir -p /root/gpu-install-baseline

uname -a > /root/gpu-install-baseline/uname.txt
lscpu > /root/gpu-install-baseline/lscpu.txt
numactl -H > /root/gpu-install-baseline/numa.txt
lspci -nn > /root/gpu-install-baseline/lspci.txt
lspci -tv > /root/gpu-install-baseline/lspci-tree.txt
ip -br link > /root/gpu-install-baseline/ip.txt
cat /proc/net/bonding/bond1 > /root/gpu-install-baseline/bond1.txt
ethtool -i <e810> > /root/gpu-install-baseline/e810-driver.txt
lsmod > /root/gpu-install-baseline/modules.txt

GPU 설치 후:

nvidia-smi > /root/gpu-install-baseline/nvidia-smi.txt
nvidia-smi -q > /root/gpu-install-baseline/nvidia-smi-q.txt
nvidia-smi topo -m > /root/gpu-install-baseline/nvidia-topo.txt

K8s:

kubectl get nodes -o wide \
  > /root/gpu-install-baseline/k8s-nodes.txt

kubectl get pods -A -o wide \
  > /root/gpu-install-baseline/k8s-pods.txt

이렇게 해두면 나중에 장애가 발생했을 때 굉장히 유용합니다.


73. 특히 B300 8-GPU node에서는 여기까지 추가

설치 완료 후 다음을 별도로 기록하세요.

nvidia-smi topo -m
nvidia-smi nvlink -s
nvidia-smi nvlink -e
nvidia-smi -q

그리고:

dmesg | grep -Ei 'NVRM|Xid|nvidia|nvlink'

정상 baseline에서는 XID가 없어야 합니다.


74. 제가 권하는 최종 설치 단계

실제 엔지니어가 작업한다면 아래 순서 그대로 진행하겠습니다.

DAY 0 — Hardware / OS

① B300 x8 PCIe 확인
② E810 PCIe 확인
③ GPU/NIC NUMA 확인
④ BIOS 확인
⑤ RHEL 10.2 확인
⑥ kernel 확인
⑦ kernel-devel/header 확인
⑧ gcc 확인
⑨ containerd version 확인
⑩ Kubespray configuration 확인

DAY 0 — Network

⑪ bond0 확인
⑫ bond1 확인
⑬ LACP 확인
⑭ E810 firmware 확인
⑮ ice 확인
⑯ irdma 확인
⑰ rdma link 확인
⑱ ibv_devinfo 확인
⑲ Host RDMA test

DAY 1 — GPU Operator

⑳ Air-gap image mirror
㉑ RHEL package repository
㉒ GPU node label
㉓ GPU Operator 26.7 install
㉔ Driver install
㉕ CDI
㉖ Device Plugin
㉗ GFD/NFD
㉘ DCGM Exporter

DAY 1 — GPU validation

㉙ nvidia-smi
㉚ 8 GPU 확인
㉛ CUDA container
㉜ PyTorch
㉝ GPU P2P
㉞ NCCL
㉟ DCGM
㊱ Prometheus

DAY 2 — RDMA

㊲ RDMA device plugin
㊳ Pod RDMA
㊴ Pod ↔ Pod RDMA
㊵ RoCEv2
㊶ bond1 RDMA
㊷ PFC/ECN

DAY 3 — GPUDirect

㊸ GPU-memory RDMA
㊹ DMA-BUF
㊺ GPUDirect RDMA
㊻ E810 limitation/support assessment

DAY 4 — AIStor

㊼ TCP baseline
㊽ RoCE baseline
㊾ AIStor performance
㊿ vLLM

75. 이번 구성에서 제가 특히 중요하게 보는 7개 Gate

최종적으로는 아래 7개를 Go/No-Go gate로 두는 것을 추천합니다.

Gate확인목표
G1RHEL 10.2 + K8s 1.33 + containerd공식/검증 조합
G2B300 x88/8 GPU
G3CUDA/CDIGPU workload 정상
G4NCCL8-GPU communication 정상
G5E810 + irdmaHost RDMA 정상
G6RoCEv2 + bond1network RDMA 정상
G7GPU-memory RDMAGPUDirect 가능성 검증

그리고 G7은 별도로 "NVIDIA 공식 지원 여부"와 "실제 기술적으로 동작하는지"를 분리해서 기록해야 합니다.

NVIDIA 현재 문서의 GPUDirect RDMA 지원표는 RHEL 10.0 등을 특정 Network Operator 버전과 함께 명시하지만, Network Operator의 공식 지원 NIC ecosystem은 NVIDIA networking 제품 중심입니다. 따라서 Intel E810을 사용한 GPUDirect RDMA는 공식 지원 조합으로 간주하지 말고 별도 POC 결과로 판단하는 것이 안전합니다. (NVIDIA Docs)


마지막으로 현재 환경에서 제가 권하는 설치 구성

처음 GPU node 1대를 추가하는 단계에서는 최대한 단순하게 시작하는 게 좋습니다.

RHEL 10.2
   │
   ├── containerd 2.x
   ├── Cilium
   ├── bond0
   │     └── external
   │
   └── bond1
         ├── K8s traffic
         └── RoCEv2
                │
             Intel E810
              ├── ice
              └── irdma

NVIDIA GPU Operator 26.7
   ├── NVIDIA Driver
   ├── Container Toolkit
   ├── CDI
   ├── Device Plugin
   ├── NFD/GFD
   ├── DCGM
   ├── DCGM Exporter
   └── Validator

B300 x8
   ├── CUDA
   ├── PyTorch
   ├── NCCL
   └── vLLM

별도 구성
   └── RDMA Device Plugin

Network Operator 26.4.1 / Multus / RDMA CNI는 현재 단계에서 일단 넣지 않는 것을 권장합니다. Intel E810을 쓰는 상황에서는 오히려 host의 ice + irdma를 먼저 정상화하고, 이후 필요한 Pod-level RDMA isolation이 생길 때 추가하는 것이 훨씬 안전합니다.

그리고 GPU Operator 26.7의 CDI는 켜고, NRI는 끄고, driver는 Operator가 관리하며 kernelModuleType=auto로 시작하는 것이 현재 B300/RHEL 10.2 환경에서 가장 무난한 출발점입니다. (NVIDIA Docs)

특히 containerd가 현재 1.7이라면 여기서 바로 멈추고 containerd 2.x 문제부터 해결하는 것이 좋습니다. GPU Operator 26.7의 공식 runtime matrix가 containerd 2.0~2.3을 기준으로 하고 있기 때문입니다. (NVIDIA Docs)

profile
engineer

0개의 댓글