26O01b

QK·약 18시간 전

k8s 환경에서의 테스트 추가 고려사항

K8s + Cilium ClusterMesh 조합이면, 지금까지 bare-metal에서 검증한 걸 "그대로 믿으면 안 되는" 항목들이 꽤 생김. 단순히 새 테스트를 추가하는 것보다, 컨테이너화/오버레이 네트워크가 기존 검증 결과를 몰래 깨뜨리지 않는지 재검증하는 항목과 K8s+ClusterMesh 고유 신규 항목을 나눠서 보는 게 정확함.

A. 가장 먼저 봐야 할 것 — NCCL 재검증

Stage1에서 NCCL All-Reduce로 NVLink 대역폭을 검증했는데, K8s Pod 내부에서 반드시 재검증 필요. 현재 Cilium이 Native Routing을 사용하는 환경이어서 Pod의 eth0는 veth 기반이지만 Cilium eBPF와 Linux native routing을 거쳐 물리 NIC으로 전달됨.

  • Single-node 8-GPU AllReduce에서는 NVLink/NVSwitch 경로가 핵심이므로 Cilium networking 영향은 제한적일 가능성이 높음. 반면 multi-node NCCL에서는 Pod → veth → Cilium → native routing → BGP/ECMP → physical NIC 경로가 실제 성능에 영향을 줄 수 있으므로 별도의 검증이 필요.
  • 따라서 K8s 검증에서는 Bare Metal → hostNetwork Pod → Cilium Pod를 비교하고, NCCL 로그에서 실제 transport/interface 선택을 확인(NCCL_SOCKET_IFNAME이 올바른 물리 NIC을 가리키는지). Multus/SR-IOV는 성능 저하가 확인될 경우 비교 대상으로 추가.
  • MTU 불일치 확인: Native Routing 환경이어도 물리 스위치(Jumbo Frame 9000), 노드 인터페이스, Pod veth 간 MTU가 일치하지 않으면 TCP 패킷 단편화로 NCCL 링 레이턴시가 급증합니다.
  • Socket Buffer Sizing: RDMA가 없는 TCP NCCL 환경에서는 NCCL_BUFFSIZE 및 리눅스 커널의 net.ipv4.tcp_rmem/wmem 파라미터가 Pod 네트워크 네임스페이스에 어떻게 전파되는지(sysctl allowlist) 확인해야 제 성능이 나옵니다.

B. Cilium ClusterMesh 자체

RDMA가 없는 상황에서는 TCP 경로에 추가 오버헤드가 조금이라도 붙으면 그대로 성능 손실로 직결됨.

  • Cilium VXLAN/Geneve 캡슐화 모드 대비 Native Routing(BGP로 Pod CIDR을 직접 광고, 캡슐화 없음) 모드가 오버헤드가 훨씬 적음.
  • 재검증 필요: Stage2의 iperf3 단일/멀티 스트림, LACP 25G/50G 테스트를 Pod-to-Pod(특히 클러스터 간)로 재실행해서 bare-metal 대비 손실폭을 측정. ClusterMesh 경유 시 홉이 늘어나는 만큼 지연(RTT)이 늘어나는지도 별도 측정.
  • BGP 라우트 수렴 시간(BGP BFD(Bidirectional Forwarding Detection) 연계 여부에 따른 수렴 시간 검증): 노드 장애/재기동 시 라우트가 얼마나 빨리 갱신되는지(수 초 vs 수십 초) — 이게 느리면 장애 시 트래픽 블랙홀 구간이 생김
  • Conntrack 테이블 포화: All-Reduce나 분산 추론 시 다수의 TCP 세션이 폭발할 때 eBPF/Linux conntrack 테이블(sysctl net.netfilter.nf_conntrack_max) 한도에 걸리지 않는지 확인해야 함.
  • eBPF Host-Routing 우회 여부: Cilium이 Host-Routing 모드로 동작하여 Pod veth의 TCP 스택을 바이패스(tc BPF)하고 있는지 cilium status --verbose로 체크 리스트에 포함.
  • NVIDIA GPU Operator + Node Feature Discovery + (필요시) Topology Manager가 제대로 구성되어 있는지. TP=8 파드가 8장을 요청했을 때 실제로 이 8장이 물리적으로 같은 NVSwitch 도메인 안에 있는 GPU들인지(멀티 NVSwitch 보드 구성이면 쪼개질 수 있음) 확인이 필요.
  • MIG를 켰다면 MIG 슬라이스 간 NVLink 특성이 완전히 달라지므로 MIG 미사용/사용 여부를 먼저 확정.
  • NUMA-NIC-GPU Alignment: 8장이 통째로 할당되는 전체 점유 상황 외에도, 부분 할당이나 PCIe/NIC 인터페이스가 특정 NUMA 노드에 바인딩되어 있을 때 GPU와 NIC 간 CPU 소켓 간 트래픽(UPI/QPI traversal)이 발생하는지 Kubelet TopologyManager 정책(single-numa-node 또는 restricted)을 통해 확실히 묶어야 함.

