네. 이 정도 수량이면 앞서의 “소규모 K8s + 몇 개의 특수 노드”가 아니라, 96대급 AI/HPC Kubernetes 인프라로 설계하는 편이 맞습니다.
사진의 HW 사양과 새로 알려주신 수량을 합치면 GPU 12대 / AIStor Storage 30대 / Compute 60대 = 총 102대입니다. 여기서 Compute 5대를 Control Plane/infra 용도로 전용하면 5 CP/Infra + 55 Compute + 12 GPU + 30 Storage 구조를 1차 권고안으로 잡겠습니다.
┌─────────────────────────────┐
│ Kubernetes Cluster │
│ API VIP / LB │
└──────────────┬──────────────┘
│
┌─────────────────────┴──────────────────────┐
│ Control / Infra Plane │
│ │
│ Compute #01 ~ #05 │
│ K8s Control Plane + etcd + Infra │
│ 5 Nodes │
└─────────────────────┬──────────────────────┘
│
100GbE Kubernetes Fabric
│
┌────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ GPU Pool │ │ Compute Pool │ │ AIStor Pool │
│ Dell XE9780 │ │ HPE DL380 G12 │ │ Lenovo SR650 V4│
│ │ │ │ │ │
│ 12 nodes │ │ 55 nodes │ │ 30 nodes │
│ B300 × 96 │ │ 5,280 cores │ │ 22.12 PB RAW │
│ RAM 24 TB │ │ RAM 55 TB │ │ 720 NVMe │
│ NDR400 ×4/node │ │ 100GbE ×4/node │ │ NDR400 ×2/node │
└───────┬────────┘ └─────────────────┘ └───────┬─────────┘
│ │
│ NDR400 AI Fabric │
└───────────────────────┬──────────────────────────┘
│
GPU ↔ AIStor RDMA Path
┌────────────────────────────────┐
│ Dell PowerScale F710 ×5 │
│ External Shared File Storage │
│ ~1.536 PB RAW │
└────────────────────────────────┘
이 구성을 기본안으로 추천합니다.
GPU Pool은 Dell XE9780 12대이므로,
12 Nodes
CPU : 128 cores/node × 12
= 1,536 physical cores
RAM : 2 TB × 12
= 24 TB
GPU : B300 × 8 × 12
= 96 × B300
Local NVMe:
15.36 TB × 12
= 184.32 TB
NDR400:
4 ports × 12
= 48 × 400G ports
입니다.
즉 96 GPU 규모의 B300 클러스터입니다. 이 정도부터는 Kubernetes보다 오히려 GPU Fabric/NCCL topology 설계가 전체 성능을 좌우할 가능성이 큽니다.
Storage Pool은 더 큽니다.
Lenovo SR650 V4 × 30
CPU
128 cores × 30
= 3,840 cores
RAM
768 GB × 30
= 23.04 TB
NVMe
30.72 TB × 24 × 30
= 22,118.4 TB
≈ 22.12 PB RAW
NVMe 수
24 × 30
= 720 NVMe
NDR400
2 × 30
= 60 × 400G ports
100GbE
4 × 30
= 120 × 100G ports
AIStor로 쓰기에 상당히 큰 규모입니다.
Compute 60대는,
96 cores × 60
= 5,760 physical cores
RAM
1 TB × 60
= 60 TB
Local NVMe
15.36 TB × 60
= 921.6 TB
100GbE
4 × 60
= 240 × 100G ports
입니다.
따라서 전체적으로 대략 11,136 CPU physical cores + 96 B300 GPU + 107TB RAM + AIStor 22.1PB raw + PowerScale 1.54PB raw 규모가 됩니다.
처음부터 GPU/Compute/Storage를 Kubernetes Cluster 3개로 나누지는 않겠습니다.
일단:
One Kubernetes Cluster
│
┌────────────────┼────────────────┐
│ │ │
GPU Pool Compute Pool Storage Pool
12 nodes 55 nodes 30 nodes
형태로 시작하는 것을 추천합니다.
총 Node 수가 100여 대 수준이라 Kubernetes 자체가 감당하기 어려운 규모가 아닙니다.
대신 Node Pool / Label / Taint / RuntimeClass / NetworkAttachmentDefinition 등을 이용해서 논리적으로 완전히 분리합니다.
다만 향후 운영 조직/업그레이드 주기/장애 도메인을 Storage와 AI Compute에서 완전히 독립시켜야 한다면 AI Kubernetes와 AIStor Kubernetes를 2개 클러스터로 분리하는 안도 가치가 있습니다. 저는 1-cluster를 기본안, 2-cluster를 비교안으로 PoC에서 검증하겠습니다.
60대 중 5대를 Control Plane 전용으로 지정하는 안을 추천합니다.
HPE DL380 Gen12
cp01
cp02
cp03
cp04
cp05
5대 모두:
kube-apiserver
kube-controller-manager
kube-scheduler
etcd
를 돌리는 stacked etcd 구성이 가장 단순합니다.
Kubernetes는 HA Control Plane에서 3대 이상 및 홀수 구성을 권장하고, stacked-etcd와 external-etcd 두 topology를 지원합니다. Kubernetes
여기서는 100여 Node 규모인데 HPE 서버가 충분하므로 5개 Control Plane이면 좋습니다.
API VIP
│
┌─────────┴─────────┐
│ L4 LoadBalancer │
└─────────┬─────────┘
│
┌──────┬───────┼───────┬──────┐
▼ ▼ ▼ ▼ ▼
CP01 CP02 CP03 CP04 CP05
│ │ │ │ │
etcd etcd etcd etcd etcd
Control Plane에는 일반 workload를 배치하지 않습니다.
node-role.kubernetes.io/control-plane=:NoSchedule
을 유지합니다.
External etcd 3대를 별도로 빼는 것은 이 규모에서는 굳이 필요하지 않다고 봅니다. Kubernetes 공식 문서 역시 stacked topology가 infrastructure가 적게 필요하고 external etcd는 별도 호스트가 필요하다고 설명합니다. Kubernetes
남은 HPE 55대를 전부 똑같이 쓰기보다는 논리적인 Pool을 둡니다.
예를 들면:
Compute 55
├── Infra/System Pool 5
│
└── General Compute Pool 50
Infra Pool에는:
CoreDNS
Ingress
Registry
Monitoring
Prometheus
Grafana
Loki
OpenTelemetry
Argo CD
Operators
Controllers
Job scheduler components
AI platform services
vLLM routing / gateway
같은 것들을 배치합니다.
그러면 B300/AIStor에 Kubernetes 관리 workload가 침범하지 않습니다.
물리적으로는 동일한 HPE이므로 장애가 생기면 Compute Pool에서 쉽게 대체할 수도 있습니다.
12대 XE9780에는 다음 정도의 Label을 권합니다.
node-role.kubernetes.io/gpu=true
accelerator=nvidia-b300
gpu-count=8
gpu-platform=hgx-b300
network-fabric=ndr400
local-storage=nvme
그리고 반드시 Taint:
dedicated=gpu:NoSchedule
를 적용합니다.
결과적으로 GPU workload만 toleration을 가지고 들어옵니다.
GPU01 B300 ×8
GPU02 B300 ×8
...
GPU12 B300 ×8
= 96 B300
NVIDIA GPU Operator를 설치하여 driver/device plugin/DCGM 등의 GPU lifecycle을 Kubernetes에서 관리하는 방향으로 가겠습니다.
여기도:
node-role.kubernetes.io/aistor=true
storage=aistor
disk=nvme-gen5
rdma=true
와
dedicated=aistor:NoSchedule
을 사용합니다.
따라서:
ST01
├ NVMe01
├ ...
└ NVMe24
...
ST30
├ NVMe01
├ ...
└ NVMe24
총 720 NVMe가 AIStor 전용 자원이 됩니다.
여기에는 일반 Kubernetes workload를 절대 배치하지 않는 것을 원칙으로 잡겠습니다.
이게 이번 설계에서 가장 중요한 부분 중 하나입니다.
저라면 최소 3-plane으로 나눕니다.
① Management
② Kubernetes / Service / Storage Ethernet
③ AI High-Speed RDMA Fabric
개념적으로:
┌── Management Network
All Nodes ────────┤
├── 100GbE Service/Data Network
│
└── NDR400 AI Fabric
▲
│
GPU + AIStor
BMC부터 분리합니다.
OOB/BMC
├ Dell iDRAC
├ Lenovo XCC
├ HPE iLO
├ Switch management
└ PowerScale management
가능하면 별도 물리 switch/VLAN으로 격리합니다.
OS Management도 별도 VLAN/Subnet을 두겠습니다.
100GbE는 Kubernetes의 기본 IP Network로 사용합니다.
100GbE Ethernet Fabric
│
┌─────────────────┼─────────────────┐
│ │ │
GPU 12 Compute 60 AIStor 30
│ │ │
└─────────────────┼─────────────────┘
│
PowerScale
여기로:
Kubernetes API
CNI primary network
Pod-to-Pod
Service traffic
Ingress/Egress
Monitoring
Image pull
PowerScale access
AIStor S3 TCP
를 보냅니다.
즉 NDR가 죽어도 Kubernetes 자체는 정상적으로 살아 있어야 합니다.
이 원칙이 중요합니다.
그리고:
GPU Node ×12
│
│ NDR400 ×4
│
▼
┌────────────────────────────┐
│ │
│ NDR400 Fabric │
│ │
└────────────────────────────┘
▲
│ NDR400 ×2
│
AIStor Node ×30
로 구성합니다.
이 Fabric의 목적은:
GPU ↔ GPU
GPU ↔ AIStor
AIStor ↔ AIStor
고속 통신입니다.
GPU 쪽만 해도:
12 × 4 × 400G
= 19.2 Tbps
의 endpoint bandwidth가 있습니다.
Storage 쪽은:
30 × 2 × 400G
= 24 Tbps
입니다.
따라서 이 시스템은 NDR Fabric switch topology와 oversubscription 설계가 상당히 중요합니다.
XE9780의 4개 NDR 포트를 단순히 아무 switch에 연결하지 않고, GPU topology와 NIC affinity를 확인하여 rail을 구성하는 방향을 추천합니다.
개념적으로:
GPU NODE
GPU 0/1 ─ NIC0 ─── Rail A
GPU 2/3 ─ NIC1 ─── Rail B
GPU 4/5 ─ NIC2 ─── Rail C
GPU 6/7 ─ NIC3 ─── Rail D
처럼 보고,
Rail A Rail B Rail C Rail D
│ │ │ │
GPU01 ─────────┼────────────┼────────────┼────────────┤
GPU02 ─────────┼────────────┼────────────┼────────────┤
... │ │ │ │
GPU12 ─────────┼────────────┼────────────┼────────────┤
형태를 검토하겠습니다.
단, 실제 XE9780 B300의 GPU↔NIC PCIe/NVLink affinity를 확인한 뒤 rail을 확정해야 합니다. 논리적인 4-port 균등분배만 보고 케이블링하면 안 됩니다.
AIStor 서버에는 NDR400이 2개 있습니다.
따라서:
Storage01
├ NDR0 ─ Fabric/Rail A
└ NDR1 ─ Fabric/Rail B
Storage02
├ NDR0 ─ Fabric/Rail A
└ NDR1 ─ Fabric/Rail B
...
Storage30
형태가 좋습니다.
AIStor는 현재 Kubernetes Operator에서 RDMA object-data path를 공식 지원하고, multi-NIC에서는 노드의 fabric 주소를 별도로 지정하는 구성도 지원합니다. MinIO AIStor Documentation
즉 이 장비 구성은 상당히 재미있게도
B300
│
│ GPUDirect/RDMA
▼
ConnectX-7
│
│ NDR400 Fabric
▼
ConnectX-7
│
▼
AIStor
│
▼
Gen5 NVMe ×720
라는 데이터 경로를 목표로 설계할 수 있습니다.
NVIDIA도 bare-metal Kubernetes에서 GPUDirect RDMA를 지원하며 GPU Operator와 Network Operator를 함께 사용하는 구성을 제공합니다. NVIDIA Docs
그래서 Kubernetes 내부에서는 Multus/secondary network 계열 구조가 필요합니다.
Pod 관점에서는:
AI Training Pod
│
├── eth0
│ │
│ └── Kubernetes CNI
│ 100GbE
│
└── net1/net2...
│
└── RDMA
│
NDR400
가 됩니다.
즉 Kubernetes CNI 자체를 InfiniBand로 돌리는 게 아닙니다.
Primary Network = Ethernet
Secondary high-performance network = NDR/RDMA
입니다.
NVIDIA Network Operator는 바로 이런 Kubernetes secondary network와 RDMA/GPUDirect RDMA 구성 요소를 관리하는 용도로 제공됩니다. NVIDIA Docs
Primary CNI 후보는 저는 Cilium을 1순위로 놓겠습니다.
구조는:
Primary CNI
│
Cilium
│
100GbE
Secondary
│
Multus / NVIDIA Network Operator
│
SR-IOV / Host Device / RDMA
│
NDR400
정도로 설계합니다.
특히 여기서 Primary CNI가 AI data path를 담당하도록 만들 필요가 없습니다.
RDMA/NCCL/S3 고속 path는 secondary network로 우회시키기 때문에 CNI의 역할이 명확해집니다.
GPU 서버는 100GbE 2포트, Compute/Storage는 4포트이므로 단일 NIC/스위치 의존은 피하겠습니다.
예를 들어:
Leaf A Leaf B
│ │
100GbE 100GbE
│ │
└────── Node ─────┘
형태입니다.
Compute/Storage의 추가 port는 Storage/Data network 분리 여부에 따라 활용합니다.
최종적으로는:
Ethernet Fabric A/B
Leaf Leaf
│ │
┌─────┴─────────────┴─────┐
│ │
Kubernetes Storage
/Service /Data
를 검토합니다.
100G 4포트가 있다고 무조건 400G LAG를 만드는 것보다는 traffic class와 failure domain을 먼저 정의하는 것이 좋습니다.
PowerScale F710 ×5는 지금처럼 Kubernetes Node로 만들지 않습니다.
Kubernetes
│
│ CSI / NFS
▼
PowerScale F710 ×5
External storage입니다.
용도는:
Shared Dataset
Home / Workspace
AI source dataset
Persistent filesystem
Archive/intermediate data
등으로 두겠습니다.
반면 AIStor는:
S3
Object Dataset
Model artifacts
Checkpoint
high-throughput object access
로 역할을 명확하게 나눕니다.
그러면 상당히 좋은 계층이 만들어집니다.
Capacity / Sharing
▲
PowerScale
Shared Dataset
│
│
AIStor
22.1 PB RAW
│
│
GPU Local NVMe
184 TB RAW
│
│
B300
HBM / KV cache
▼
Performance
Compute에도 총 약 922TB Local NVMe가 있기 때문에 필요하다면 별도의 distributed cache / ephemeral storage 계층으로 활용할 수 있습니다.
다만 처음부터 Ceph 같은 또 하나의 storage system을 여기에 넣지는 않겠습니다. 이미 AIStor와 PowerScale이라는 두 개의 강력한 Storage Tier가 있기 때문입니다.
따라서 최종 Kubernetes inventory를 이렇게 잡겠습니다.
| Pool | HW | 수량 | 역할 |
|---|---|---|---|
| Control Plane | HPE DL380 G12 | 5 | K8s + etcd |
| Infra | HPE DL380 G12 | 5 | Monitoring/Ingress/Registry/Operators |
| Compute | HPE DL380 G12 | 50 | CPU workload |
| GPU | Dell XE9780 | 12 | B300 ×96 |
| Storage | Lenovo SR650 V4 | 30 | AIStor, 22.1PB raw |
| External NAS | PowerScale F710 | 5 | Shared FS |
즉 Kubernetes Node는 102대이고, PowerScale 5대는 외부 Storage입니다.
Users / AI Platform
│
Ingress/LB
│
┌─────────────▼──────────────┐
│ Kubernetes Cluster │
│ 102 Nodes │
└─────────────┬──────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
Control/Infra Compute GPU
5 + 5 50 12
HPE DL380 HPE DL380 XE9780
│ │ B300 ×96
│ │ │
└──────────────┬────────┴───────────┬───────────┘
│ │
100GbE Fabric NDR400 Fabric
│ │
│ ┌──────┴───────┐
│ │ │
│ GPU↔GPU GPU↔Storage
│ │
│ ┌──────▼──────┐
│ │ AIStor ×30 │
│ │ NVMe ×720 │
│ │ ~22.1PB RAW │
│ └─────────────┘
│
┌──────▼─────────┐
│ PowerScale ×5 │
│ Shared Dataset │
└────────────────┘
특히 NDR400을 Kubernetes 기본 CNI에 섞지 않는 것이 중요합니다. B300/ConnectX 계열에서 GPU Operator + Network Operator를 조합하면 GPUDirect RDMA를 Kubernetes에서 제공할 수 있고, 현재 NVIDIA 지원표도 Blackwell GPU와 ConnectX를 지원 대상으로 명시하고 있습니다. NVIDIA Docs
다음 설계 단계에서는 이 논리구성을 기반으로 실제 물리 Network Topology를 잡는 게 우선입니다. 즉 100GbE Leaf-Spine 스위치 몇 대 / NDR400 스위치 몇 대 / GPU 4-port rail 배치 / AIStor 2-port 배치 / VLAN·Subnet·MTU / Cilium+Multus / NIC bonding까지 내려가야 합니다. 이 단계에서 스위치 포트 수와 예상 oversubscription까지 계산하면 실제 발주 가능한 수준의 K8s + Network 물리 아키텍처가 됩니다.
네. 이 정도 수량이면 앞서의 “소규모 K8s + 몇 개의 특수 노드”가 아니라, 96대급 AI/HPC Kubernetes 인프라로 설계하는 편이 맞습니다.
사진의 HW 사양과 새로 알려주신 수량을 합치면 GPU 12대 / AIStor Storage 30대 / Compute 60대 = 총 102대입니다. 여기서 Compute 5대를 Control Plane/infra 용도로 전용하면 5 CP/Infra + 55 Compute + 12 GPU + 30 Storage 구조를 1차 권고안으로 잡겠습니다.
┌─────────────────────────────┐
│ Kubernetes Cluster │
│ API VIP / LB │
└──────────────┬──────────────┘
│
┌─────────────────────┴──────────────────────┐
│ Control / Infra Plane │
│ │
│ Compute #01 ~ #05 │
│ K8s Control Plane + etcd + Infra │
│ 5 Nodes │
└─────────────────────┬──────────────────────┘
│
100GbE Kubernetes Fabric
│
┌────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ GPU Pool │ │ Compute Pool │ │ AIStor Pool │
│ Dell XE9780 │ │ HPE DL380 G12 │ │ Lenovo SR650 V4│
│ │ │ │ │ │
│ 12 nodes │ │ 55 nodes │ │ 30 nodes │
│ B300 × 96 │ │ 5,280 cores │ │ 22.12 PB RAW │
│ RAM 24 TB │ │ RAM 55 TB │ │ 720 NVMe │
│ NDR400 ×4/node │ │ 100GbE ×4/node │ │ NDR400 ×2/node │
└───────┬────────┘ └─────────────────┘ └───────┬─────────┘
│ │
│ NDR400 AI Fabric │
└───────────────────────┬──────────────────────────┘
│
GPU ↔ AIStor RDMA Path
┌────────────────────────────────┐
│ Dell PowerScale F710 ×5 │
│ External Shared File Storage │
│ ~1.536 PB RAW │
└────────────────────────────────┘
이 구성을 기본안으로 추천합니다.
GPU Pool은 Dell XE9780 12대이므로,
12 Nodes
CPU : 128 cores/node × 12
= 1,536 physical cores
RAM : 2 TB × 12
= 24 TB
GPU : B300 × 8 × 12
= 96 × B300
Local NVMe:
15.36 TB × 12
= 184.32 TB
NDR400:
4 ports × 12
= 48 × 400G ports
입니다.
즉 96 GPU 규모의 B300 클러스터입니다. 이 정도부터는 Kubernetes보다 오히려 GPU Fabric/NCCL topology 설계가 전체 성능을 좌우할 가능성이 큽니다.
Storage Pool은 더 큽니다.
Lenovo SR650 V4 × 30
CPU
128 cores × 30
= 3,840 cores
RAM
768 GB × 30
= 23.04 TB
NVMe
30.72 TB × 24 × 30
= 22,118.4 TB
≈ 22.12 PB RAW
NVMe 수
24 × 30
= 720 NVMe
NDR400
2 × 30
= 60 × 400G ports
100GbE
4 × 30
= 120 × 100G ports
AIStor로 쓰기에 상당히 큰 규모입니다.
Compute 60대는,
96 cores × 60
= 5,760 physical cores
RAM
1 TB × 60
= 60 TB
Local NVMe
15.36 TB × 60
= 921.6 TB
100GbE
4 × 60
= 240 × 100G ports
입니다.
따라서 전체적으로 대략 11,136 CPU physical cores + 96 B300 GPU + 107TB RAM + AIStor 22.1PB raw + PowerScale 1.54PB raw 규모가 됩니다.
처음부터 GPU/Compute/Storage를 Kubernetes Cluster 3개로 나누지는 않겠습니다.
일단:
One Kubernetes Cluster
│
┌────────────────┼────────────────┐
│ │ │
GPU Pool Compute Pool Storage Pool
12 nodes 55 nodes 30 nodes
형태로 시작하는 것을 추천합니다.
총 Node 수가 100여 대 수준이라 Kubernetes 자체가 감당하기 어려운 규모가 아닙니다.
대신 Node Pool / Label / Taint / RuntimeClass / NetworkAttachmentDefinition 등을 이용해서 논리적으로 완전히 분리합니다.
다만 향후 운영 조직/업그레이드 주기/장애 도메인을 Storage와 AI Compute에서 완전히 독립시켜야 한다면 AI Kubernetes와 AIStor Kubernetes를 2개 클러스터로 분리하는 안도 가치가 있습니다. 저는 1-cluster를 기본안, 2-cluster를 비교안으로 PoC에서 검증하겠습니다.
60대 중 5대를 Control Plane 전용으로 지정하는 안을 추천합니다.
HPE DL380 Gen12
cp01
cp02
cp03
cp04
cp05
5대 모두:
kube-apiserver
kube-controller-manager
kube-scheduler
etcd
를 돌리는 stacked etcd 구성이 가장 단순합니다.
Kubernetes는 HA Control Plane에서 3대 이상 및 홀수 구성을 권장하고, stacked-etcd와 external-etcd 두 topology를 지원합니다. Kubernetes
여기서는 100여 Node 규모인데 HPE 서버가 충분하므로 5개 Control Plane이면 좋습니다.
API VIP
│
┌─────────┴─────────┐
│ L4 LoadBalancer │
└─────────┬─────────┘
│
┌──────┬───────┼───────┬──────┐
▼ ▼ ▼ ▼ ▼
CP01 CP02 CP03 CP04 CP05
│ │ │ │ │
etcd etcd etcd etcd etcd
Control Plane에는 일반 workload를 배치하지 않습니다.
node-role.kubernetes.io/control-plane=:NoSchedule
을 유지합니다.
External etcd 3대를 별도로 빼는 것은 이 규모에서는 굳이 필요하지 않다고 봅니다. Kubernetes 공식 문서 역시 stacked topology가 infrastructure가 적게 필요하고 external etcd는 별도 호스트가 필요하다고 설명합니다. Kubernetes
남은 HPE 55대를 전부 똑같이 쓰기보다는 논리적인 Pool을 둡니다.
예를 들면:
Compute 55
├── Infra/System Pool 5
│
└── General Compute Pool 50
Infra Pool에는:
CoreDNS
Ingress
Registry
Monitoring
Prometheus
Grafana
Loki
OpenTelemetry
Argo CD
Operators
Controllers
Job scheduler components
AI platform services
vLLM routing / gateway
같은 것들을 배치합니다.
그러면 B300/AIStor에 Kubernetes 관리 workload가 침범하지 않습니다.
물리적으로는 동일한 HPE이므로 장애가 생기면 Compute Pool에서 쉽게 대체할 수도 있습니다.
12대 XE9780에는 다음 정도의 Label을 권합니다.
node-role.kubernetes.io/gpu=true
accelerator=nvidia-b300
gpu-count=8
gpu-platform=hgx-b300
network-fabric=ndr400
local-storage=nvme
그리고 반드시 Taint:
dedicated=gpu:NoSchedule
를 적용합니다.
결과적으로 GPU workload만 toleration을 가지고 들어옵니다.
GPU01 B300 ×8
GPU02 B300 ×8
...
GPU12 B300 ×8
= 96 B300
NVIDIA GPU Operator를 설치하여 driver/device plugin/DCGM 등의 GPU lifecycle을 Kubernetes에서 관리하는 방향으로 가겠습니다.
여기도:
node-role.kubernetes.io/aistor=true
storage=aistor
disk=nvme-gen5
rdma=true
와
dedicated=aistor:NoSchedule
을 사용합니다.
따라서:
ST01
├ NVMe01
├ ...
└ NVMe24
...
ST30
├ NVMe01
├ ...
└ NVMe24
총 720 NVMe가 AIStor 전용 자원이 됩니다.
여기에는 일반 Kubernetes workload를 절대 배치하지 않는 것을 원칙으로 잡겠습니다.
이게 이번 설계에서 가장 중요한 부분 중 하나입니다.
저라면 최소 3-plane으로 나눕니다.
① Management
② Kubernetes / Service / Storage Ethernet
③ AI High-Speed RDMA Fabric
개념적으로:
┌── Management Network
All Nodes ────────┤
├── 100GbE Service/Data Network
│
└── NDR400 AI Fabric
▲
│
GPU + AIStor
BMC부터 분리합니다.
OOB/BMC
├ Dell iDRAC
├ Lenovo XCC
├ HPE iLO
├ Switch management
└ PowerScale management
가능하면 별도 물리 switch/VLAN으로 격리합니다.
OS Management도 별도 VLAN/Subnet을 두겠습니다.
100GbE는 Kubernetes의 기본 IP Network로 사용합니다.
100GbE Ethernet Fabric
│
┌─────────────────┼─────────────────┐
│ │ │
GPU 12 Compute 60 AIStor 30
│ │ │
└─────────────────┼─────────────────┘
│
PowerScale
여기로:
Kubernetes API
CNI primary network
Pod-to-Pod
Service traffic
Ingress/Egress
Monitoring
Image pull
PowerScale access
AIStor S3 TCP
를 보냅니다.
즉 NDR가 죽어도 Kubernetes 자체는 정상적으로 살아 있어야 합니다.
이 원칙이 중요합니다.
그리고:
GPU Node ×12
│
│ NDR400 ×4
│
▼
┌────────────────────────────┐
│ │
│ NDR400 Fabric │
│ │
└────────────────────────────┘
▲
│ NDR400 ×2
│
AIStor Node ×30
로 구성합니다.
이 Fabric의 목적은:
GPU ↔ GPU
GPU ↔ AIStor
AIStor ↔ AIStor
고속 통신입니다.
GPU 쪽만 해도:
12 × 4 × 400G
= 19.2 Tbps
의 endpoint bandwidth가 있습니다.
Storage 쪽은:
30 × 2 × 400G
= 24 Tbps
입니다.
따라서 이 시스템은 NDR Fabric switch topology와 oversubscription 설계가 상당히 중요합니다.
XE9780의 4개 NDR 포트를 단순히 아무 switch에 연결하지 않고, GPU topology와 NIC affinity를 확인하여 rail을 구성하는 방향을 추천합니다.
개념적으로:
GPU NODE
GPU 0/1 ─ NIC0 ─── Rail A
GPU 2/3 ─ NIC1 ─── Rail B
GPU 4/5 ─ NIC2 ─── Rail C
GPU 6/7 ─ NIC3 ─── Rail D
처럼 보고,
Rail A Rail B Rail C Rail D
│ │ │ │
GPU01 ─────────┼────────────┼────────────┼────────────┤
GPU02 ─────────┼────────────┼────────────┼────────────┤
... │ │ │ │
GPU12 ─────────┼────────────┼────────────┼────────────┤
형태를 검토하겠습니다.
단, 실제 XE9780 B300의 GPU↔NIC PCIe/NVLink affinity를 확인한 뒤 rail을 확정해야 합니다. 논리적인 4-port 균등분배만 보고 케이블링하면 안 됩니다.
AIStor 서버에는 NDR400이 2개 있습니다.
따라서:
Storage01
├ NDR0 ─ Fabric/Rail A
└ NDR1 ─ Fabric/Rail B
Storage02
├ NDR0 ─ Fabric/Rail A
└ NDR1 ─ Fabric/Rail B
...
Storage30
형태가 좋습니다.
AIStor는 현재 Kubernetes Operator에서 RDMA object-data path를 공식 지원하고, multi-NIC에서는 노드의 fabric 주소를 별도로 지정하는 구성도 지원합니다. MinIO AIStor Documentation
즉 이 장비 구성은 상당히 재미있게도
B300
│
│ GPUDirect/RDMA
▼
ConnectX-7
│
│ NDR400 Fabric
▼
ConnectX-7
│
▼
AIStor
│
▼
Gen5 NVMe ×720
라는 데이터 경로를 목표로 설계할 수 있습니다.
NVIDIA도 bare-metal Kubernetes에서 GPUDirect RDMA를 지원하며 GPU Operator와 Network Operator를 함께 사용하는 구성을 제공합니다. NVIDIA Docs
그래서 Kubernetes 내부에서는 Multus/secondary network 계열 구조가 필요합니다.
Pod 관점에서는:
AI Training Pod
│
├── eth0
│ │
│ └── Kubernetes CNI
│ 100GbE
│
└── net1/net2...
│
└── RDMA
│
NDR400
가 됩니다.
즉 Kubernetes CNI 자체를 InfiniBand로 돌리는 게 아닙니다.
Primary Network = Ethernet
Secondary high-performance network = NDR/RDMA
입니다.
NVIDIA Network Operator는 바로 이런 Kubernetes secondary network와 RDMA/GPUDirect RDMA 구성 요소를 관리하는 용도로 제공됩니다. NVIDIA Docs
Primary CNI 후보는 저는 Cilium을 1순위로 놓겠습니다.
구조는:
Primary CNI
│
Cilium
│
100GbE
Secondary
│
Multus / NVIDIA Network Operator
│
SR-IOV / Host Device / RDMA
│
NDR400
정도로 설계합니다.
특히 여기서 Primary CNI가 AI data path를 담당하도록 만들 필요가 없습니다.
RDMA/NCCL/S3 고속 path는 secondary network로 우회시키기 때문에 CNI의 역할이 명확해집니다.
GPU 서버는 100GbE 2포트, Compute/Storage는 4포트이므로 단일 NIC/스위치 의존은 피하겠습니다.
예를 들어:
Leaf A Leaf B
│ │
100GbE 100GbE
│ │
└────── Node ─────┘
형태입니다.
Compute/Storage의 추가 port는 Storage/Data network 분리 여부에 따라 활용합니다.
최종적으로는:
Ethernet Fabric A/B
Leaf Leaf
│ │
┌─────┴─────────────┴─────┐
│ │
Kubernetes Storage
/Service /Data
를 검토합니다.
100G 4포트가 있다고 무조건 400G LAG를 만드는 것보다는 traffic class와 failure domain을 먼저 정의하는 것이 좋습니다.
PowerScale F710 ×5는 지금처럼 Kubernetes Node로 만들지 않습니다.
Kubernetes
│
│ CSI / NFS
▼
PowerScale F710 ×5
External storage입니다.
용도는:
Shared Dataset
Home / Workspace
AI source dataset
Persistent filesystem
Archive/intermediate data
등으로 두겠습니다.
반면 AIStor는:
S3
Object Dataset
Model artifacts
Checkpoint
high-throughput object access
로 역할을 명확하게 나눕니다.
그러면 상당히 좋은 계층이 만들어집니다.
Capacity / Sharing
▲
PowerScale
Shared Dataset
│
│
AIStor
22.1 PB RAW
│
│
GPU Local NVMe
184 TB RAW
│
│
B300
HBM / KV cache
▼
Performance
Compute에도 총 약 922TB Local NVMe가 있기 때문에 필요하다면 별도의 distributed cache / ephemeral storage 계층으로 활용할 수 있습니다.
다만 처음부터 Ceph 같은 또 하나의 storage system을 여기에 넣지는 않겠습니다. 이미 AIStor와 PowerScale이라는 두 개의 강력한 Storage Tier가 있기 때문입니다.
따라서 최종 Kubernetes inventory를 이렇게 잡겠습니다.
| Pool | HW | 수량 | 역할 |
|---|---|---|---|
| Control Plane | HPE DL380 G12 | 5 | K8s + etcd |
| Infra | HPE DL380 G12 | 5 | Monitoring/Ingress/Registry/Operators |
| Compute | HPE DL380 G12 | 50 | CPU workload |
| GPU | Dell XE9780 | 12 | B300 ×96 |
| Storage | Lenovo SR650 V4 | 30 | AIStor, 22.1PB raw |
| External NAS | PowerScale F710 | 5 | Shared FS |
즉 Kubernetes Node는 102대이고, PowerScale 5대는 외부 Storage입니다.
Users / AI Platform
│
Ingress/LB
│
┌─────────────▼──────────────┐
│ Kubernetes Cluster │
│ 102 Nodes │
└─────────────┬──────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
Control/Infra Compute GPU
5 + 5 50 12
HPE DL380 HPE DL380 XE9780
│ │ B300 ×96
│ │ │
└──────────────┬────────┴───────────┬───────────┘
│ │
100GbE Fabric NDR400 Fabric
│ │
│ ┌──────┴───────┐
│ │ │
│ GPU↔GPU GPU↔Storage
│ │
│ ┌──────▼──────┐
│ │ AIStor ×30 │
│ │ NVMe ×720 │
│ │ ~22.1PB RAW │
│ └─────────────┘
│
┌──────▼─────────┐
│ PowerScale ×5 │
│ Shared Dataset │
└────────────────┘
특히 NDR400을 Kubernetes 기본 CNI에 섞지 않는 것이 중요합니다. B300/ConnectX 계열에서 GPU Operator + Network Operator를 조합하면 GPUDirect RDMA를 Kubernetes에서 제공할 수 있고, 현재 NVIDIA 지원표도 Blackwell GPU와 ConnectX를 지원 대상으로 명시하고 있습니다. NVIDIA Docs
다음 설계 단계에서는 이 논리구성을 기반으로 실제 물리 Network Topology를 잡는 게 우선입니다. 즉 100GbE Leaf-Spine 스위치 몇 대 / NDR400 스위치 몇 대 / GPU 4-port rail 배치 / AIStor 2-port 배치 / VLAN·Subnet·MTU / Cilium+Multus / NIC bonding까지 내려가야 합니다. 이 단계에서 스위치 포트 수와 예상 oversubscription까지 계산하면 실제 발주 가능한 수준의 K8s + Network 물리 아키텍처가 됩니다.
이 규모와 용도를 기준으로 보면 한 개의 Kubernetes 클러스터에 전부 넣기보다는 분리하는 쪽을 권장합니다. 다만 GPU/Compute/Storage를 무조건 3개로 쪼개기보다는, “AI Compute Cluster”와 “AIStor Storage Cluster”의 2-Cluster 구조가 가장 균형이 좋습니다.
┌───────────────────────────────┐
│ AI Platform / Users │
└───────────────┬───────────────┘
│
100GbE IP Fabric
│
┌──────────────────────┴──────────────────────┐
│ │
▼ ▼
┌────────────────────────────┐ ┌───────────────────────────┐
│ AI Compute K8s Cluster │ │ AIStor K8s Cluster │
│ │ │ │
│ Control Plane : HPE ×5 │ │ Control Plane : 별도 권장 │
│ Infra : HPE ×5 │ │ │
│ Compute : HPE ×45~50 │ │ Lenovo Storage ×30 │
│ GPU : XE9780 ×12 │ │ NVMe ×720 │
│ │ │ ~22.1 PB RAW │
│ B300 ×96 │ │ │
└──────────────┬─────────────┘ └─────────────┬─────────────┘
│ │
└──────────── NDR400 Fabric ────────────────┘
GPU ↔ AIStor RDMA
제가 2-cluster를 선호하는 가장 큰 이유는 AIStor 30대/22PB급 Storage가 단순한 Kubernetes workload가 아니라 하나의 독립적인 인프라 서비스이기 때문입니다.
한 클러스터라면 Kubernetes control-plane 장애, CNI 문제, 인증서/업그레이드 사고, 잘못된 admission policy 등이 GPU/Compute와 Storage를 동시에 영향 줄 수 있습니다. 반대로 분리하면 AI Compute K8s를 업그레이드하거나 장애가 나도 AIStor의 S3 서비스 자체는 별도 failure domain으로 유지할 수 있습니다.
| 항목 | 단일 Cluster | 2 Cluster: Compute+GPU / AIStor | 3 Cluster: GPU / Compute / AIStor |
|---|---|---|---|
| 운영 단순성 | ★★★★★ | ★★★★☆ | ★★☆☆☆ |
| 장애 격리 | ★★☆☆☆ | ★★★★★ | ★★★★★ |
| Storage 안정성 | ★★☆☆☆ | ★★★★★ | ★★★★★ |
| GPU↔Compute 연계 | ★★★★★ | ★★★★★ | ★★★☆☆ |
| 업그레이드 독립성 | ★★☆☆☆ | ★★★★★ | ★★★★★ |
| 자원 활용 | ★★★★★ | ★★★★☆ | ★★★☆☆ |
| 정책/보안 분리 | ★★☆☆☆ | ★★★★★ | ★★★★★ |
| 운영 복잡도 | 낮음 | 중간 | 높음 |
| 이번 환경 적합성 | 보통 | 가장 추천 | 과도함 |
특히 GPU와 Compute는 같은 Cluster에 두는 것이 좋습니다. AI workflow 하나가 CPU preprocessing → GPU training/inference → CPU postprocessing으로 이어지는 경우가 많고, Kubernetes scheduler/Job/Workflow 관점에서도 한 Cluster에 있는 것이 편합니다.
반면 AIStor는 API가 S3이기 때문에 애플리케이션 관점에서는 반드시 동일한 Kubernetes Cluster일 필요가 없습니다.
Compute 60대가 있으므로 일부를 떼면 됩니다.
제가 선택한다면:
HPE Compute 60대
│
├── AI Compute Control Plane 3대
│
├── AIStor Control Plane 3대
│
├── Infra/System 4대
│
└── General Compute 50대
로 시작하겠습니다.
앞서 단일 클러스터에서는 CP 5대를 제안했지만 2-cluster로 나누면 각각 CP 3대가 더 합리적입니다.
결과적으로:
Cluster #1 : AI Compute
Control Plane HPE 3
Infra HPE 4
Compute HPE 50
GPU XE9780 12
────────────────────────────
Total 69
Cluster #2 : AIStor
Control Plane HPE 3
Storage Lenovo 30
────────────────────────────
Total 33
전체 = 102 Kubernetes nodes
가 됩니다.
여기서 AIStor의 Control Plane을 Storage Lenovo 30대 중 3대에 같이 올리는 것보다는 HPE 3대를 떼어주는 것을 추천합니다. Storage data plane 장애/부하와 Kubernetes control plane을 분리할 수 있기 때문입니다.
중요한 포인트입니다.
Kubernetes Cluster를 나눈다고 Network Fabric까지 물리적으로 완전히 분리할 필요는 없습니다.
오히려:
Physical Network
│
┌────────────────┴────────────────┐
│ │
100GbE Ethernet NDR400 Fabric
│ │
┌───────┴────────┐ ┌───────┴────────┐
│ │ │ │
Compute K8s AIStor K8s B300 GPU AIStor
│ │ │ │
└──── IP/S3 ─────┘ └──── RDMA ──────┘
처럼 가져가면 됩니다.
즉 Cluster boundary와 Network boundary를 동일하게 생각하면 안 됩니다.
논리적으로는:
AI Compute Cluster
Pod CIDR 10.10.0.0/16
Service CIDR 10.11.0.0/16
AIStor Cluster
Pod CIDR 10.20.0.0/16
Service CIDR 10.21.0.0/16
Storage S3 VIP
10.30.x.x
Management
10.40.x.x
RDMA / NDR
별도 Fabric/Subnet
같은 식으로 완전히 충돌하지 않도록 IP plan을 잡습니다.
AI Compute Pod가 Storage Cluster 내부 구조를 알아서는 안 됩니다.
Training Pod
│
│ S3
▼
s3-aistor.company.internal
│
▼
S3 VIP/LB
│
┌────┴──────────────┐
│ AIStor Cluster │
│ │
│ Storage01 ... 30 │
└───────────────────┘
이렇게 해야 AIStor Cluster를 업그레이드하거나 노드를 교체해도 AI application에서는 동일 endpoint만 봅니다.
이 부분은 나중에 vLLM/LMCache/MemKV 실험에서도 중요합니다. remote object storage를 Kubernetes 내부 Service 이름에 종속시키지 않고 독립 S3 endpoint로 정의해 두는 게 좋습니다.
예를 들어 이런 pipeline이 있다고 해보겠습니다.
Data ingestion
│
▼
CPU preprocessing
│
▼
GPU Training
│
▼
Checkpoint → AIStor
│
▼
Evaluation
│
▼
vLLM serving
GPU와 Compute가 같은 Kubernetes에 있으면 scheduler 관점에서:
nodeSelector:
workload: cpu
또는
nodeSelector:
accelerator: nvidia-b300
만 바꾸면 됩니다.
Argo Workflow/Ray/Kubeflow 계열을 쓰더라도 하나의 workflow가 두 Pool을 자연스럽게 사용할 수 있습니다.
따라서:
AI Compute Cluster
│
┌────────┴────────┐
│ │
CPU Pool GPU Pool
HPE ×50 XE9780 ×12
│
B300 ×96
이 조합은 유지하는 것이 좋습니다.
향후 GPU가 12대에서 예를 들어 50~100대로 늘어나거나, 조직적으로 Training과 일반 Compute 운영 주체가 완전히 달라진다면:
Cluster A
GPU / AI Training
Cluster B
CPU / General Compute
Cluster C
AIStor
도 의미가 생깁니다.
하지만 지금부터 이렇게 나누면 Cross-cluster scheduling/workflow, monitoring, secrets, registry, IAM, observability, GitOps가 전부 복잡해집니다.
현재 12 GPU nodes / 60 Compute nodes 규모에서는 그 복잡성을 감수할 이득이 크지 않다고 봅니다.
오히려 GPU/Compute를 나누는 것보다 이쪽을 고민하는 게 더 중요합니다.
제가 실제 설계한다면 최종적으로는 다음 방향까지 열어 놓겠습니다.
┌─────────────────────┐
│ Management / GitOps │
└──────────┬──────────┘
│
┌─────────────────┴─────────────────┐
│ │
Production AI Cluster Test / Validation
│
┌──────┴──────┐
│ │
Compute Pool GPU Pool
┌───────────────────────────────────┐
│
Production AIStor Cluster
│
Storage ×30
특히 B300 driver, CUDA, NCCL, GPU Operator, Network Operator, OFED/DOCA, CNI 같은 구성은 버전 변화가 전체 AI 환경에 영향을 줄 수 있기 때문에 몇 대를 validation/canary 대상으로 운영하는 전략이 필요합니다.
반드시 별도 영구 K8s cluster일 필요는 없지만 이 영역은 처음부터 설계해 두는 게 좋습니다.
이번 HW에서는 저는 2 Kubernetes Cluster로 확정하는 쪽에 한 표입니다.
┌──────────────────────┐
│ AI Compute Cluster │
│ │
│ CP HPE ×3 │
│ Infra HPE ×4 │
│ Compute HPE ×50 │
│ GPU XE9780 ×12 │
│ B300 ×96 │
└──────────┬───────────┘
│
100GbE + NDR400
│
┌──────────▼───────────┐
│ AIStor Cluster │
│ │
│ CP HPE ×3 │
│ Storage Lenovo ×30 │
│ NVMe ×720 │
│ RAW ~22.1PB │
└──────────────────────┘
PowerScale ×5 = External Shared Storage
“Workload 성격”이 아니라 “failure domain” 기준으로 나눈다고 생각하면 결정하기 쉽습니다. GPU와 CPU Compute는 하나의 AI workload domain이므로 합치고, AIStor는 22PB 규모의 독립적인 persistent infrastructure이므로 Kubernetes lifecycle 자체를 분리하는 것이 좋습니다.
그리고 두 Cluster가 100GbE와 NDR400 물리 Fabric은 공유하되, VLAN/VRF/Subnet/Pod CIDR/Service CIDR은 분리하는 방향으로 가는 게 제가 보기에는 현재 장비에서 가장 균형 잡힌 아키텍처입니다.
네. Cilium native routing + BGP + ECMP + ClusterMesh를 전제로 해도 2-Cluster 구성이 더 적합하다고 봅니다. 오히려 그 네트워크 구조라면 2개 클러스터의 단점인 “클러스터 간 네트워크 경계”가 상당 부분 사라지기 때문에, AI Compute(GPU+CPU) / AIStor(Storage) 분리가 더 매력적입니다.
다만 한 가지 중요한 수정이 있습니다. ClusterMesh를 쓴다고 두 클러스터를 하나처럼 강하게 결합하면 Storage 장애 격리라는 분리 목적이 약해집니다. 따라서 ClusterMesh는 선택적으로 활용하고, AIStor의 주 데이터 접근은 routable S3/RDMA endpoint 중심으로 설계하는 것을 권합니다.
┌──────────────── Physical Fabric ────────────────┐
│ │
100/400GbE L3 Fabric NDR400 Fabric
BGP + ECMP RDMA / NCCL
│ │
┌────────┴─────────┐ ┌─────────────┴──────┐
│ │ │ │
▼ ▼ ▼ ▼
┌────────────────┐ ┌─────────────────┐ GPU ×12 AIStor ×30
│ Cluster #1 │ │ Cluster #2 │
│ AI Compute │ │ AIStor │
│ │ │ │
│ CP ×3 │ │ CP ×3 │
│ Infra ×4 │ │ Storage ×30 │
│ Compute ×50 │ │ │
│ GPU ×12 │ │ │
└───────┬────────┘ └────────┬────────┘
│ │
│ Cilium Native │
│ BGP / ECMP │
└─────────┬─────────┘
│
optional ClusterMesh
이 경우 underlay가 이미 두 클러스터를 L3로 연결하고, Cilium native routing에서는 네트워크가 Pod 주소를 직접 라우팅할 수 있어야 합니다. Cilium BGP Control Plane은 Pod/Service route를 외부 router에 advertise할 수 있습니다. Cilium 문서
그래서 overlay/VXLAN 환경보다 2-cluster의 networking penalty가 훨씬 작습니다.
| 항목 | 1 Cluster | 2 Cluster | 3 Cluster |
|---|---|---|---|
| 장애 격리 | ★★ | ★★★★★ | ★★★★★ |
| GPU↔CPU workflow | ★★★★★ | ★★★★★ | ★★★ |
| GPU↔AIStor | ★★★★★ | ★★★★½ | ★★★★½ |
| Cilium/BGP 운영 | ★★★★ | ★★★★ | ★★★ |
| ClusterMesh 복잡도 | 없음 | 낮음 | 높음 |
| Upgrade 독립성 | ★★ | ★★★★★ | ★★★★★ |
| AIStor 안정성 | ★★ | ★★★★★ | ★★★★★ |
| 자원 활용성 | ★★★★★ | ★★★★½ | ★★★★ |
| 운영 복잡도 | 가장 낮음 | 적절 | 높음 |
| 종합 | ★★★½ | ★★★★★ | ★★★½ |
특히 GPU와 Compute를 3번째 Cluster로 분리해서 얻는 네트워크상의 이득이 거의 없습니다.
오히려 GPU/CPU 사이에 ClusterMesh dependency를 하나 더 만드는 결과가 됩니다.
GPU와 CPU workload는 scheduling domain이 같습니다.
예를 들어:
AI Compute Cluster
┌──────────────┴──────────────┐
│ │
Compute Pool GPU Pool
HPE ×50 XE9780 ×12
│ B300 ×96
│ │
└────── Same Scheduler ───────┘
preprocessing
↓
distributed
training
↓
inference
↓
postprocessing
여기서는 Cilium/BGP가 해결할 수 없는 Kubernetes 차원의 문제가 있습니다.
BGP는 routing을 해결하지만 scheduling을 해결하지 않습니다.
3개 Cluster로 나누면 CPU→GPU workflow에서 cross-cluster Job orchestration, Service discovery, secrets, RBAC, monitoring, GitOps 등이 추가됩니다.
GPU와 CPU를 같은 cluster에 두면 이런 복잡성이 없습니다.
AIStor는 Kubernetes scheduler domain을 공유할 이유가 별로 없기 때문입니다.
AI Compute가 원하는 것은 결국:
S3 endpoint
↓
AIStor
입니다.
AIStor 내부 Pod를 AI Compute Kubernetes scheduler가 scheduling할 이유가 없습니다.
그리고 Storage는 lifecycle이 다릅니다.
AI Compute
────────────────
CUDA
GPU Driver
GPU Operator
Network Operator
NCCL
vLLM
PyTorch
Ray
K8s Upgrade
AIStor
────────────────
AIStor version
NVMe firmware
Erasure coding
Storage maintenance
Storage Operator
K8s Upgrade
이 두 lifecycle을 묶어서 얻는 이점보다 분리해서 얻는 안정성이 큽니다.
예를 들어 IP Plan을 처음부터 이렇게 잡습니다.
Infrastructure supernet
10.0.0.0/8
AI Compute Cluster
────────────────────────
Node 10.10.0.0/16
Pod 10.20.0.0/14
Service 10.24.0.0/16
AIStor Cluster
────────────────────────
Node 10.30.0.0/16
Pod 10.32.0.0/14
Service 10.36.0.0/16
External Service/VIP
────────────────────────
10.40.0.0/16
실제 CIDR 크기는 예상 최대 Pod 수를 계산해서 다시 산정해야 하지만 핵심은 절대 overlap시키지 않는 것입니다.
ClusterMesh는 각 클러스터의 PodCIDR이 unique/non-overlapping이어야 하고, native-routing ClusterMesh에서는 native routing CIDR이 연결된 모든 클러스터의 PodCIDR을 포함해야 합니다. Cilium 문서
예를 들어 상위 10.0.0.0/8을 native routing 범위로 잡고 하위 CIDR을 계획적으로 할당하는 방식이 가능합니다.
Leaf-Spine을 가정하면 저는 다음 형태를 선호합니다.
Spine01 Spine02
▲ ▲
│ ECMP │
┌──────┴────────────────┴──────┐
│ │
Leaf01 Leaf02
/ \ / \
/ \ / \
100/400G 100/400G 100/400G 100/400G
│ │ │ │
Node01 Node02 Node03 Node04
│ │ │ │
Cilium Cilium Cilium Cilium
│ │ │ │
└──────────── BGP ────────────────┘
Cilium BGP가 필요한 Pod/Service prefix를 fabric에 advertise하고,
Pod / Service Prefix
│
BGP
▼
Leaf / Spine
│
ECMP
┌────┴────┐
▼ ▼
Node A Node B
형태로 전달합니다.
단, 중요한 점은 Cilium BGP Control Plane 자체가 intra-cluster datapath를 만드는 것은 아니라는 것입니다. 공식 문서도 BGP Control Plane은 route advertisement를 담당하며 datapath를 직접 프로그래밍하지 않는다고 명시합니다. Cilium 문서
즉 설계할 때 Native Routing, BGP advertisement, Service advertisement, ECMP의 역할을 각각 구분해야 합니다.
여기서 제가 강조하고 싶은 부분입니다.
ClusterMesh가 있으니:
AI Compute K8s
│
ClusterMesh
│
AIStor K8s
를 모든 통신의 기본 경로로 만들 필요는 없습니다.
ClusterMesh가 제공하는 것은 cross-cluster Pod-to-Pod connectivity, service discovery/load-balancing, cluster-aware policy 같은 기능입니다. Cilium 문서
따라서 예를 들어 관리/모니터링 계층에서는 유용합니다.
AI Compute Cluster
│
│ ClusterMesh
│
├── monitoring
├── internal service discovery
└── selected management services
│
AIStor Cluster
하지만 실제 수십 PB AIStor data path는:
Training Pod
│
│ S3 / RDMA
▼
AIStor Endpoint
│
▼
AIStor Storage Nodes
처럼 명시적인 Storage endpoint로 접근시키는 것을 선호합니다.
ClusterMesh에 대해 반드시 알고 있어야 할 사항도 있습니다.
Cilium 공식 문서는 ClusterMesh에 연결된 모든 cluster가 하나의 trust domain을 형성하며, 서로 신뢰하고 동등한 security posture를 가진 cluster만 연결하라고 명시합니다. Cilium 문서
그래서 저는 ClusterMesh를 다음처럼 생각합니다.
Kubernetes Failure Domain
Cluster A Cluster B
AI Compute AIStor
│ │
│ │
└────── ClusterMesh ───────┘
│
Connectivity Layer
↑ ↑
독립 CP 독립 CP
독립 etcd 독립 etcd
독립 Cilium 독립 Cilium
ClusterMesh는 Kubernetes Cluster를 합치는 기술이 아니라 독립 Cluster 사이의 networking/service 기능을 연결하는 기술로 사용하는 것입니다.
그러면 한쪽 Kubernetes API/control plane 문제가 다른 쪽 control plane 자체까지 죽이지 않습니다.
3개로 하면:
GPU Cluster
│
│
ClusterMesh
│
Compute Cluster
│
│
ClusterMesh
│
AIStor Cluster
가 됩니다.
그러면 cross-cluster dependency가 늘어납니다.
반면 2개면:
AI Compute
┌──────────────┐
│ CPU GPU │
│ 50 12 │
└──────┬───────┘
│
ClusterMesh
+ BGP/ECMP
│
┌──────▼───────┐
│ AIStor │
│ ×30 │
└──────────────┘
이므로 훨씬 단순합니다.
또 하나 중요한 것은 Cilium ClusterMesh/BGP fabric과 NDR400 RDMA fabric을 논리적으로 분리해서 생각해야 한다는 것입니다.
제가 권하는 구조는:
APPLICATION / K8S
│
Cilium ClusterMesh
│
BGP + ECMP
│
100/400GbE IP Fabric
│
───────────────────
│
DATA PLANE
│
NDR400
│
RDMA / GPUDirect
│
GPU ←────────→ AIStor
입니다.
즉,
Cilium native+BGP = Kubernetes IP connectivity
ClusterMesh = Cross-cluster service/policy/connectivity
NDR400 = AI high-performance data plane
으로 역할을 분리합니다.
이 셋을 하나로 합치려고 하지 않는 것이 설계를 훨씬 안정적으로 만듭니다.
L3 Leaf-Spine
BGP + ECMP
│
┌────────────┴────────────┐
│ │
▼ ▼
AI COMPUTE CLUSTER AISTOR CLUSTER
================== ==============
CP ×3 CP ×3
Infra ×4 Storage ×30
Compute ×50
GPU ×12
B300 ×96
Cilium Native Cilium Native
BGP Control Plane BGP Control Plane
Hubble Hubble
│ │
└──── ClusterMesh ────────┘
(선택적 사용)
└──────────┬──────────────┘
│
NDR400 Fabric
│
GPU ←─ RDMA ─→ AIStor
PowerScale F710 ×5
│
100GbE IP
│
External Shared Filesystem
따라서 질문에 대한 답은 “네, Cilium Native Routing + BGP + ECMP + ClusterMesh 환경이어도 2-Cluster가 더 유리하다”입니다.
오히려 이 네트워크 아키텍처 덕분에 2개로 분리하면서 얻는 failure-domain/lifecycle 격리는 유지하고, 분리로 발생하는 network/service-connectivity 단점은 크게 줄일 수 있습니다.
다만 저는 ClusterMesh를 AIStor 데이터 접근의 필수 dependency로 만들지는 않겠습니다. 이게 이 설계에서 꽤 중요한 원칙입니다. AIStor는 routable S3/RDMA endpoint로 독립적으로 접근 가능하게 하고, ClusterMesh는 필요한 cross-cluster service discovery/policy/management connectivity에 제한적으로 사용하는 것이 좋습니다.
네. 이번에는 논리 아키텍처보다 한 단계 내려가서 실제 케이블링/BOM을 산정할 수 있는 수준의 물리 Network Topology 초안으로 잡아보겠습니다.
현재 장비 기준으로는 저는 ① OOB 관리망, ② 100GbE IP/Kubernetes Fabric, ③ NDR400 RDMA Fabric의 3개 물리 Fabric으로 분리하겠습니다. 특히 NDR400은 GPU 48포트와 AIStor 60포트를 가지고 있으므로 단순 ToR가 아니라 rail-aware + dual-plane 구조로 설계하는 것이 핵심입니다. NVIDIA의 최신 AI Factory RA도 GPU East-West RDMA fabric과 CPU/Storage North-South fabric, OOB를 별도 역할로 분리하고 GPU fabric에는 rail-optimized leaf-spine을 사용합니다. NVIDIA Docs
제가 권하는 목표 구조는 이것입니다.
┌────────────────────────┐
│ DC / Enterprise Core │
└───────────┬────────────┘
│
100/400G Uplink
│
┌───────────────────┴───────────────────┐
│ │
Ethernet IP Fabric NDR400 RDMA Fabric
100G Leaf-Spine 400G Rail Fabric
│ │
┌───────────┼────────────┐ ┌────────────┴───────────┐
│ │ │ │ │
Compute GPU AIStor GPU AIStor
60 nodes 12 nodes 30 nodes 12 nodes 30 nodes
│ │ │ │ │
2×100G 2×100G 2×100G 4×400G 2×400G
│ │ │ │ │
└───────────┴────────────┘ └────────────┬───────────┘
│
RDMA / GPUDirect
+ 별도 OOB Fabric
iDRAC / iLO / XCC / Switch Mgmt / PowerScale Mgmt
여기서 가장 중요한 원칙은:
Kubernetes가 살아 있기 위해 NDR400이 필요해서는 안 됩니다.
NDR 전체가 내려가도 Kubernetes API, Cilium, DNS, AIStor S3 TCP, monitoring, SSH/management 등은 Ethernet Fabric에서 살아 있어야 합니다.
장비에 포트가 많지만 모든 포트를 처음부터 사용하는 것은 추천하지 않습니다.
| Node | 수량 | 보유 100G | 1차 사용 | Ethernet 연결 |
|---|---|---|---|---|
| GPU XE9780 | 12 | 2 | 2 | 24 |
| Compute DL380 | 60 | 4 | 2 | 120 |
| AIStor SR650 | 30 | 4 | 2 | 60 |
| 합계 | 102 | 204 × 100G |
나머지 Compute/AIStor의 100G 포트는 처음부터 bond에 전부 넣지 않고 향후 Storage/Replication/Service Fabric 확장용으로 남겨두는 것을 추천합니다.
예:
Ethernet Leaf-A
│
100GbE
│
NIC #1
│
┌────┴────┐
│ Server │
└────┬────┘
│
NIC #2
│
100GbE
│
Ethernet Leaf-B
따라서 단일 NIC, optic, cable, Leaf 장애로 서버가 isolation되지 않습니다.
여기서는 MC-LAG에 의존하는 전통적인 L2 fabric보다 L3 ToR + BGP를 선호합니다.
대략 다음 구조입니다.
Spine01 Spine02
▲ ▲
│ ECMP │
┌──────────────┼──────────────┼──────────────┐
│ │ │ │
Leaf01 Leaf02 Leaf03 Leaf04
│ │ │ │
Rack Rack Rack Rack
│ │ │ │
Servers Servers Servers Servers
실제 Leaf 수는 rack당 서버 수와 사용할 switch의 100G breakout density가 확정돼야 결정할 수 있습니다.
따라서 지금 단계에서는 특정 벤더 모델보다 다음 기준으로 발주하는 것이 좋습니다.
Leaf
────────────────────
400G native port
4×100G breakout 지원
BGP
ECMP
BFD
EVPN capability
Jumbo MTU
L3 routed interface
MLAG(optional)
PFC/ECN(optional)
Spine
────────────────────
400G
BGP
ECMP
BFD
Jumbo MTU
예를 들어 64 × 400G class 스위치를 사용하면 breakout을 통해 상당한 100G port density를 만들 수 있습니다.
장비 배치를 예를 들어 8~10 rack 정도로 잡는다면:
Rack01
├ Leaf01-A
├ Leaf01-B
├ GPU / Compute
Rack02
├ Leaf02-A
├ Leaf02-B
├ GPU / Compute
...
Storage Rack
├ Leaf0N-A
├ Leaf0N-B
└ AIStor
가 좋습니다.
다만 GPU 12대의 실제 rack 수는 XE9780의 전력/냉각 요구사항을 먼저 확인해야 합니다. 서버 U수만 보고 한 rack에 몰아넣으면 안 됩니다.
그래서 현 단계의 Ethernet BOM budget은 대략:
8~10 rack이라면 Ethernet Leaf 16~20대 + Spine 2~4대
정도를 설계 범위로 잡겠습니다.
최종 rack elevation이 나오면 정확하게 다시 계산해야 합니다.
여기에 Cilium을 얹습니다.
Pod
│
│ eBPF
▼
Cilium
│
│ Native Routing
▼
Linux Routing
│
▼
Server NIC
│
▼
Leaf
│
│ BGP
▼
Spine
VXLAN/Geneve overlay를 사용하지 않고:
routingMode: native
방향입니다.
Cilium native routing에서는 물리 network가 PodCIDR을 직접 routing할 수 있어야 합니다. Cilium 문서
추천 구조는:
Spine
▲
BGP
│
┌────────┴────────┐
Leaf-A Leaf-B
▲ ▲
│ BGP BGP │
│ │
NIC-A NIC-B
\ /
\ /
Kubernetes
Node
│
Cilium
│
PodCIDR
Cilium BGP Control Plane에서 PodCIDR과 필요한 Service prefix를 advertise합니다.
Cilium BGP Control Plane은 route advertisement 기능이며 Cilium datapath 자체를 만드는 기능은 아닙니다. 이 역할 분리는 설계 문서에서도 명확히 해야 합니다. Cilium 문서
Node가 두 Leaf에 route를 advertise할 수 있으므로:
Pod 10.20.12.10
▲
10.20.12.0/24
/ \
/ \
Leaf-A Leaf-B
\ /
\ /
Spine
형태로 ECMP가 가능합니다.
Service VIP 역시 필요한 경우 여러 Node에서 advertise해서:
Service VIP
10.40.1.100
│
┌──────┴──────┐
│ ECMP │
▼ ▼
Node1 Node2
│ │
Cilium Cilium
│ │
└──── Pod ────┘
구조를 만들 수 있습니다.
다만 node/route 변화에 따른 ECMP rehash가 기존 connection에 영향을 줄 수 있으므로 upstream switch의 resilient hashing과 Cilium Maglev도 같이 검토하는 게 좋습니다. Cilium 공식 운영 문서도 이 조합을 언급합니다. Cilium 문서
여기서는 저는 LACP bond를 모든 서버에 무조건 적용하지 않겠습니다.
Cilium+BGP+L3 ToR 구조라면:
NIC1 ─── Leaf-A
NIC2 ─── Leaf-B
를 독립된 L3 interface로 사용하는 설계가 더 자연스러울 수 있습니다.
즉:
추천 후보 A
ens1f0
10.10.x.x/31
│
Leaf-A
ens2f0
10.10.y.x/31
│
Leaf-B
BGP
입니다.
반대로 기존 운영 표준 때문에 bond가 반드시 필요하면:
NIC1 ─┐
├─ bond0
NIC2 ─┘
도 가능하지만 Leaf pair의 MLAG/EVPN multihoming 같은 추가 dependency가 생깁니다.
L3 dual-homed + BGP/ECMP
bond/LACP + MLAG
입니다.
Cilium native+BGP를 이미 선택했다면 굳이 다시 L2 MLAG dependency를 만들 이유가 적습니다.
이제 중요한 부분입니다.
GPU:
12 nodes × 4 NDR400
= 48 × 400G
AIStor:
30 nodes × 2 NDR400
= 60 × 400G
총:
108 × NDR400 endpoint ports
입니다.
이것을 Ethernet Leaf에 섞지 않고 별도의 AI/RDMA fabric으로 둡니다.
권장 구조는:
NDR FABRIC
Plane A Plane B
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ │ │ │
Leaf A1 Leaf A2 Leaf B1 Leaf B2
│ │ │ │
└───────┬─────┘ └─────┬───────┘
│ │
\ /
\ /
GPU Node
4 NIC
AIStor도:
AIStor Node
NDR0 NDR1
│ │
▼ ▼
Plane A Plane B
로 나눕니다.
한 plane 전체 장애에도 반대 plane이 살아 있습니다.
GPU node 하나를 보면:
Dell XE9780
B300 GPU complex
│
┌──────┼──────────────────────────┐
│ │ │ │
NIC0 NIC1 NIC2 NIC3
400G 400G 400G 400G
│ │ │ │
▼ ▼ ▼ ▼
Rail0 Rail1 Rail2 Rail3
12대를 동일하게 연결합니다.
Rail0 Rail1 Rail2 Rail3
GPU01 ● ● ● ●
GPU02 ● ● ● ●
GPU03 ● ● ● ●
...
GPU12 ● ● ● ●
즉 동일한 NIC/GPU affinity를 동일 rail에 연결합니다.
NVIDIA 역시 GPU compute fabric에서 rail-optimized topology를 사용하며, 동일 GPU position을 동일 rail/leaf 쪽에 연결하는 설계를 사용합니다. NVIDIA Docs
단, 최종 Rail0~3 매핑은 Dell의 XE9780 PCIe/NVLink/NIC topology를 nvidia-smi topo -m 등으로 실제 장비에서 확인한 뒤 고정해야 합니다.
AIStor는 훨씬 단순합니다.
Lenovo AIStor01
ConnectX-7 #0 ──400G── NDR Plane A
ConnectX-7 #1 ──400G── NDR Plane B
AIStor02
ConnectX-7 #0 ──400G── NDR Plane A
ConnectX-7 #1 ──400G── NDR Plane B
...
AIStor30
따라서 각 plane에는 AIStor endpoint가 30개씩 존재합니다.
AIStor는 multi-NIC internode communication에서 여러 NIC에 traffic을 분산할 수 있고, 각 NIC를 별도 network/subnet에 두는 것을 요구/권장합니다. MinIO AIStor Documentation
여기서는 switch가 64 × 400G class라고 가정하겠습니다.
각 Plane에 64-port switch를 두는 collapsed fabric입니다.
Plane 하나의 endpoint 수를 잘 배분하면 12 GPU node의 해당 rail/NIC들과 AIStor 30대를 수용할 수 있습니다.
하지만 향후 GPU 확장과 non-blocking leaf-spine 확장이 제한됩니다.
따라서 PoC에는 가능하지만 이번 96×B300 Production 환경에서는 제 1순위가 아닙니다.
NDR Plane A
Spine A1 Spine A2
▲ ▲
│ │
Leaf A1 Leaf A2
│ │
GPU + AIStor endpoints
NDR Plane B
Spine B1 Spine B2
▲ ▲
│ │
Leaf B1 Leaf B2
│ │
GPU + AIStor endpoints
64×400G class 기준 최소 8대 정도
Plane A
Leaf 2
Spine 2
Plane B
Leaf 2
Spine 2
──────────
Total 8
부터 상세 설계를 시작하겠습니다.
실제 non-blocking port allocation은 각 Leaf의 downlink/up-link 비율과 rack placement를 넣어 다시 계산해야 합니다. 8대를 지금 확정 BOM으로 보지는 말고, 64-port switch를 가정한 baseline으로 보는 게 맞습니다.
여기서 흔히 헷갈립니다.
Rail
= GPU/NIC affinity / traffic locality
Plane
= failure domain
입니다.
최종적으로는 예를 들어:
Plane A Plane B
Rail0/2 Rail1/3
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │
NIC0 NIC2 NIC1 NIC3
\ \ / /
└──────── GPU NODE ────────────┘
같은 배치를 검토할 수 있습니다.
다만 정확한 GPU↔NIC affinity가 나오기 전에는 NIC 번호를 고정하면 안 됩니다.
이것도 상당히 중요합니다.
NDR400 OSFP라고 해서 자동으로 InfiniBand 설계가 확정되는 것은 아닙니다.
두 후보가 있습니다.
B300
│
ConnectX-7
│
NDR400 IB
│
IB Switch
│
ConnectX-7
│
AIStor
B300
│
ConnectX-7
│
400GbE RoCEv2
│
Spectrum Ethernet
│
ConnectX-7
│
AIStor
AIStor는 현재 InfiniBand HDR/NDR 또는 RoCEv2 모두 RDMA fabric으로 지원합니다. MinIO AIStor Documentation
현재 BOM 사진이 ConnectX-7 NDR400 OSFP로 되어 있으므로 저는 NDR InfiniBand를 우선안으로 검토하되, 실제 NIC SKU/VPI mode와 구매 예정 switch SKU를 확인한 뒤 결정하겠습니다.
RoCE를 선택한다면 단순 Ethernet 설정으로 끝나지 않습니다.
AIStor는 inter-node RDMA를 RoCE에서 사용할 경우 end-to-end lossless fabric을 요구하며 PFC, NIC의 DCQCN, switch ECN/RED 구성이 필요합니다. MinIO AIStor Documentation
따라서:
RoCE Priority
│
├─ PFC
├─ ECN
├─ RED/WRED
└─ DCQCN
을 전체 path에서 검증해야 합니다.
이 때문에 운영 단순성을 중요하게 본다면 NDR InfiniBand가 오히려 명확한 선택이 될 수 있습니다.
Ethernet Fabric에서는 다음 정도로 분리하겠습니다.
| Network | 용도 | 예시 |
|---|---|---|
| OOB | iDRAC/iLO/XCC | 10.1.0.0/16 |
| Node Mgmt | OS/K8s Node | 10.10.0.0/16 |
| Compute Pod | Compute cluster Pod | 10.20.0.0/14 |
| Compute Service | Compute cluster Service | 10.24.0.0/16 |
| AIStor Node | Storage K8s | 10.30.0.0/16 |
| AIStor Pod | Storage cluster Pod | 10.32.0.0/14 |
| AIStor Service/VIP | S3 endpoints | 10.36.0.0/16 |
| PowerScale | NAS/Data | 10.40.0.0/16 |
| Infra VIP | API/Ingress/LB | 10.50.0.0/16 |
이것들은 예시 주소입니다. 기존 사내 IPAM과 겹치지 않는 실제 CIDR로 바꿔야 합니다.
그리고 가능하면 VRF도:
VRF-MGMT
VRF-K8S
VRF-STORAGE
정도로 분리합니다.
예를 들어 NDR/RDMA에는:
Plane A
172.20.0.0/16
Plane B
172.21.0.0/16
같이 별도 address space를 사용합니다.
AIStor:
ST01
RDMA0 = 172.20.0.11
RDMA1 = 172.21.0.11
ST02
RDMA0 = 172.20.0.12
RDMA1 = 172.21.0.12
...
ST30
GPU도 동일한 Fabric address plan을 가집니다.
AIStor의 현재 Kubernetes RDMA multi-NIC 방식은 실제로 각 Node의 fabric 주소를 Node label로 전달하는 구조를 지원합니다. MinIO AIStor Documentation
Ethernet IP Fabric은:
Physical Fabric MTU : 9216
Node : 9000
Cilium : 9000 전후
방향으로 검토하겠습니다.
정확한 값은 switch/NIC/Cilium overhead를 포함해서 테스트 후 고정합니다.
Native routing이므로 VXLAN/Geneve overhead가 없다는 것도 장점입니다.
NDR InfiniBand라면 Ethernet MTU 9000 설정을 그대로 적용하는 개념이 아니며 IB fabric의 active MTU를 별도로 설정/검증합니다. AIStor의 RDMA 검증 절차도 ibv_devinfo, ibstat 등을 통해 active RDMA port와 MTU를 확인하도록 되어 있습니다. MinIO AIStor Documentation
여기서 한 가지 수정할 부분이 있습니다.
모든 RDMA traffic을 Multus로 처리하지 않습니다.
Kubernetes Pod
│
┌──────────┴──────────┐
│ │
Primary Secondary
│ │
Cilium Multus
│ │
Native Routing SR-IOV/RDMA
│ │
100GbE NDR400
이 구조는 GPU training Pod에는 적합합니다.
GPU workload가 NDR NIC/VF를 받아 NCCL/GPUDirect RDMA를 사용할 수 있습니다.
이 부분은 현재 AIStor 문서상 매우 중요합니다.
AIStor RDMA Object Store Pod는:
hostNetwork: true
를 사용하고 RDMA adapter를 직접 사용합니다.
따라서:
AIStor Pod
│
hostNetwork
│
Host RDMA NIC
│
NDR400
입니다.
현재 AIStor Operator의 RDMA 구성에서는 Multus NetworkAttachmentDefinition을 AIStor Object Store에 붙이는 방식이 적용되지 않습니다. 공식 문서도 AIStor RDMA Pod는 host network를 사용하므로 Multus NAD가 효과가 없다고 명시합니다. MinIO AIStor Documentation
이건 설계서에 꼭 명시하겠습니다.
Cilium
├ Native Routing
├ kube-proxy replacement
├ BGP Control Plane
├ ECMP
├ Hubble
└ ClusterMesh
│
│
Multus
└ SR-IOV / RDMA
│
NVIDIA Network Operator
│
NDR400
│
NCCL / GPUDirect RDMA
Cilium
├ Native Routing
├ BGP
├ Hubble
└ ClusterMesh(optional)
AIStor
└ hostNetwork
│
├ RDMA NIC A
└ RDMA NIC B
│
NDR400
가 됩니다.
PowerScale은 NDR에 연결할 필요가 없습니다.
PowerScale F710 ×5
│
2×100GbE+
│
Ethernet Fabric
│
┌───┴────┐
│ │
Compute GPU
PowerScale Client Network 역시 Leaf pair에 dual-home하고 별도 Storage VLAN/VRF를 사용하는 것을 권합니다.
결과적으로 최종 그림은 다음과 같습니다.
Enterprise Core
│
100/400G Border
│
┌───────────────┴───────────────┐
│ │
Spine E1 Spine E2
│ │
┌──────────┼───────────────┬───────────────┤
│ │ │ │
Leaf Pair Leaf Pair Leaf Pair Leaf Pair
│ │ │ │
Compute Compute GPU AIStor
×60 ×12 ×30
│ │ │
│ 2×100G 2×100G
│ │ │
└──────── Cilium Native / BGP / ECMP ──────┘
│
PowerScale ×5
═══════════ Separate Physical Fabric ═══════════
NDR400 RDMA FABRIC
Plane A Plane B
┌────────────┐ ┌────────────┐
│ Spine A1/A2│ │ Spine B1/B2│
└──────┬─────┘ └─────┬──────┘
│ │
Leaf A1/A2 Leaf B1/B2
│ │
┌───────┴────────┐ ┌──────┴────────┐
│ │ │ │
GPU NICs AIStor0 GPU NICs AIStor1
│ │ │ │
└─────── GPU / Storage RDMA ──────────────┘
═════════════ Separate OOB Fabric ═════════════
OOB Switch A/B
│
┌──────────────┼──────────────┐
│ │ │
iDRAC iLO XCC
GPU Compute AIStor
정확한 rack elevation과 switch SKU가 나오기 전의 설계 baseline입니다.
| Fabric | Baseline |
|---|---|
| OOB switch | rack당 1~2, 이중화 정책에 따라 결정 |
| Ethernet Leaf | rack당 2 |
| Ethernet Spine | 2~4 |
| Server Ethernet | 204 × 100G active links |
| NDR endpoint | 108 × 400G links |
| NDR Leaf | 4 이상 |
| NDR Spine | 4 정도 |
| NDR 총계 baseline | 약 8 × 64-port 400G class |
| PowerScale | Ethernet Fabric dual-homed |
여기서 특히 NDR 8대는 최종 발주 수량이 아닙니다. 64×400G switch + dual-plane + leaf/spine을 가정한 starting point입니다. GPU rack 배치, rail별 uplink/downlink 비율, non-blocking 요구사항과 향후 GPU 증설 목표를 넣으면 수량이 달라집니다.
그리고 100GbE Leaf 수는 서버 대수가 아니라 rack 배치가 결정합니다. XE9780의 전력/냉각 때문에 GPU rack 수가 먼저 확정되어야 정확하게 산출할 수 있습니다.
제가 다음 단계에서 가장 먼저 확정할 항목은 ① NDR를 InfiniBand로 할지 400G RoCEv2로 할지, ② GPU/Storage/Compute의 rack당 실제 배치 대수, ③ Ethernet/NDR switch의 후보 port density(예: 64×400G)입니다. 이 세 가지가 정해지면 바로 rack별 GPU01 NIC0 → NDR-A Leaf01 Port01 수준의 포트맵, switch 정확한 대수, oversubscription ratio, 케이블/optic 수량까지 산출할 수 있습니다.
네. 그 조건이면 앞서 제안한 “100G NIC들을 독립 L3+BGP interface로 사용”하는 부분은 수정하는 게 맞습니다. 기존 사이트의 운영 모델을 계승해서 bond0 = Public/External, bond1 = Private/Kubernetes, 그리고 GPU/AIStor만 별도로 400G RDMA Fabric을 추가하는 구조가 가장 자연스럽습니다.
핵심은 100G 4포트를 가진 Compute/Storage는 2+2로 정확히 나누고, GPU는 사진상 100G 2포트뿐이라 Public/Private을 동일한 방식의 2+2 bonding으로 만들 수 없다는 점입니다. 이 부분은 GPU 서버 BOM 확인/보강이 필요합니다.
각 Node
│
┌────────────────┼───────────────────┐
│ │ │
bond0 bond1 RDMA
PUBLIC PRIVATE FABRIC
│ │ │
100GbE 100GbE 400G
│ │ │
External/Ingress Kubernetes GPU ↔ AIStor
User/API Pod/Service GPUDirect/RDMA
S3 Public ClusterMesh NCCL
Storage TCP
Management/iDRAC/iLO/XCC는 말씀하신 대로 여기서 완전히 제외하겠습니다.
HPE Compute 60대에는 100GbE ×4가 있으므로 정확히 2+2로 나눕니다.
HPE DL380 Gen12
────────────────────────────────────
100G NIC #1 Port0 ───┐
├── bond0 ── PUBLIC
100G NIC #2 Port0 ───┘
2 × 100G
100G NIC #1 Port1 ───┐
├── bond1 ── PRIVATE / K8s
100G NIC #2 Port1 ───┘
2 × 100G
여기서 가능하면 같은 물리 NIC의 두 포트를 같은 bond에 넣지 않는 것이 중요합니다.
예를 들어 실제 카드가:
PCIe NIC-A
├ p0 100G
└ p1 100G
PCIe NIC-B
├ p0 100G
└ p1 100G
라면:
bond0
NIC-A/p0 ─── Public Leaf-A
NIC-B/p0 ─── Public Leaf-B
bond1
NIC-A/p1 ─── Private Leaf-A
NIC-B/p1 ─── Private Leaf-B
를 추천합니다.
그러면 NIC-A 카드 자체가 죽어도 bond0와 bond1 모두 NIC-B를 통해 살아 있습니다.
이게 단순히 port redundancy보다 좋습니다.
HPE Compute
│
┌──────────────┼──────────────┐
│ │
bond0 bond1
PUBLIC PRIVATE
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ │ │ │
100G 100G 100G 100G
│ │ │ │
Public Leaf-A Public Leaf-B Private-A Private-B
따라서 한 Compute node당:
4 × 100GbE active입니다.
Lenovo에는 100G ×4가 있으므로 Compute와 동일하게 가져갑니다.
Lenovo SR650 V4 / AIStor
─────────────────────────────────────────
100G NIC-A/p0 ─────┐
├── bond0 PUBLIC
100G NIC-B/p0 ─────┘
2×100G
100G NIC-A/p1 ─────┐
├── bond1 PRIVATE
100G NIC-B/p1 ─────┘
2×100G
ConnectX-7 #0 ───────── 400G RDMA Fabric A
ConnectX-7 #1 ───────── 400G RDMA Fabric B
따라서 Storage 한 대에는:
2 × 100G → bond0
2 × 100G → bond1
2 × 400G → RDMA
────────────────────
총 6 high-speed physical links
가 됩니다.
명확하게 이렇게 나누겠습니다.
AIStor Node
│
┌──────────────┼────────────────┐
│ │ │
bond0 bond1 NDR400
PUBLIC PRIVATE RDMA
│ │ │
│ │ │
S3 External Kubernetes AIStor internode
S3 client Cilium GPU↔AIStor
API Operator high-speed path
LB/VIP Monitoring
Control
이렇게 해두면 RDMA Fabric이 죽어도 bond1을 통한 Kubernetes/management data path가 살아 있고, 필요하면 S3 TCP fallback도 설계할 수 있습니다.
사진의 XE9780 구성에서는:
100GbE ×2
NDR400 ×4
였습니다.
따라서 기존 사이트와 똑같이:
bond0 = 2 NIC
bond1 = 2 NIC
을 만들 수 없습니다.
2포트밖에 없기 때문입니다.
그래서 GPU에서는 100GbE NIC 2포트를 추가하는 것을 강하게 권합니다.
목표 BOM:
Dell XE9780
100G ×4
+
NDR400 ×4
로 만드는 게 가장 깔끔합니다.
100G 2포트 추가가 가능하다는 전제에서는:
Dell XE9780 / B300 ×8
────────────────────────────────────────────
100G NIC-A/p0 ─────┐
├── bond0 PUBLIC
100G NIC-B/p0 ─────┘
2×100G
100G NIC-A/p1 ─────┐
├── bond1 PRIVATE
100G NIC-B/p1 ─────┘
2×100G
CX-7 NDR #0 ────────── 400G Rail 0
CX-7 NDR #1 ────────── 400G Rail 1
CX-7 NDR #2 ────────── 400G Rail 2
CX-7 NDR #3 ────────── 400G Rail 3
GPU 한 대당 총:
100G ×4
400G ×4
= 8 high-speed links
입니다.
가능하면 이 변경을 지금 BOM 단계에서 해두는 게 좋습니다.
여기는 아주 중요합니다.
400G ×4를:
NDR0 ─┐
NDR1 ─┤
├── bond2 ← 이렇게 하지 않음
NDR2 ─┤
NDR3 ─┘
으로 만들지 않습니다.
각 NIC를 독립적으로 유지합니다.
rdma0
rdma1
rdma2
rdma3
그리고 NCCL/RDMA/GPUDirect가 topology에 따라 사용하도록 합니다.
즉 GPU에는:
bond0 Public IP
bond1 Private/K8s IP
rdma0 Rail0
rdma1 Rail1
rdma2 Rail2
rdma3 Rail3
가 존재하게 됩니다.
전체적으로:
400G RDMA FABRIC
┌─────────────────────────────┐
│ │
Fabric A Fabric B
│ │
┌───────┴───────┐ ┌──────┴────────┐
│ │ │ │
Rail0 Rail2 Rail1 Rail3
│ │ │ │
GPU rdma0 GPU rdma2 GPU rdma1 GPU rdma3
│ │ │ │
└─────── GPU B300 ×12 ─────────┴───────────────┘
AIStor ×30
rdma0 rdma1
│ │
▼ ▼
Fabric A Fabric B
GPU는 4×400G를 이용해 총 1.6 Tbps/node의 physical RDMA bandwidth를 갖습니다.
AIStor는 2×400G = 800Gbps/node입니다.
예를 들어 제가 위에서:
rdma0 → Fabric A
rdma1 → Fabric B
rdma2 → Fabric A
rdma3 → Fabric B
라고 썼지만 이 번호 자체를 지금 확정하면 안 됩니다.
실제 XE9780에서:
GPU ↔ NVSwitch
GPU ↔ PCIe Root Complex
PCIe Root Complex ↔ ConnectX-7
NUMA
affinity를 확인해야 합니다.
장비 입고 후:
nvidia-smi topo -m
lspci -tv
ibdev2netdev
numactl -H
등의 결과를 기준으로 NIC/GPU affinity가 가장 자연스러운 rail mapping을 고정하는 게 맞습니다.
차선책은 있습니다.
현재 2×100G를:
100G #0 ─┐
├── bond1 PRIVATE
100G #1 ─┘
으로 사용하는 것입니다.
그리고 GPU Node 자체에는 bond0 Public을 만들지 않습니다.
저라면 이게 차선책 중에서는 가장 낫다고 봅니다.
왜냐하면 GPU Worker가 외부 network에 직접 노출될 이유가 별로 없기 때문입니다.
External User
│
▼
Ingress / LB
│
▼
Compute/Infra Node
bond0 Public
│
│ Kubernetes
▼
bond1 Private
│
▼
GPU Worker
로 접근할 수 있습니다.
즉 GPU에서는:
100G ×2 → bond1 Private
400G ×4 → RDMA
bond0 → 없음
입니다.
이건 오히려 security 관점에서는 꽤 좋은 구조입니다.
| 구성 | bond0 | bond1 | RDMA | 평가 |
|---|---|---|---|---|
| A. 100G NIC 추가 | 2×100G | 2×100G | 4×400G | 기존 표준과 일치 / 추천 |
| B. 현 BOM 유지 | 없음 | 2×100G | 4×400G | 기술적으로 더 단순 / 추천 가능 |
| C. 100G 한 포트씩 | 1×100G | 1×100G | 4×400G | 비추천 |
특히 C:
100G #0 → bond0(?)
100G #1 → bond1(?)
은 실제로 bond가 아니고 redundancy도 없어집니다.
이렇게 구성하는 것은 추천하지 않습니다.
따라서 GPU는 100G를 2포트 추가하거나, Public을 없애고 기존 2포트를 Private bond1으로 묶는 것 중 하나를 선택하는 게 좋습니다.
개인적으로는 GPU Worker에 직접 Public 접근이 필요하지 않다면 B안도 상당히 매력적입니다.
HPE 60대 중 CP 6대를 두 Kubernetes Cluster에 3+3으로 나눈다고 했으므로:
Control Plane
100G-A/p0 ─┐
├── bond0 Public
100G-B/p0 ─┘
100G-A/p1 ─┐
├── bond1 Private
100G-B/p1 ─┘
로 동일하게 갑니다.
하지만 Kubernetes API의 실제 내부 endpoint는 bond1 Private에 두는 것을 권합니다.
kubectl/Admin
│
bond0/Public
│
API LB/VIP
│
firewall
│
bond1
│
kube-apiserver
처럼 외부 접근과 내부 control traffic을 분리합니다.
기존 사이트와 운영 일관성을 유지하려면 저는 가능하면 물리적으로도:
PUBLIC FABRIC
Public Leaf-A Public Leaf-B
│ │
bond0 members
│
Node
PRIVATE FABRIC
Private Leaf-A Private Leaf-B
│ │
bond1 members
│
Node
를 선호합니다.
즉 bond0/bond1이 VLAN만 다른 같은 switch에 들어가는 것보다는 failure domain 자체를 나누는 구조입니다.
HW budget 때문에 같은 Leaf-Spine을 써야 한다면 VRF/VLAN으로 강하게 분리할 수 있지만, 이번 장비 규모라면 물리 fabric 분리를 검토할 가치가 있습니다.
이제 Cilium 관계도 명확해집니다.
Kubernetes Node
Pod
│
Cilium
│
Native Routing
│
bond1
│
PRIVATE Fabric
│
BGP / ECMP
즉:
Cilium Native Routing → bond1
입니다.
PodCIDR/BGP/ClusterMesh/Pod-to-Pod/Kubernetes 내부 Service traffic도 기본적으로 Private fabric을 사용합니다.
bond0는 Cilium의 일반 node-to-node transport network로 사용하지 않습니다.
bond0
│
├ External Client
├ API ingress
├ LoadBalancer VIP
├ vLLM endpoint
├ S3 external endpoint
└ Enterprise network
등입니다.
특히 BGP advertisement도 두 종류를 구분해야 합니다.
PRIVATE BGP
────────────
Pod CIDR
Internal Service
Node route
PUBLIC BGP
────────────
Ingress VIP
LoadBalancer VIP
S3 external VIP
vLLM/API VIP
모든 PodCIDR을 Public fabric에 advertise할 이유가 없습니다.
AIStor 하나를 보면:
AIStor
│
┌────────────────┼────────────────┐
│ │ │
bond0 bond1 RDMA
│ │ │
PUBLIC PRIVATE 400G
│ │ │
S3 external Kubernetes GPU↔AIStor
S3 clients internode TCP AIStor RDMA
API Cilium NVMe data
이 구조가 상당히 좋습니다.
그리고 성능 시험도 정확하게 분리할 수 있습니다.
S3 TCP Public
S3 TCP Private
S3 RDMA
GPU Direct / RDMA
를 각각 비교할 수 있습니다.
Compute는 단순합니다.
HPE Compute
┌─────────────┐
│ │
bond0 bond1
200G raw 200G raw
PUBLIC PRIVATE
│ │
External Cilium
ingress Pod traffic
AIStor TCP
여기서 2×100G bond = 200Gbps라고 표기하긴 했지만 단일 flow가 자동으로 200Gbps가 되는 것은 아닙니다. LACP hashing과 switch/uplink capacity에 따라 실제 처리량이 결정됩니다.
기존 사이트에서 2×25G bond라도 switch 측 병목 때문에 40Gbps/약 5GB/s가 최대였던 것과 같은 개념입니다.
따라서 신규 사이트에서는 서버 NIC 총합만 보고 200G라고 하지 말고 Leaf uplink/spine oversubscription까지 맞춰야 합니다.
이렇게 정리하면 가장 명확합니다.
| Node | bond0 PUBLIC | bond1 PRIVATE | 400G RDMA |
|---|---|---|---|
| Control Plane HPE | 2×100G | 2×100G | - |
| Infra HPE | 2×100G | 2×100G | - |
| Compute HPE | 2×100G | 2×100G | - |
| AIStor Lenovo | 2×100G | 2×100G | 2×400G |
| GPU XE9780 권장 | 2×100G | 2×100G | 4×400G |
| GPU XE9780 현 BOM | - | 2×100G | 4×400G |
| PowerScale | Storage/Public network 별도 | 필요시 Private | - |
따라서 GPU만 BOM 결정이 하나 필요합니다.
이번 사이트가 기존 운영 표준을 계승해야 한다면 최종적으로는 GPU 서버에도 100G 2포트를 추가해서 모든 Kubernetes Node의 Ethernet 구조를 통일하겠습니다.
ALL K8S NODES
┌────────────┴─────────────┐
│ │
bond0 bond1
PUBLIC PRIVATE
│ │
2 × 100GbE 2 × 100GbE
│ │
Public Leaf Pair Private Leaf Pair
│
Cilium
Native/BGP/ECMP
GPU / AIStor ONLY
│
400G RDMA
│
┌──────────────┴──────────────┐
│ │
GPU: 4 ×400G AIStor: 2 ×400G
│ │
└────── NDR Fabric A/B ───────┘
이렇게 하면 기존 사이트와 운영 모델도 정확하게 이어집니다.
bond0 = 외부, bond1 = Kubernetes, rdma* = AI Data Fabric이라는 아주 단순한 규칙이 모든 서버에 적용됩니다.
그리고 이 구조에서는 앞서 이야기했던 Cilium+BGP 설계도 bond1 Private Fabric 안에 한정시키는 게 좋습니다. Public에는 필요한 Ingress/LB/S3 VIP만 별도로 advertise하고, PodCIDR이나 ClusterMesh traffic을 Public 쪽으로 흘리지 않습니다.
한 가지 BOM 변경을 할 수 있다면 저는 GPU XE9780의 100GbE를 현재 2포트 → 4포트로 만드는 것을 가장 먼저 확인하겠습니다. 그게 가능하면 전체 네트워크 구조가 매우 깔끔해집니다.
맞습니다. 다만 앞서 제가 100GbE와 ConnectX 포트 구성을 조금 단순화해서 표현한 부분은 정정하는 게 좋습니다. 처음 올려주신 사양표 기준으로 보면 핵심은 다음과 같습니다.
| Node | 100G/IP 계열 | 400G/RDMA 계열 |
|---|---|---|
| GPU XE9780 | ConnectX-6 계열 100G ×2 | ConnectX-7 NDR400 ×4 |
| AIStor SR650 V4 | 100GbE ×4 | ConnectX-7 NDR400 ×2 |
| Compute DL380 | 100GbE ×4 | 없음 |
즉 질문하신 것처럼 GPU는 RDMA 400G 4포트, AIStor는 RDMA 400G 2포트인 비대칭 구조로 보는 게 맞습니다.
그리고 결론부터 말하면 전혀 문제 없습니다. GPU 4포트와 AIStor 2포트가 1:1로 대응해야 하는 구조가 아닙니다.
서버끼리 NIC를 직접 연결하는 게 아닙니다.
GPU01 AIStor01
4 × 400G 2 × 400G
│ │ │ │ │ │
│ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼
┌─────────────────────────────────────────┐
│ │
│ NDR400 Fabric │
│ Switch / Leaf-Spine │
│ │
└─────────────────────────────────────────┘
▲ ▲ ▲ ▲ ▲ ▲
│ │ │ │ │ │
GPU02 AIStor02
따라서
GPU NIC 수 = Storage NIC 수
일 필요가 없습니다.
Ethernet에서 PC가 1GbE이고 서버가 100GbE여도 서로 통신할 수 있는 것과 비슷한 개념입니다.
차이는 총 aggregate bandwidth입니다.
GPU 한 대:
4 × 400G
= 1.6 Tbps
≈ 200 GB/s theoretical line rate
AIStor 한 대:
2 × 400G
= 800 Gbps
≈ 100 GB/s theoretical line rate
하지만 전체 시스템으로 보면 이야기가 달라집니다.
12 × 4 × 400G
= 19.2 Tbps
30 × 2 × 400G
= 24 Tbps
즉 재미있게도 전체 Storage-side RDMA network bandwidth가 GPU-side보다 더 큽니다.
GPU side 19.2 Tbps
│
│
NDR Fabric
│
▼
AIStor side 24.0 Tbps
그래서 전체 cluster 관점에서는 매우 괜찮은 비율입니다.
한 GPU node가 AIStor 한 대와 1:1로 연결되는 구조가 아니기 때문입니다.
실제 S3/Object Storage는 이런 형태가 됩니다.
GPU01
B300 ×8
│
CX-7 ×4 / 1.6Tbps
│
▼
NDR400 Fabric
│
┌───────────┼─────────────┐
│ │ │
▼ ▼ ▼
AIStor01 AIStor02 ... AIStor30
800G 800G 800G
따라서 GPU가 여러 Storage node로 request/object access를 분산하면 storage cluster 전체 bandwidth를 활용할 수 있습니다.
AIStor 쪽 30대가 총 60개의 400G endpoint를 제공하는 이유도 이런 scale-out 구조와 잘 맞습니다.
여기서 중요한 게 있습니다.
GPU의 4×400G를 AIStor만을 위한 NIC라고 보면 안 됩니다.
이 Fabric의 중요한 목적은:
NDR400
GPU ←────────────────→ GPU
NCCL / RDMA
Training
GPU ←────────────────→ AIStor
RDMA
Dataset
Checkpoint
두 가지입니다.
Distributed Training을 하면 GPU01과 GPU02~12 사이의 통신이 엄청나게 발생합니다.
그래서 GPU의 4×400G는:
GPU East-West communication + GPU↔Storage communication
둘 다 담당한다고 보는 게 맞습니다.
개념적으로 다음처럼 구성할 수 있습니다.
GPU Node
CX7-0 ──400G── Rail 0
CX7-1 ──400G── Rail 1
CX7-2 ──400G── Rail 2
CX7-3 ──400G── Rail 3
12개 GPU node가 동일하게:
Rail0 Rail1 Rail2 Rail3
GPU01 ● ● ● ●
GPU02 ● ● ● ●
GPU03 ● ● ● ●
...
GPU12 ● ● ● ●
연결됩니다.
그리고 Storage는 2포트이므로 예를 들어:
AIStor01
CX7-0 ──400G── Fabric/Rail group A
CX7-1 ──400G── Fabric/Rail group B
처럼 연결합니다.
물리 Fabric 내부에서 rail 간 reachability가 있도록 Leaf-Spine을 설계하기 때문에 GPU가 가진 rail 수와 Storage의 rail 수가 같을 필요가 없습니다.
RDMA line은 Kubernetes cluster가 연결된 bond1과 별개로 존재해도 서로 연동 가능한가?
네. 오히려 그렇게 구성하는 것을 권장합니다.
이 부분을 이해하면 전체 네트워크가 훨씬 명확해집니다.
GPU Node를 예로 들면:
GPU Node
Linux / Kubernetes
│
┌────────────┴─────────────┐
│ │
bond1 RDMA
Private K8s CX-7 ×4
│ │
100G 400G
│ │
▼ ▼
Private IP Fabric NDR Fabric
│ │
Cilium / K8s NCCL / GPUDirect
API / Pod GPU↔AIStor
두 개가 동시에 존재합니다.
예를 들어 Training Pod가 만들어진다고 해보겠습니다.
Kubernetes API
│
│ bond1
▼
GPU Node
│
kubelet
│
▼
Training Pod
이 과정은 bond1 Private network입니다.
Training Pod
│
NCCL
│
▼
ConnectX-7
│
RDMA
│
▼
NDR400
│
▼
Other GPU
이건 bond1을 통과하지 않습니다.
RDMA path를 사용하는 경우:
Training Pod
│
AIStor client
│
RDMA
│
GPU CX-7
│
NDR400
│
AIStor CX-7
│
AIStor
│
Gen5 NVMe
역시 bond1을 통과하지 않습니다.
APPLICATION
Training Pod
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
Kubernetes Normal IP AI Data
Control Traffic Traffic
│ │ │
▼ ▼ ▼
bond1 bond1 RDMA
│ │ │
100G 100G 400G
│ │ │
▼ ▼ ▼
Cilium/BGP TCP/S3 NDR400
│
┌─────────┴────────┐
│ │
GPU AIStor
이게 HPC/AI 환경에서는 정상적인 구조입니다.
여기서 Multus / NVIDIA Network Operator / SR-IOV 또는 host-device가 등장합니다.
일반 Pod interface는:
Pod
eth0
│
▼
Cilium
│
bond1
입니다.
RDMA가 필요한 AI Pod에는 추가 interface/device를 제공합니다.
Training Pod
eth0
│
└── Cilium → bond1
Kubernetes network
net1 / RDMA device
│
└── ConnectX-7
│
└── NDR400
즉 Pod가 두 개의 network world에 동시에 붙을 수 있습니다.
Host에서:
GPU01
bond0
└ Public
bond1
└ Kubernetes Private
ib0 / rdma0
└ CX7-0 400G
ib1 / rdma1
└ CX7-1 400G
ib2 / rdma2
└ CX7-2 400G
ib3 / rdma3
└ CX7-3 400G
Pod에서는:
AI Pod
eth0
10.20.x.x
│
└ Cilium → bond1
RDMA device(s)
│
├ mlx5_0
├ mlx5_1
├ mlx5_2
└ mlx5_3
│
▼
NDR400
형태가 됩니다.
AIStor Node:
bond0
└ Public/S3
bond1
└ Kubernetes Private
rdma0
└ 400G Fabric A
rdma1
└ 400G Fabric B
AIStor Kubernetes 자체는:
kubelet
Cilium
Operator
API
Monitoring
etc.
│
bond1
으로 동작하면서 실제 고속 Storage Data Plane은:
AIStor
│
RDMA
│
rdma0/1
│
NDR400
│
GPU
를 사용할 수 있습니다.
즉 Kubernetes가 사용하는 network와 Kubernetes 위 application이 사용하는 high-speed data network가 반드시 같을 필요가 없습니다.
만약 전부 bond1에 넣으면:
K8s API
Pod traffic
Monitoring
S3
NCCL
GPU training
Storage traffic
│
▼
bond1
200G
가 되어 버립니다.
그런데 장비에는 GPU당 1.6Tbps의 RDMA bandwidth가 있습니다.
그걸 놔두고 100G bond를 통과시키면 HW를 제대로 활용하지 못합니다.
따라서:
GPU NODE
bond0 bond1 RDMA
│ │ │
Public K8s AI Data
│ │ │
100G×2 100G×2* 400G×4
│
▼
1.6 Tbps
가 이상적입니다.
* GPU는 현재 BOM상 100G가 2포트라 앞서 말씀드린 것처럼 bond0/bond1을 모두 2-port로 만들려면 100G 포트 추가 여부를 확인해야 합니다.
앞에서 정한:
AI Compute K8s
│
│
├── Compute ×50
└── GPU ×12
│
│ RDMA
▼
═══ NDR400 Fabric ═══
▲
│ RDMA
│
AIStor K8s
Storage ×30
구조에서 Kubernetes Cluster가 서로 달라도 RDMA Fabric에는 아무 문제가 없습니다.
중요한 포인트입니다.
RDMA 통신의 관점에서:
“같은 Kubernetes Cluster인가?”
가 중요한 것이 아니라,
“두 RDMA endpoint 사이에 정상적인 RDMA fabric connectivity가 존재하는가?”
가 중요합니다.
따라서:
Cluster #1
GPU Pod
│
RDMA
│
CX-7
│
│
══════════════ NDR Fabric ═════════════
│
CX-7
│
AIStor
│
Cluster #2
가 가능합니다.
ClusterMesh도 이 RDMA data path를 만들어 주는 것이 아닙니다. ClusterMesh는 Kubernetes/Cilium IP connectivity/service/policy 측면이고, NDR RDMA는 별도의 high-performance data plane으로 보는 게 맞습니다.
bond0 = North-South/Public, bond1 = Kubernetes/Cilium Private, ConnectX-7 400G = AI/RDMA Data Plane
입니다.
그리고 GPU 4×400G ↔ AIStor 2×400G의 포트 비대칭은 문제가 아니라 각 서버 역할에 따른 bandwidth provisioning 차이입니다. 전체로 보면 GPU 측 19.2Tbps보다 30대 AIStor 측이 24Tbps라서 aggregate bandwidth도 부족하지 않습니다.
다만 다음 단계에서 꼭 확인할 것은 ConnectX-7이 실제 발주 SKU상 InfiniBand NDR인지 Ethernet/RoCE인지(VPI 포함)입니다. 이게 확정돼야 4 GPU rail ↔ 2 AIStor rail의 실제 switch topology와 포트 수를 정확하게 산출할 수 있습니다.