네. 지금까지 이야기한 조건을 종합하면, 현재 GPU node는 Intel E810을 사용하고, 기존 bond0=외부, bond1=K8s 내부/LACP active-active를 유지하면서, GPU Operator + host의 ice/irdma + RDMA Device Plugin을 구성하고, 필요하면 나중에 RoCEv2 PFC/ECN을 추가하는 구조가 가장 깔끔합니다.
특히 NVIDIA Network Operator는 현재 E810 환경에서는 필수 구성요소로 넣지 않는 것을 권합니다. NVIDIA 문서상 DMA-BUF GPUDirect RDMA에서는 네트워크 드라이버를 host에 설치할 수 있고, Network Operator는 네트워크 드라이버/Device Plugin을 관리할 때 사용하는 선택적 경로입니다. (NVIDIA Docs)
아래처럼 진행하겠습니다.
현재 환경을 기준으로 하면:
Existing K8s Cluster
│
┌──────────────┴──────────────┐
│ │
Existing CPU nodes GPU node
RHEL 10 Ubuntu 24.04
│ │
Cilium Cilium
│ │
┌────────┴────────┐ ┌────────┴────────┐
│ │ │ │
bond0 bond1 bond0 bond1
external K8s internal external K8s internal
│
E810 LACP
active-active
│
ice + irdma
│
RoCEv2
│
Switch
│
E810
│
AIStor
그리고 GPU 쪽은:
B300
│
│ GPUDirect RDMA
▼
E810
│
│ RoCEv2
▼
Switch
│
▼
AIStor E810
입니다.
중요: GPUDirect RDMA와 "AIStor가 실제로 RDMA를 이용하는지"는 별개의 검증 항목입니다. GPU Operator가 GPUDirect RDMA 경로를 준비해 준다고 해서 일반 S3/HTTP traffic이 자동으로 GPUDirect RDMA가 되는 것은 아닙니다.
현재 말씀하신:
ice + irdma조합은 방향상 적절합니다.
GPU Operator 26.3.x는 현재 supported release이고, Ubuntu 22.04/24.04 및 RHEL 10 계열에서 Kubernetes 1.32~1.36을 검증하고 있습니다. 따라서 K8s 1.33 자체는 지원 범위입니다. (NVIDIA Docs)
그리고 기존 RHEL10 CPU node와 Ubuntu GPU node가 섞이는 것 자체는 문제가 아닙니다. 중요한 것은 GPU workload를 실제로 실행하는 GPU node들의 OS/driver 환경을 일관되게 관리하는 것입니다.
현재 GPU node가 1대라면 사실상 그 한 대의 환경을 표준으로 잡으면 됩니다.
제가 추천하는 GPU node OS는:
Ubuntu 24.04 LTS
입니다.
GPU Operator 26.3은 Ubuntu 24.04 + K8s 1.32~1.36을 지원합니다. (NVIDIA Docs)
cat /etc/os-release
uname -r
lscpu
free -h
GPU:
lspci | grep -i nvidia
B300이 보여야 합니다.
GPU node에서:
apt update
apt install -y \
build-essential \
linux-headers-$(uname -r) \
pciutils \
ethtool \
iproute2 \
rdma-core \
ibverbs-providers \
infiniband-diags \
perftest
여기서 중요한 것은:
rdma-core
ibverbs
perftest
입니다.
perftest는 나중에:
ib_write_bw
ib_read_bw
ib_send_bw
ib_send_lat
테스트에 사용합니다.
E810은:
ice = Ethernet driver
irdma = RDMA driver
구조입니다.
Intel 공식 문서에서도 E810 Linux RDMA stack은 ice + irdma이고 RoCEv2를 지원합니다. (Intel)
확인:
lspci -nn | grep -i ethernet
예:
Intel Corporation Ethernet Controller E810
ethtool -i <E810_PORT0>
예:
ethtool -i ens5f0np0
확인:
driver: ice
version: ...
firmware-version: ...
두 port 모두:
ethtool -i ens5f0np0
ethtool -i ens5f1np1
확인합니다.
ethtool -i ens5f0np0
ethtool -i ens5f1np1
에서:
firmware-version
을 확인합니다.
현재 E810 + LACP + RDMA 조합에서는 최신 ice driver/NVM을 사용하는 것을 강하게 권합니다.
Intel은 E810에서 RDMA+LAG를 사용할 경우 최신 driver/NVM, RoCEv2, active-active/active-backup, 같은 device의 두 port, bonding 전 QoS 동일이라는 조건을 제시합니다. (Intel)
현재 bond1이:
802.3ad
LACP
active-active
이므로 먼저:
cat /proc/net/bonding/bond1
확인합니다.
원하는 형태:
Bonding Mode: IEEE 802.3ad Dynamic link aggregation
MII Status: up
Slave Interface: ens5f0np0
Slave Interface: ens5f1np1
그리고:
ip -d link show bond1
Intel 공식 문서상 E810에서는 RDMA + LAG가 가능합니다.
조건:
E810
+
latest driver/NVM
+
RoCEv2
+
active-active 또는 active-backup
+
같은 E810 device의 두 port
+
두 port QoS 설정 동일
입니다. (Intel)
따라서 현재 bond1이 정말 동일 E810의 두 port인지 확인해야 합니다.
먼저:
lsmod | grep irdma
없으면:
modprobe irdma
그리고:
lsmod | grep -E 'ice|irdma'
확인.
rdma link
그리고:
ibv_devices
ibv_devinfo
정상적으로 RDMA HCA/device가 보여야 합니다.
이 단계에서 실패하면 GPU Operator나 Kubernetes를 건드리지 말고 여기부터 해결하는 게 좋습니다.
E810의 RDMA protocol이 RoCEv2인지 확인합니다.
rdma link
그리고 Intel E810의 RDMA 설정/driver 상태를 확인합니다.
현재 목표는:
E810
↓
ice
↓
irdma
↓
RoCEv2
입니다.
여기까지가 host-level RDMA 준비입니다.
이제 GPU Operator를 설치합니다.
GPU Operator 26.3의 기본 설치는 GPU driver, NVIDIA Container Toolkit, Device Plugin, DCGM Exporter, MIG Manager 등을 GPU node에 배포합니다. (NVIDIA Docs)
Air-gapped이므로 먼저 필요한 NVIDIA image를 내부 Nexus/registry로 mirror해야 합니다.
일반적인 online 설치 예:
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
helm repo update
설치:
helm upgrade --install gpu-operator \
nvidia/gpu-operator \
-n gpu-operator \
--create-namespace \
--version=v26.3.3 \
--set driver.kernelModuleType=open \
--wait
NVIDIA 문서상 kernelModuleType은:
auto
open
proprietary
이고 auto가 기본값입니다. (NVIDIA Docs)
open을 추천하느냐현재 목표가:
B300
+
GPUDirect RDMA
이기 때문입니다.
NVIDIA는 GPUDirect RDMA에서:
DMA-BUF
방식을 legacy nvidia-peermem보다 권장하고 있습니다.
DMA-BUF 방식에는 NVIDIA Open GPU Kernel Module이 필요합니다. (NVIDIA Docs)
그래서:
driver:
kernelModuleType: open
을 권합니다.
driver.rdma.enabled는 일단 켜지 않는다중요합니다.
driver:
rdma:
enabled: false
또는 기본값 그대로 둡니다.
왜냐하면:
driver.rdma.enabled=true
는 legacy nvidia-peermem kernel module을 사용하는 옵션입니다. NVIDIA 문서에서도 DMA-BUF를 사용하는 경우 반드시 켤 필요가 없다고 설명합니다. (NVIDIA Docs)
따라서 현재 목표:
B300
↓
DMA-BUF
↓
E810
에서는:
nvidia-peermem ❌
로 먼저 갑니다.
kubectl get pods -n gpu-operator
주요 component:
gpu-operator
gpu-feature-discovery
nvidia-container-toolkit
nvidia-device-plugin
nvidia-dcgm
dcgm-exporter
nvidia-driver-daemonset
등이 정상이어야 합니다.
그리고:
kubectl describe node <GPU_NODE>
에서:
Capacity:
nvidia.com/gpu: 1
확인.
GPU test pod:
resources:
limits:
nvidia.com/gpu: 1
로 실행해서:
nvidia-smi
가 정상인지 확인합니다.
이 단계에서:
Kubernetes
↓
NVIDIA Device Plugin
↓
B300
이 정상입니다.
현재 E810을 host에서 직접 관리할 것이므로 NVIDIA Network Operator는 일단 사용하지 않습니다.
대신 Kubernetes에 RDMA device를 expose하기 위해:
Kubernetes RDMA Shared Device Plugin
을 설치합니다.
공식 plugin은 RDMA-capable hardware와 RDMA kernel stack이 올라온 node에서 동작하도록 설계되어 있습니다. (GitHub)
GPU Operator에는 NFD가 포함되어 배포되는 구성이 있습니다.
하지만 RDMA Device Plugin이 요구하는 node selection/label까지 GPU Operator의 NFD가 반드시 동일하게 제공한다고 가정하지 않는 것이 좋습니다.
따라서:
중 무엇을 사용할지 정리해야 합니다.
GPU node가 1대이고 명확하다면 초기 POC에서는 nodeSelector/label을 직접 지정하는 방법이 가장 단순합니다.
예:
nodeSelector:
gpu: "true"
예를 들어 resource를:
rdma/e810
으로 Kubernetes에 expose합니다.
개념적인 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: rdma-devices
namespace: kube-system
data:
config.json: |
{
"periodicUpdateInterval": 60,
"configList": [
{
"resourceName": "e810",
"rdmaHcaMax": 1,
"selectors": {
"ifNames": [
"ens5f0np0"
]
}
}
]
}
다만 현재는 bond1 + E810 2-port LAG이므로 이 부분은 실제 rdma link 출력에 맞춰 resource selector를 결정해야 합니다.
즉, 무조건 ens5f0np0 하나를 넣기보다는 irdma가 실제 어떤 RDMA device를 expose하는지 먼저 확인해야 합니다.
kubectl describe node <GPU_NODE>
예:
Allocatable:
nvidia.com/gpu: 1
rdma/e810: 1
이런 식으로 보이면 성공입니다.
테스트 Pod에서:
rdma link
ibv_devices
ibv_devinfo
확인합니다.
즉:
Host
E810
↓
irdma
↓
RDMA device
↓
RDMA Device Plugin
↓
Kubernetes Pod
가 완성됩니다.
여기서부터는 GPU를 아직 개입시키지 않습니다.
GPU node:
E810
AIStor node:
E810
간에 먼저 테스트합니다.
AIStor node:
ib_write_bw
GPU node:
ib_write_bw <AIStor_RDMA_IP>
그리고:
ib_read_bw <AIStor_RDMA_IP>
ib_send_bw <AIStor_RDMA_IP>
ib_send_lat <AIStor_RDMA_IP>
E810은 단일 QP보다 여러 QP에서 성능이 더 잘 나오는 경우가 있으므로:
ib_write_bw -q 1 <IP>
ib_write_bw -q 4 <IP>
ib_write_bw -q 8 <IP>
식으로 비교합니다.
기록:
QP
Bandwidth
Latency
CPU
packet loss
처음부터 PFC를 넣지 않는 것을 추천합니다.
현재:
bond1
├── Cilium
└── RoCEv2
상태에서:
PFC OFF
ECN OFF
으로 먼저 측정합니다.
이렇게 해야 나중에 QoS 효과를 정확히 비교할 수 있습니다.
여기가 지금까지 질문하신 핵심입니다.
원하는 구조:
bond1
│
├── Cilium
│ ↓
│ Priority 0
│ ↓
│ TC0
│ ↓
│ PFC OFF
│
└── RoCEv2
↓
Priority 3
↓
TC3
↓
PFC ON
E810에서는 Priority → Traffic Class → PFC 구조로 만듭니다.
현재 환경에서는 DSCP 방식이 깔끔합니다.
예:
RoCEv2
↓
DSCP 24
↓
Priority 3
↓
TC3
↓
PFC ON
일반 Cilium:
Cilium
↓
DSCP 0
↓
Priority 0
↓
TC0
↓
PFC OFF
Intel E810은 DSCP 기반 QoS/PFC를 지원합니다.
Intel의 irdma에서는 RoCEv2 기본 ToS를 지정할 수 있습니다.
개념적으로:
echo 96 > \
/sys/kernel/config/rdma_cm/irdma0/ports/1/default_roce_tos
여기서:
ToS = 96
DSCP = 96 >> 2
= 24
입니다.
즉:
RoCEv2
→ ToS 96
→ DSCP 24
→ Priority 3
구조입니다.
실제 port/device 이름은 rdma link 결과에 맞춰 변경해야 합니다.
그 다음 E810의 DCB를:
Priority 3 → TC3
Priority 3 → PFC ON
으로 설정합니다.
예시적인 dcb 명령:
dcb pfc show dev ens5f0np0
dcb ets show dev ens5f0np0
그리고 설정 예:
dcb pfc set dev ens5f0np0 \
prio-pfc \
0:off 1:off 2:off 3:on \
4:off 5:off 6:off 7:off
ETS:
dcb ets set dev ens5f0np0 \
prio-tc \
0:0 1:0 2:0 3:3 \
4:0 5:0 6:0 7:0
하지만 현재 환경에서는 이 명령을 바로 실행하면 안 됩니다.
이유는:
E810 port0
E810 port1
↓
bond1 / LACP
이기 때문입니다.
Intel은 E810 RDMA+LAG에서 bonding 전에 두 port의 QoS 설정이 동일해야 한다고 명시합니다. 또한 LAG 이후 QoS 변경에 제한이 있습니다. (Intel)
따라서 현재 운영 bond1을 그대로 둔 상태에서 실제 변경 작업을 할 때는 maintenance window와 Intel driver version/NVM에 맞춰 순서를 잡아야 합니다.
최종적으로:
E810 port0:
P3 → TC3 → PFC ON
E810 port1:
P3 → TC3 → PFC ON
이어야 합니다.
Intel이 요구하는 조건입니다. (Intel)
Switch:
DSCP 24
↓
Priority 3
↓
TC3
↓
PFC ON
그리고 일반 K8s:
DSCP 0
↓
Priority 0
↓
TC0
↓
PFC OFF
으로 합니다.
따라서:
E810
│
DSCP 24 / P3
│
▼
┌───────────┐
│ Switch │
│ │
│ P3 → PFC │
│ P3 → ECN │
└─────┬─────┘
│
DSCP 24 / P3
│
▼
E810
입니다.
PFC만 먼저:
RoCE → P3 → PFC
테스트하고,
그 다음:
RoCE → P3
↓
PFC + ECN
으로 올리는 것을 권합니다.
왜냐하면 문제가 발생했을 때:
NIC
Switch
PFC
ECN
중 어디에서 문제가 발생했는지 분리하기 쉽기 때문입니다.
이제서야 B300을 RDMA path에 넣습니다.
기본 RDMA:
CPU memory
↓
E810
↓
RoCE
↓
E810
↓
CPU
GPUDirect:
B300 HBM
↓
DMA-BUF
↓
E810
↓
RoCEv2
↓
E810
↓
AIStor
NVIDIA GPU Operator는 DMA-BUF 기반 GPUDirect RDMA를 지원하고, NVIDIA는 nvidia-peermem보다 DMA-BUF 사용을 권장합니다. (NVIDIA Docs)
GPU node:
nvidia-smi topo -m
그리고:
lspci -tv
확인.
이상적인 것은:
B300
│
PCIe Root/Bridge
│
E810
가 가까운 PCIe topology에 있는 것입니다.
특히 NUMA/PCIe root complex가 중요합니다.
이제 CUDA-aware RDMA test를 합니다.
일반:
ib_write_bw
만으로는 GPU memory path를 검증할 수 없습니다.
GPU memory를 RDMA buffer로 사용하는 테스트가 필요합니다.
여기서:
등을 사용합니다.
목표는:
GPU HBM
↓
NIC
간에 CPU bounce buffer 없이 DMA가 이루어지는지 확인하는 것입니다.
여기가 최종 목표입니다.
다만 매우 중요합니다.
GPUDirect RDMA 가능
과
AIStor가 S3 traffic을 GPUDirect RDMA로 처리
는 동일하지 않습니다.
따라서 AIStor 측에서 실제 사용하려는 RDMA 기능/API/client 경로가 무엇인지 확인해야 합니다.
최종 path가 실제로:
vLLM
↓
GPU memory
↓
GPUDirect RDMA
↓
E810
↓
RoCEv2
↓
AIStor
가 되는지 별도 검증해야 합니다.
최종적으로:
GPU Node
┌──────────────────────┐
│ vLLM │
│ │ │
│ B300 │
│ │ │
│ GPUDirect RDMA │
│ │ │
│ E810 │
└──────────┼───────────┘
│
RoCEv2
│
Switch
│
│
E810
│
AIStor
가 됩니다.
현재는:
NVIDIA ConnectX ❌
NVIDIA OFED ❌
Intel E810 ✅
ice/irdma host driver ✅
이므로:
GPU Operator
+
Host ice/irdma
+
RDMA Device Plugin
이면 됩니다.
그때:
NVIDIA Network Operator
+
MOFED/DOCA
+
NVIDIA RDMA Device Plugin
+
Multus
등을 검토합니다.
NVIDIA 문서에서도 Network Operator는 네트워크 device driver와 Kubernetes device plugin 등을 관리하는 경로로 설명합니다. (NVIDIA Docs)
아닙니다.
현재:
bond0 → external
bond1 → K8s internal + RoCE
이고 RoCE가 bond1을 통해 기존 network namespace에서 동작한다면:
Multus ❌
로 시작할 수 있습니다.
Multus는:
Pod에 별도의 network interface/network attachment를 붙이고 싶을 때
필요한 것입니다.
RDMA Device Plugin은:
Pod가 RDMA device를 사용할 수 있도록 resource/device를 제공
하는 것이고,
둘은 역할이 다릅니다.
현재 1차 POC에서는 저는 정확히 다음만 설치합니다.
| 구성요소 | 설치 위치 | 필요 | 역할 |
|---|---|---|---|
ice | GPU node OS | 필수 | E810 Ethernet driver |
irdma | GPU node OS | 필수 | E810 RDMA/RoCE |
rdma-core | GPU node OS | 필수 | userspace RDMA |
| GPU Operator | K8s | 필수 | GPU driver/runtime/device plugin/DCGM |
| RDMA Device Plugin | K8s | 필수 | RDMA를 K8s resource로 expose |
| NFD | K8s | 권장 | GPU/RDMA node discovery |
| NVIDIA Network Operator | K8s | 현재 불필요 | ConnectX/MOFED 등의 lifecycle 관리 |
| Multus | K8s | 현재 불필요 | 추가 Pod network |
| PFC | NIC/Switch | 선택→운영 권장 | RoCE lossless priority |
| ECN | NIC/Switch | 선택→운영 권장 | congestion control |
| NCCL | GPU workload | vLLM/분산 GPU 시 중요 | GPU↔GPU collective |
| GDRCopy | GPU node | 선택 | low-latency GPU memory copy/test |
| GDS | GPU node | 현재 별도 목적 | GPU↔storage direct path |
최종적으로는 이 순서입니다.
① Ubuntu 24.04 GPU node 준비
↓
② E810 firmware/NVM 확인
↓
③ ice driver
↓
④ irdma driver
↓
⑤ rdma-core / ibverbs
↓
⑥ bond1 LACP 상태 확인
↓
⑦ rdma link / ibv_devinfo
↓
⑧ RoCEv2 host ↔ host 테스트
↓
⑨ GPU Operator 26.3.x
↓
⑩ B300 / nvidia-smi
↓
⑪ RDMA Device Plugin
↓
⑫ K8s Pod에서 RDMA device 확인
↓
⑬ E810 ↔ E810 perftest
↓
⑭ PFC OFF baseline
↓
⑮ RoCE priority/TC 설정
↓
⑯ RoCE priority에만 PFC
↓
⑰ ECN 추가
↓
⑱ GPUDirect RDMA test
↓
⑲ AIStor 실제 RDMA path test
↓
⑳ vLLM 실제 workload
ice + irdma를 GPU Operator가 설치한다고 생각하면 안 됩니다현재 Intel E810에서는 OS/host에서 관리합니다.
Ubuntu
├── ice
├── irdma
└── rdma-core
GPU Operator는:
NVIDIA driver
NVIDIA Container Toolkit
NVIDIA Device Plugin
DCGM
...
를 담당합니다.
nvidia-peermem을 처음부터 설치하지 않습니다GPU Operator
└── DMA-BUF
↓
GPUDirect RDMA
를 우선 사용합니다.
NVIDIA가 DMA-BUF 방식을 권장합니다. (NVIDIA Docs)
현재:
E810
ice
irdma
를 host에서 관리할 수 있으므로 굳이 Network Operator를 추가해서 복잡도를 높일 이유가 없습니다.
처음:
RoCEv2
PFC OFF
ECN OFF
로 기능 확인이 가능합니다.
그 후:
RoCE → P3 → PFC
로 QoS를 적용합니다.
그리고:
PFC + ECN
으로 운영 최적화합니다.
Intel이 명시한 E810 RDMA+LAG 조건:
E810
+
latest driver/NVM
+
RoCEv2
+
active-active
+
same device ports
+
QoS 동일
을 만족해야 합니다. (Intel)
따라서 PFC 설정을 실제로 적용하는 단계에서는 현재 bond1의 LACP 구조와 switch의 MLAG/LAG 구성을 먼저 확인해야 합니다.
현재는 굳이 복잡하게:
Network Operator
Multus
NVIDIA OFED
ConnectX
까지 넣지 않고,
GPU node
Ubuntu 24.04
│
┌──────┴───────┐
│ │
GPU Operator E810 host
│ │
B300 ice + irdma
│ │
└──────┬───────┘
│
RDMA Device Plugin
│
K8s Pod
│
RoCEv2
│
bond1 / LACP
│
Switch
│
E810
│
AIStor
로 먼저 기능을 완전히 검증하는 것을 추천합니다.
그 다음 운영 환경에서는:
RoCEv2
↓
DSCP 24
↓
Priority 3
↓
TC3
↓
PFC ON
↓
ECN
을 추가하고, 기존 Cilium traffic은:
Priority 0
TC0
PFC OFF
로 그대로 유지하는 방향이 가장 합리적입니다.
특히 다음 단계에서는 현재 GPU node의 bond1이 이미 LACP 3+4인 상황을 고려해서, Kubespray → OS 설정 → ice/irdma → bond → RoCE → GPU Operator → RDMA Device Plugin을 실제 Kubespray group_vars와 Ansible task까지 포함한 "GPU node 증설 표준 절차"로 만드는 것이 좋습니다. 그러면 지금 1대뿐 아니라 나중에 GPU node가 여러 대 들어올 때 그대로 반복 적용할 수 있습니다.