D. 기존 Compute 클러스터(Spark/StarRocks/Trino/JupyterLab) 특화 부하 패턴

지금까지의 stage3a6(포화점), stage5b(부하테스트)는 "점진적으로 동시성을 올리는" 패턴이었는데, 실제 이 엔진들의 트래픽은 성격이 다름.

엔진실제 패턴추가로 봐야 할 것
Spark수백 개 executor가 동시에 폭발적으로 추론 요청을 쏨(스텝 함수형 버스트)점진적 동시성 램프업이 아니라 즉각적 스파이크(예: 0→256 동시성이 수 초 내) 테스트, LiteLLM/Envoy 레벨 커넥션 풀 고갈 여부
Trino/StarRocks쿼리 페더레이션 중 GPU 노드로의 소수의 긴 요청(UDF 스타일)쿼리 타임아웃과 vLLM 응답시간 불일치 시 커넥션 누수 여부
JupyterLab사람이 쓰는 인터랙티브 — 낮은 동시성, 매우 불규칙, 장시간 유휴 후 갑작스런 요청Stage1에서 짚었던 "유휴 후 첫 요청 지연(warm-up latency)"이 K8s 파드 레벨에서도 재현되는지 — 특히 GPU가 아니라 파드 자체가 스케일다운되어 있다가 콜드 스타트하는 경우(오토스케일링 쓴다면) 지연이 수십 초까지 갈 수 있음
  • 신규 필요: Spark 스타일 "스텝 버스트" 부하 생성기 — 기존 stage3a6(점진적 램프업)와 별개로, 순간적으로 목표 동시성에 도달하는 패턴 전용 스크립트.
  • SYN Queue / Listen Backlog: Spark executor 수백 개가 동시에 vLLM 엔드포인트(혹은 앞단의 Gateway/Envoy)로 TCP 커넥션을 맺을 때 net.core.somaxconn 및 tcp_max_syn_backlog 제한으로 인한 패킷 드롭이 발생하기 쉽습니다.
  • vLLM Continuous Batching 큐잉 지연: 스텝 버스트 인입 시 vLLM의 KV Cache가 포화되어 대기 큐(Waiting Queue)에 머무르는 시간이 길어지며 발생하는 Time-to-First-Token(TTFT)의 P99 스파이크를 측정 지표로 명시하면 좋음.

E. MinIO AIStor 접근 경로 변화

  • 기존엔 STORAGE_NODE_IP 고정 IP로 접근했는데, ClusterMesh에서는 Global Service(같은 이름의 서비스가 여러 클러스터에 존재할 때 자동 로드밸런싱/장애조치)로 접근하게 됨. 이 서비스 디스커버리 자체의 지연과, 실제로 "가까운"(같은 클러스터) MinIO 백엔드를 우선 선택하는지(Cilium의 로컬리티 우선순위 설정) 확인 필요.
  • 재검증 필요: Stage2의 MinIO Cold Load 테스트를 ClusterMesh 경유로 재실행해서 대역폭 손실 여부 확인.
  • Cilium Topology Aware Routing: service.kubernetes.io/topology-mode: Auto 또는 Cilium 서비스 어노테이션을 통해 Compute 파드가 속한 클러스터/존의 MinIO 파드로 트래픽을 강제하는지 검증 필요. 로컬 노드 백엔드가 준비 상태임에도 ClusterMesh 터널을 타고 원격 클러스터 MinIO로 트래픽이 새어나가지 않는지 패킷 경로 확인이 필수.

F. 회복탄력성 (K8s라서 새로 생기는 항목)

  • 노드 드레인/코든: 유지보수 시 GPU 노드를 드레인하면 서빙 중인 vLLM 파드가 얼마나 우아하게 종료되는지(진행 중인 요청 처리 후 종료 vs 강제 킬), PodDisruptionBudget 동작 확인
  • Readiness Probe 오탐: DeepSeek-R1처럼 로딩에 수십 분 걸리는 모델은, 기본 HTTP readiness probe가 "포트는 열렸지만 모델 로딩 안 끝남" 상태에서 트래픽을 조기에 흘려보낼 위험 — initialDelaySeconds/startupProbe 설정 검증 필수
  • ClusterMesh 단절 시뮬레이션: 클러스터 간 연결이 일시적으로 끊겼을 때 GPU 노드가 로컬 트래픽은 정상 처리하는지, Compute 클러스터 쪽은 재시도/서킷브레이커로 우아하게 실패하는지(캐스케이딩 장애 방지)
  • StartupProbe 분리: Readiness 대신 startupProbe(failureThreshold × periodSeconds를 30분 이상으로 넉넉히 설정)를 적용하여 모델 체크포인트 다운로드 및 메모리 로딩 중 Kubelet이 컨테이너를 OOM/Restart 루프에 빠뜨리지 않도록 구성해야 합니다.
  • preStop Hook 구현: Kubelet 드레인 시 vLLM 프로세스가 SIGTERM을 받기 전 인그레스/엔드포인트 슬라이스에서 먼저 제외되도록 5~10초간 sleep을 주는 preStop 훅 유무를 검증 항목에 추가하세요.

G. 관측성 통합

  • Stage5e에서 독립적으로 띄운 Prometheus/Grafana를, 기존 클러스터에 이미 있는 모니터링 스택과 federation할지 별도로 유지할지 결정 필요
  • Cilium Hubble로 클러스터 간 트래픽 플로우/정책 드롭을 시각화 — 특히 네트워크 정책으로 막힌 트래픽을 조기에 발견하는 용도로 유용

H. 보안/네트워크 정책

  • 기존엔 firewalld 규칙이었는데, K8s에서는 CiliumNetworkPolicy/CiliumClusterwideNetworkPolicy로 전환 — Compute 클러스터의 어떤 워크로드 아이덴티티(namespace/서비스어카운트)만 GPU 서비스에 접근 가능한지를 IP 기반이 아니라 아이덴티티 기반으로 재설계·검증

I. 리소스 경합 (노이즈 네이버)

  • ClusterMesh로 물리 네트워크 팹릭을 공유하게 되므로, Spark의 대용량 셔플/StarRocks 쿼리가 네트워크를 점유할 때 GPU 노드의 외부 통신(모델 다운로드, KV 티어 트래픽)이 밀리는지 — Cilium Bandwidth Manager(대역폭 제한/QoS) 설정 여부에 따라 결과가 크게 갈림.
  • Cilium Bandwidth Manager는 Linux 커널 FQ(Fair Queueing)와 BPF 기반 패킷 스케줄링을 사용하므로, 노드 커널 버전 호환성과 활성화 여부(enable-bandwidth-manager: true)를 사전 확인해야 합니다.
  • CiliumNetworkPolicy 적용 시 eBPF 맵 엔트리가 과도하게 늘어나 데이터 플레인 지연(BPF Map lookup overhead)이 생기지 않는지 부하 상태에서 CPU/지연을 함께 관측하는 것이 좋음.

우선순위영역테스트 시나리오사전 조건 및 필수 설정핵심 측정 지표합격 기준 (Pass Criteria)
P0 (Critical)네트워크 기반Host vs hostNetwork vs Pod veth TCP 성능 및 RTT 비교MTU 9000 통일(스위치·노드·Pod veth); Cilium Native Routing 및 eBPF Host Routing 활성화iperf3 단일·멀티 Throughput; ping·sockperf RTT; CPU softirq 점유율Bare-metal 대비 처리량 손실률 5% 이하; Pod 간 RTT 증가 0.1ms 이하
P0 (Critical)GPU 통신Pod 환경 NCCL All-Reduce 대역폭 및 인터페이스 바인딩 검증NCCL_SOCKET_IFNAME 물리 NIC 지정; Pod net.ipv4.tcp_rmem/wmem 튜닝; NVIDIA Operator 및 Topology Manager 구성Bus Bandwidth (GB/s); NCCL 커널 로그 인터페이스 확인; NUMA 소켓 간 트래픽 여부단일 노드 8-GPU: Bare-metal 대비 NVLink 98% 이상 유지; 멀티 노드: Bare-metal 대비 TCP 90% 이상 유지
P0 (Critical)수명주기/안정성대형 모델(R1 등) Pod 콜드 스타트 및 Startup/Readiness 프로브 오탐 검증startupProbe 분리(failureThreshold 넉넉히 설정); Ingress/Service 라우팅 연계모델 가중치 메모리 적재 완료 시간; Probe 실패로 인한 컨테이너 비정상 재시작 횟수초기 모델 로딩 중 비정상 재시작 0회; 실제 서빙 준비 완료 전 트래픽 유입 0건
P1 (High)서비스 디스커버리ClusterMesh Global Service 경유 MinIO Cold Load 및 로컬리티 라우팅 검증Cilium ClusterMesh 피어링 정상 상태; service.kubernetes.io/topology-mode: Auto 적용MinIO 읽기·쓰기 Throughput (MB/s); 클러스터 간 Egress/Ingress 트래픽 발생 비율동일 클러스터 내 백엔드로 100% 로컬 라우팅 유지; 고정 IP 직접 접근 대비 전송 속도 저하 3% 이하
P1 (High)워크로드 부하Spark 대규모 동시 요청(스텝 버스트: 0→256) 급증 시 TCP 커넥션 처리somaxconn 및 tcp_max_syn_backlog 상향; Envoy/LiteLLM 연결 풀 설정 완료SYN Drop 횟수 (netstat -s); Conntrack 테이블 사용률; TTFT P95/P99 레이턴시SYN 드롭 및 커넥션 거부 0건; Conntrack 테이블 포화율 70% 이하
P1 (High)회복탄력성GPU 워커 노드 유지보수(Drain/Cordon) 시 Graceful Shutdown 및 PDB 동작preStop 훅(5~10초 sleep); PodDisruptionBudget(minAvailable) 설정처리 중이던 In-flight 요청 실패율; 엔드포인트 슬라이스 동기화 지연노드 드레인 시 처리 중인 요청의 502/504 에러 0건; PDB 위반 없는 롤링 퇴거 확인
P2 (Medium)라우팅 수렴ClusterMesh 장애·단절 시뮬레이션 및 BGP 라우트 수렴 시간 측정BGP 라우팅 피어링 및 BFD 연동; 장애 주입 툴 또는 인터페이스 down 스크립트BGP Route Convergence Time (초); 클러스터 단절 중 로컬 Pod 간 요청 성공률BGP 라우트 재수렴 3초 이하 (BFD 적용 시 1초 이하); 원격 클러스터 단절 시 로컬 트래픽 영향 0%
P2 (Medium)노이즈 네이버Spark 대용량 셔플·분산 쿼리와 GPU 통신 간 네트워크 경합 완화Cilium Bandwidth Manager 활성화; Linux 커널 FQ(Fair Queueing) 스케줄러 적용백그라운드 셔플 중 vLLM 토큰 생성 속도 저하율; 네트워크 패킷 지연 편차(Jitter)대역폭 포화 상태에서도 GPU 외부 통신 Throughput 저하 15% 이내 방어
P2 (Medium)보안/관측성CiliumNetworkPolicy 적용 및 Hubble 기반 클러스터 간 트래픽 플로우 추적Hubble Relay 및 UI/CLI 구동; Workload Identity(Namespace/SA) 기반 정책 배포eBPF 맵 엔트리 크기 및 메모리 점유율; 정책 파싱으로 인한 데이터 플레인 레이턴시정책 적용 전후 RTT 차이 오차범위(0.05ms 이하) 유지; 비인가 접근 즉각 DROP 및 감사 로그 적재

전체적으로 매우 좋은 구성입니다. 특히 “bare-metal 테스트를 K8s에서 반복한다”와 “K8s/ClusterMesh에서만 생기는 신규 failure mode를 별도로 검증한다”를 분리한 것이 맞습니다.

다만 실무 관점에서는 몇 군데 중요한 수정/보강이 필요합니다. 특히 B의 ClusterMesh 경로, E의 Global Service, C의 GPU topology, 그리고 I의 네트워크 경합은 조금 더 정확하게 정의하는 것이 좋습니다.

제가 보면 현재 문서는 약 85~90% 완성된 상태이고, 아래처럼 다듬으면 실제 K8s validation plan으로 바로 사용할 수 있습니다.


1. 전체 평가

영역평가수정 필요성
A. NCCL 재검증★★★★★거의 그대로 사용 가능
B. ClusterMesh★★★★☆Native routing/ClusterMesh 경로 표현 보강
C. GPU topology★★★★☆Topology Manager에 대한 표현 수정
D. 실제 workload★★★★☆일부 workload 특성 재검토
E. AIStor★★★★☆Global Service와 AIStor 고정 IP를 분리해서 정의
F. Resilience★★★★★매우 중요
G. Observability★★★★☆federation보다 correlation이 더 중요
H. Security★★★★★반드시 포함
I. Resource contention★★★★★매우 중요한 신규 항목

그리고 하나 더 추가하고 싶습니다.

J. Kubernetes scheduling / lifecycle / CPU-memory overhead

현재 문서에는 GPU와 network는 잘 들어가 있지만, K8s가 GPU inference 성능에 추가하는 CPU, memory, IRQ, cgroup, NUMA, eviction 등의 영향이 별도 항목으로 빠져 있습니다.


2. A — NCCL 재검증: 거의 정확함

이 부분은 그대로 가져가도 됩니다.

다만 문장을 하나 수정하는 것을 권합니다.

현재:

NCCL_SOCKET_IFNAME이 올바른 물리 NIC을 가리키는지

이렇게 쓰면 Pod 내부에서 물리 NIC 이름을 지정해야 한다는 의미로 오해할 수 있습니다.

일반 Pod에서는 Pod namespace 안에 물리 NIC이 직접 보이지 않고 보통 eth0가 보입니다.

따라서:

NCCL이 의도한 Pod interface/IP 경로를 선택하는지 확인하고, hostNetwork/일반 Pod에서 실제 물리 NIC으로 연결되는 경로를 검증한다.

가 더 정확합니다.

예를 들어:

Pod
  eth0
   │
   ▼
veth
   │
   ▼
Cilium eBPF
   │
   ▼
Linux routing
   │
   ▼
Intel E810

Native routing은 encapsulation을 하지 않고 Linux routing을 이용합니다. :chatgpt-content-reference{index="0"}

그리고 ClusterMesh에서도 cross-cluster Pod-to-Pod traffic은 별도의 proxy/gateway를 반드시 거치는 구조가 아닙니다. Cilium 문서도 노드 간, 클러스터 간 Pod traffic이 직접 forwarding된다고 설명합니다. :chatgpt-content-reference{index="1"}

따라서 A는:

Bare Metal
    ↓
hostNetwork Pod
    ↓
Cilium Pod

비교가 매우 좋습니다.


3. B — ClusterMesh: 방향은 맞지만 중요한 수정

여기서 가장 중요한 것은:

"ClusterMesh라서 TCP 경로에 추가 오버헤드가 붙는다"

라고 일반화하면 안 된다는 것입니다.

현재 구성:

Cilium
routing-mode=native
BGP
ECMP
ClusterMesh

이라면:

Pod A
 ↓
Cilium
 ↓
native routing
 ↓
Node NIC
 ↓
network
 ↓
Node NIC
 ↓
native routing
 ↓
Cilium
 ↓
Pod B

형태가 될 수 있습니다.

Native routing은 기본적으로 encapsulation을 하지 않습니다. :chatgpt-content-reference{index="2"}

따라서 B에서는 "ClusterMesh overhead"를 하나의 숫자로 측정하지 말고 경로별로 분리하는 것이 좋습니다.

제가 추천하는 비교

TestSource → Destination목적
B1Host → Host물리 네트워크 baseline
B2Pod → Pod, same nodeCilium local datapath
B3Pod → Pod, different node, same clusterCilium + native routing
B4Pod → Pod, different clusterClusterMesh + native routing
B5hostNetwork → hostNetworkPod/veth 제거 baseline
B6Pod → Pod + ECMPECMP path 확인

이렇게 하면:

B1 → B2

에서 Cilium 자체 비용,

B2 → B3

에서 node routing 비용,

B3 → B4

에서 ClusterMesh cross-cluster 비용

을 분리할 수 있습니다.

특히 RTT도 반드시 넣는 게 좋습니다.

단순 throughput뿐 아니라:

RTT
p50
p95
p99
jitter
packet loss
retransmission

을 봐야 합니다.

NCCL에서는 평균 bandwidth가 괜찮아도 tail latency / retransmission이 증가하면 collective performance가 크게 영향을 받을 수 있기 때문입니다.


4. BGP convergence도 매우 좋은 항목

이건 유지하세요.

다만:

수 초 vs 수십 초

처럼 고정된 기대치를 쓰기보다는 실제 환경에서 측정하는 게 좋습니다.

예:

T0       node down
T1       BGP route withdrawn
T2       Cilium route update
T3       ECMP table update
T4       traffic recovery

그리고 다음을 측정합니다.

Recovery Time
Packet Loss Duration
Connection Reset
Existing TCP session survival
New TCP connection recovery

특히 inference에서는:

새로운 요청이 복구되는 시간

뿐 아니라

이미 진행 중인 inference 요청이 살아남는가

가 중요합니다.


5. C — GPU topology: 맞지만 Topology Manager 표현은 수정

현재 문장:

NVIDIA GPU Operator + Node Feature Discovery + (필요시) Topology Manager

방향은 맞습니다.

하지만 Topology Manager가 "8 GPU가 같은 NVSwitch domain인지 보장하는 기능"이라고 이해하면 안 됩니다.

Topology Manager는 NUMA topology alignment 같은 리소스 할당 정합성에 중요한 역할을 하지만, GPU topology 자체를 magically 최적화해주는 것은 아닙니다.

따라서 실제 검증은:

nvidia-smi topo -m

와 Kubernetes에서 할당된 GPU ID를 연결해서 확인하는 방식이 좋습니다.

예:

Pod
 ├─ GPU0
 ├─ GPU1
 ├─ GPU2
 ...
 └─ GPU7

        ↓

nvidia-smi topo -m

GPU0 ↔ GPU1 : NV#
GPU0 ↔ GPU2 : NV#
...

그리고 TP=8에서는 GPU allocation 결과와 실제 NCCL topology를 같이 확인해야 합니다.

GPU Operator는 Kubernetes에서 GPU device plugin, GFD, DCGM 등 GPU 관련 구성요소를 관리합니다. :chatgpt-content-reference{index="3"}

MIG 부분

이것도 맞습니다.

다만 현재 B300 inference benchmark가 목적이라면 저는 문서에:

MIG 사용 여부를 테스트 시작 전에 고정한다.

라고 명시하는 것을 추천합니다.

MIG configuration은 GPU workload 자체를 중지시키는 reconfiguration이 될 수 있으므로 benchmark 중간에 변경하면 안 됩니다. NVIDIA GPU Operator의 MIG Manager도 configuration 변경 시 GPU workload와 관련 operator component를 중지시키는 절차를 수행합니다. :chatgpt-content-reference{index="4"}


6. D — workload 특성은 조금 수정하는 게 좋음

여기서는 Spark에 대한 표현을 약간 수정하고 싶습니다.

Spark가 수백 개 executor가 동시에 추론 요청을 쏜다

이것은 특정 Spark inference architecture에서는 맞지만 Spark 일반적인 특성이라고 정의하면 너무 강합니다.

더 정확하게:

Spark-based batch inference에서는 executor/task scheduling에 따라 요청이 짧은 시간에 집중되는 burst pattern이 발생할 수 있다.

정도가 좋습니다.

그리고 D에서 제가 하나 추가하고 싶은 것이 있습니다.

"burst → queue → recovery"

입니다.

단순:

0 → 256 concurrency

만 보는 것보다:

0
 ↓
256 burst
 ↓
queue 증가
 ↓
GPU saturation
 ↓
request completion
 ↓
0

전체 lifecycle을 측정해야 합니다.

특히:

  • queue time
  • TTFT
  • ITL
  • output tok/s
  • GPU utilization
  • KV cache utilization
  • error rate
  • recovery time

을 같이 봐야 합니다.


7. E — AIStor: 여기서 가장 큰 수정이 필요

현재:

ClusterMesh에서는 Global Service로 접근하게 됨.

이건 항상 그런 것은 아닙니다.

Global Service를 사용하도록 구성했을 경우에 그렇습니다.

Cilium ClusterMesh는 Global Service와 MCS-API 두 가지 방식으로 cross-cluster service discovery/load-balancing을 지원합니다. :chatgpt-content-reference{index="5"}

따라서:

AIStor fixed IP

와

AIStor ClusterIP

와

AIStor Global Service

를 서로 다른 테스트 케이스로 보는 것이 좋습니다.


특히 이 테스트가 좋습니다

Test접근 방식
E1Pod → AIStor local ClusterIP
E2Pod → AIStor remote ClusterIP/endpoint
E3Pod → Global Service, local preferred
E4Pod → Global Service, remote preferred
E5Global Service + local backend 장애
E6Global Service + cluster 장애

Cilium은 Global Service에 대해 service.cilium.io/affinity=local을 사용해서 local endpoint를 우선하고 local endpoint가 없거나 unhealthy할 때 remote endpoint를 사용할 수 있습니다. :chatgpt-content-reference{index="6"}

따라서 사용자 환경에서 AIStor 모델 로딩을 생각하면:

Inference Pod
       │
       ▼
 AIStor Global Service
       │
       ├── local AIStor   ← preferred
       │
       └── remote AIStor

이 구조가 실제로 의도대로 동작하는지 확인하는 것이 중요합니다.


8. F — Resilience: 아주 중요

이 부분은 반드시 유지하겠습니다.

특히 사용자 환경에서는:

DeepSeek-R1
large model
long loading time

이 있기 때문에 startupProbe와 readinessProbe를 별도 검증해야 합니다.

여기서 중요한 것은:

container started
       ≠
model loaded
       ≠
ready to serve

입니다.

따라서 최소한:

Pod Scheduled
   ↓
Container Started
   ↓
Model Loading
   ↓
Weights Loaded
   ↓
CUDA/NCCL initialized
   ↓
Warm-up completed
   ↓
Ready

각 timestamp를 수집하는 것이 좋습니다.


9. G — Observability: federation보다 더 중요한 게 있음

현재:

Prometheus/Grafana federation할지 별도 유지할지

이건 운영 설계 문제이고 테스트 항목에서는 조금 후순위입니다.

오히려 validation에서 중요한 것은 cross-layer correlation입니다.

예:

Request latency ↑
      │
      ├─ vLLM queue time ↑
      │
      ├─ GPU utilization ↑
      │
      ├─ Cilium drops ↑ ?
      │
      ├─ TCP retransmission ↑ ?
      │
      ├─ NIC utilization ↑ ?
      │
      └─ AIStor latency ↑ ?

즉 하나의 테스트 ID에:

vLLM
GPU/DCGM
Cilium
Hubble
Node exporter
NIC
Prometheus
AIStor

의 timestamp-aligned metric을 남기는 것이 더 중요합니다.

Hubble은 이 부분에 매우 적합합니다.


10. H — Security: 반드시 추가

이것도 아주 좋습니다.

특히 사용자 환경은:

Compute Cluster
     ↓
Gateway
     ↓
LLM Router
     ↓
GPU Cluster

구조를 고려하고 있기 때문에 단순 IP allowlist보다:

namespace
service account
Cilium identity

기반 접근 제어를 테스트해야 합니다.

예를 들어:

spark namespace
   └── inference SA       → allowed

jupyter namespace
   └── user SA            → allowed

random namespace
   └── default SA         → denied

그리고 반드시:

same-cluster
cross-cluster

둘 다 테스트해야 합니다.

ClusterMesh에서는 연결된 클러스터가 하나의 trust domain을 형성하므로, 보안 설계에서도 이 점을 별도로 고려해야 합니다. :chatgpt-content-reference{index="7"}


11. I — Resource contention: 이건 오히려 최상위 항목으로 올리고 싶음

이 부분은 아주 중요합니다.

특히 사용자 환경에서는:

GPU inference
      +
AIStor
      +
Spark shuffle
      +
StarRocks
      +
Trino

가 동일한 physical network fabric을 공유할 가능성이 있기 때문입니다.

예를 들어:

Spark shuffle
████████████████████████ 40Gbps

AIStor model load
████████ 10Gbps

NCCL TCP
██ 2Gbps

처럼 경쟁이 발생하면 inference 성능이 떨어질 수 있습니다.

그런데 이때 단순 GPU utilization만 보면:

GPU utilization 70%

처럼 정상적으로 보일 수도 있습니다.

그래서 반드시:

NIC throughput
NIC drops
TCP retransmission
Cilium drops
Cilium bandwidth
AIStor latency
NCCL bandwidth
GPU utilization

을 동시에 봐야 합니다.


12. 그리고 J를 하나 추가하는 것을 강력 추천

J. Kubernetes resource / NUMA / CPU overhead

이게 현재 문서에서 가장 큰 누락입니다.

Bare metal:

Process
 ↓
CPU
 ↓
GPU

K8s:

Pod
 ↓
cgroup
 ↓
CPU request/limit
 ↓
scheduler
 ↓
NUMA
 ↓
GPU

가 됩니다.

따라서 다음을 별도로 검증하는 것이 좋습니다.

Test확인 항목
J1CPU request/limit 영향
J2CPU pinning / exclusive CPU
J3NUMA locality
J4GPU ↔ CPU PCIe locality
J5IRQ/NIC ↔ CPU locality
J6CPU throttling
J7Memory pressure
J8OOM/eviction
J9Pod restart 후 GPU 재초기화
J10여러 inference Pod 간 CPU contention

특히 B300에서는 GPU만 잘 붙어 있다고 끝나는 것이 아닙니다.

예를 들어:

GPU0-3
   │
PCIe root complex A
   │
NUMA 0
   │
CPU 0-31

GPU4-7
   │
PCIe root complex B
   │
NUMA 1
   │
CPU 32-63

같은 topology라면 vLLM의 CPU-side preprocessing, networking, tokenization, scheduler, NCCL socket thread 등이 어느 NUMA에 배치되는지가 영향을 줄 수 있습니다.


13. 그래서 최종적으로는 이렇게 분류하는 것을 추천

현재 문서를 조금 재구성하면 훨씬 강력한 validation plan이 됩니다.

K8s validation의 4개 축

                  K8s GPU Validation
                         │
       ┌─────────────────┼─────────────────┐
       │                 │                 │
       ▼                 ▼                 ▼
  A. Regression      B. Network        C. Runtime
       │                 │                 │
 bare-metal vs       Cilium             GPU Operator
 K8s Pod              Native/BGP/ECMP    scheduling
       │              ClusterMesh        NUMA
 NCCL                 MTU                cgroup
 GPU topology         packet loss        lifecycle
       │              BGP convergence    probes
       │
       └──────────────────────┐
                              ▼
                       D. Application
                              │
                       vLLM / AIStor
                       Spark / Trino
                       StarRocks
                       Jupyter

그리고 테스트 번호를 다음처럼 만드는 것을 추천합니다.

Section의미
K1Bare-metal → Pod regression
K2GPU/NVLink/NCCL
K3Cilium datapath
K4ClusterMesh/BGP/ECMP
K5AIStor connectivity
K6GPU scheduling/NUMA
K7Workload/burst
K8Failure/Recovery
K9Security/NetworkPolicy
K10Observability
K11Resource contention

제가 특히 강조하고 싶은 5개

현재 문서에서 실제 장애를 잡아낼 가능성이 가장 높은 테스트는 다음 다섯 가지입니다.

① Bare metal → hostNetwork Pod → Cilium Pod NCCL 비교

→ GPU/container/Cilium 문제를 분리.

② Pod → same-node → same-cluster remote-node → cross-cluster iperf3

→ Cilium/Native Routing/ClusterMesh 오버헤드를 단계별 분리.

③ Global Service local/remote affinity

→ AIStor 모델 loading에서 의도하지 않은 cross-cluster traffic 방지. Cilium은 local affinity를 명시적으로 지원합니다. :chatgpt-content-reference{index="8"}

④ GPU topology + NUMA + CPU/NIC locality

→ "8 GPU가 할당됐다"와 "8 GPU가 효율적으로 연결됐다"는 다른 문제.

⑤ Network contention + inference 동시 부하

→ 실제 운영환경에서 가장 재현하기 어려운 AIStor/Spark/StarRocks/Trino ↔ inference 간 noisy-neighbor 문제를 잡을 수 있음.


최종 평가

따라서 현재 작성하신 A~I는 그대로 버릴 필요가 전혀 없고, 다음 세 가지를 수정하면 상당히 좋은 K8s validation plan이 됩니다.

  1. B: “ClusterMesh가 오버헤드를 만든다”가 아니라 same-node → same-cluster → cross-cluster로 경로별 측정
  2. E: “ClusterMesh에서는 Global Service를 쓴다”가 아니라 Global Service/MCS/fixed endpoint를 실제 구성에 맞게 구분
  3. J 추가: NUMA/CPU/cgroup/GPU scheduling/resource contention을 별도 검증

그리고 현재 사용자 환경처럼 Cilium Native + BGP + ECMP + ClusterMesh + B300 8GPU + AIStor 조합이라면, 저는 이 K8s 테스트를 단순히 “Stage 4”로 만들기보다 기존 Stage 1~3 결과를 기준선으로 삼는 K-Regression + K-Network + K-Resilience 구조로 만드는 것을 권합니다. Cilium의 Native Routing과 ClusterMesh는 실제로 cross-cluster Pod connectivity를 native datapath로 구성할 수 있기 때문에, 이 구조가 현재 환경과 가장 잘 맞습니다. :chatgpt-content-reference{index="9"}

profile
engineer

0개의 댓글