Skip to content

从零到一搭建企业级 K8s GPU 集群完整教程

RKE2 + Rancher + Harbor + GPU 虚拟化 + 分布式训练/推理

目标规模:30 台 GPU 物理机 × 8 × NVIDIA RTX PRO 6000 Blackwell(96GB)= 240 卡,约 23TB 显存平台:Ubuntu 24.04 + RKE2(K8s v1.35.6)+ Rancher 托管 + Harbor 私有仓库(纯内网) 能力:GPU 虚拟化(MIG/Time-Slicing)、RoCE RDMA 分布式训练、vLLM 大模型推理、Kueue 队列调度、多租户配额 本文覆盖:硬件选型推荐 → 机房组网布线 → 交换机配置 → BIOS/虚拟机 → OS → 平台部署 → 大模型上线 → 验收运维


目录

  • 第 1 章 总体方案与硬件配置推荐
  • 第 2 章 机房组网基础(拓扑/布线/交换机配置/RoCE 无损网络)
  • 第 3 章 服务器初始化(BIOS/固件/RAID/虚拟机创建)
  • 第 4 章 Ubuntu 24.04 安装与系统基线
  • 第 5 章 Harbor 私有镜像仓库(独立 VM)
  • 第 6 章 管理集群与 Rancher 安装
  • 第 7 章 GPU 集群 RKE2 部署
  • 第 8 章 GPU 能力接入与虚拟化(节点池化最佳实践)
  • 第 9 章 多租户体系(配额/RBAC/网络隔离)
  • 第 10 章 计算网接入(Multus + RDMA)
  • 第 11 章 Kueue 队列调度
  • 第 12 章 分布式训练(Kubeflow + NCCL)
  • 第 13 章 vLLM 推理服务与生产力大模型部署推荐
  • 第 14 章 监控告警体系
  • 第 15 章 整体验收 Checklist
  • 第 16 章 常见问题速查
  • 附录 A 镜像同步清单 / 附录 B 调池与运维速记 / 附录 C 术语表

第 1 章 总体方案与硬件配置推荐

1.1 总体架构

┌─────────────────────────── 管理面(虚拟化区) ──────────────────────────┐
│  Harbor VM(8C16G/2TB)   管理 RKE2 ×3(8C16G) 跑 Rancher   堡垒机/NTP/DNS │
│  10.10.0.10             10.10.0.11~13                     10.10.0.5    │
└────────────────────────────────┬───────────────────────────────────────┘
                                 │ Rancher 纳管 / Harbor 镜像分发
┌───────────────────────── GPU 集群(RKE2 v1.35.6) ─────────────────────┐
│  控制面 VM ×3(16C32G): 10.10.1.11~13,API VIP 10.10.1.10              │
│                                                                        │
│  GPU Worker ×30,节点池化:                                             │
│  ┌──────────────────┬──────────────────┬──────────────────┐            │
│  │ 训练池 ×20        │ 推理池 ×8         │ 开发池 ×2         │            │
│  │ 整卡 + RDMA       │ MIG 4×24GB/卡    │ Time-Slicing ×8  │            │
│  └──────────────────┴──────────────────┴──────────────────┘            │
│                                                                        │
│  网络三平面:                                                            │
│   ① 管理/K8s/存储网:双 100G bond0 (LACP) —— 10.10.0.0/16               │
│   ② 计算网:ConnectX-7 独立口 RoCEv2 —— 192.168.100.0/24(无损)        │
│   ③ IPMI/BMC 带外管理网 —— 172.16.0.0/24(独立低速交换机)              │
└────────────────────────────────────────────────────────────────────────┘

1.2 硬件配置推荐(可在此基线上加减)

1.2.1 GPU 服务器(30 台)推荐配置

部件推荐配置说明
GPU8 × RTX PRO 6000 Blackwell 96GB(PCIe 版)已确定;PCIe 版双宽风冷,确认机型散热/供电支持 8 卡 600W
CPU2 × AMD EPYC 9355/9455(32~48 核)或 2 × Intel Xeon 8570关键:每卡至少 8~12 物理核,8 卡建议 ≥64 核/机;PCIe 5.0 通道数 ≥128(8 卡 ×16 + 网卡 ×16)
内存1.5~2TB DDR5(24 × 64GB)经验值:显存总量 ×1.5~2 倍(8×96=768GB 显存 → 1.5TB 内存),vLLM KV offload、数据加载、页面缓存都吃内存
系统盘2 × 960GB SATA/NVMe SSD RAID1OS + 容器镜像
数据盘4 × 7.68TB NVMe U.2(≥15TB)模型权重本地预置(推荐方案)、训练数据集缓存、vLLM prefix cache;单盘读 ≥6GB/s
管理网卡1 × 双口 100G(CX-6/7 DX)做 bond0(LACP),承载 K8s/存储/管理
计算网卡1 × ConnectX-7 100G 单口(独立卡,不 bond)RoCEv2 RDMA 计算网,NCCL 专用;固件保持最新 GA
带外独立 IPMI/BMC(iDRAC/iLO/Redfish)接带外管理交换机,远程开关机/KVM/固件升级
电源2+2 冗余,单机满载约 6~7kW机柜供电按 8kW/柜规划(每柜 1 台)或 16kW/柜(2 台)
机型参考超微 AS-4125GS / 浪潮 NF5688 类 8 卡 PCIe 机型4U,确认 GPU 拓扑为 单 PCIe switch 平面或双 socket 均衡nvidia-smi topo -m 验证)

CPU/内存不足的代价:数据加载瓶颈(GPU 空转)、vLLM 权重加载慢、容器镜像解压缩慢。240 卡集群不要在这些部件上省钱。

1.2.2 虚拟化宿主机(跑 9 台 VM)

用途推荐说明
宿主机2 台通用服务器(每台 2×16 核 / 512GB / 2×3.84TB NVMe RAID1 / 双 25G)跑 KVM(libvirt) 或 VMware ESXi
VM 清单GPU CP ×3(16C32G/200G盘)、管理 RKE2 ×3(8C16G/100G盘)、Harbor ×1(8C16G/2TB 数据盘)、堡垒机 ×1(4C8G)跨 2 台宿主机反亲和放置,控制面不挤一台

1.2.3 网络设备推荐

设备推荐数量说明
管理/存储接入交换机100G 交换机(如 NVIDIA SN3700 / 华为 CE6857 / H3C S6850),支持 MLAG + LACP + jumbo2 台(堆叠/MLAG)30 台 × 2 口 = 60 个 100G 口 + 上联
计算网交换机NVIDIA Spectrum-3/4(SN4000 系列)或同级支持 RoCE 无损的 100G/400G 交换机1~2 台30 个 100G 下联网口,1:1 无阻塞;必须支持 PFC + ECN
带外管理交换机48 口千兆1 台IPMI 专用
线缆100G DAC(同柜)/ AOC(跨柜)60 + 30 条DAC ≤3m 省钱稳定;跨排用 AOC 或光模块+多模光纤

1.2.4 存储(可选但推荐)

方案推荐场景
节点本地 NVMe(本教程默认)模型权重预置、数据集缓存;零额外成本,速度最快
分布式存储 Ceph(3~5 台存储节点)需要 PVC 动态供给、模型版本共享、 checkpoint 集中保存时增加;独立 25G/100G 网
NFS 一体机轻量共享(配置文件、小模型),最简单

预算允许建议加 3 台 Ceph 存储节点(每台 2×16核/256GB/10×7.68TB NVMe/双 100G),否则用本地 NVMe + NFS 组合即可跑通全流程。

1.2.5 版本基线(最佳实践定稿)

组件版本组件版本
Ubuntu24.04 LTS(内核 6.8+)NVIDIA 驱动570.x(PRO/数据中心分支)
RKE2v1.35.6+rke2r1CUDA / NCCL12.8 / 2.26.x
Rancherv2.12.xPyTorchNGC 25.05-py3(2.7.x)
Harborv2.12.xvLLMv0.9.x
GPU Operatorv25.3.xLWSv0.6.x
Network Operatorv25.4.xKueuev0.12.x
Kubeflow Training Op.v1.9.xMultusv4.2.x

第 2 章 机房组网基础

2.1 三张网的设计理念(为什么要分网)

网络平面流量特征设计要点
① 管理/K8s/存储网突发、混合(API、镜像拉取、etcd、模型分发)双口 bond 提高可用性;可容忍拥塞
② 计算网(RDMA)大流量、延迟敏感、丢包零容忍(NCCL AllReduce/AllGather)独立物理网络、无阻塞、无损(PFC+ECN),与管理网故障域隔离
③ 带外管理网极小流量(IPMI)物理隔离,带内网络挂掉也能救机器

混在一起的典型事故:拉取 20GB 训练镜像时 NCCL 超时、训练任务挂死。分网是 GPU 集群的第一原则。

2.2 物理拓扑与布线

                ┌──────────┐  ┌──────────┐
                │ 管理SW-A │──│ 管理SW-B │   (MLAG 对,双活)
                └────┬─────┘  └─────┬────┘
        ┌────────────┼──────────────┼────────────┐
        │            │              │            │   每台 GPU 服务器双 100G 口
     ┌──┴──┐      ┌──┴──┐        ┌──┴──┐      ┌──┴──┐  分别接 SW-A / SW-B(bond0 LACP)
     │GPU-1│ ...  │GPU-15          GPU-16 ... │GPU-30│
     └──┬──┘      └──┬──┘        └──┬──┘      └──┬──┘
        │            │              │            │
        └────────────┴──────┬───────┴────────────┘   每台 CX-7 计算口单线
                     ┌──────┴───────┐                 接入计算交换机
                     │  计算网 SW    │  (100G×30 下联,无阻塞)
                     └──────────────┘

布线规范

  1. 管理网双口分别接两台交换机(跨机箱链路聚合),单交换机故障不断网。
  2. 计算网单口接计算交换机;30 台全在同一台交换机(单跳)性能最优;若两台则做 spine-leaf 且保证同池同 leaf。
  3. 同柜用 100G DAC(≤3m),跨柜用 AOC;线缆两端打标签(机柜-端口号)。
  4. 服务器上架:8 卡 GPU 机 4U/6~7kW,每机柜最多 2 台(16kW 供电),注意机房承重与冷热通道。
  5. IPMI 全部接带外交换机,DHCP 或静态 172.16.0.x。

2.3 VLAN 与 IP 规划

VLAN网段用途
1010.10.0.0/24管理面(Harbor/Rancher/堡垒机)
1110.10.1.0/24GPU 集群控制面 + VIP
1210.10.2.0/24GPU Worker(bond0)
100192.168.100.0/24计算网(纯二层,无需 VLAN 也可独立物理网)
200172.16.0.0/24IPMI 带外

节点 IP 分配(固定规则,便于脚本生成):

角色主机名bond0 IP计算网 IP
堡垒机/NTP/DNSbastion10.10.0.5-
Harborharbor10.10.0.10-
管理 RKE2 ×3mgmt-01~0310.10.0.11~13-
Rancher VIP-10.10.0.14-
GPU CP ×3gpu-cp-01~0310.10.1.11~13-
GPU API VIP-10.10.1.10-
训练池 ×20gpu-train-01~2010.10.2.11~30192.168.100.11~30
推理池 ×8gpu-infer-01~0810.10.2.31~38192.168.100.31~38
开发池 ×2gpu-dev-01~0210.10.2.39~40192.168.100.39~40

2.4 交换机配置(关键,逐条照做)

2.4.1 管理网交换机(双机 MLAG + LACP)

通用配置要求:

1. 两台交换机配置 MLAG(华为 iStack/CE M-LAG,H3C IRF,NVIDIA Cumulus clag)
2. 每台服务器一个 port-channel(LACP mode active),成员口为两个交换机上同编号口
3. VLAN:10/11/12 放行(trunk 或 access 按规划)
4. 全局 MTU ≥ 9216(jumbo)
5. 上联口:接核心/出口(或纯内网只接防火墙管理区)

华为 CE 系列示例(一台服务器接 SW-A 的 GE1/0/1 和 SW-B 的 GE1/0/1):

# SW-A 与 SW-B 都执行(M-LAG 双活网关场景)
interface Eth-Trunk11
 mode lacp-static
 lacp timeout fast
 port link-type access
 port default vlan 12
 stp edged-port enable
#
interface 100GE1/0/1
 eth-trunk 11
 mtu 9216

2.4.2 计算网交换机(RoCEv2 无损 —— 最重要的配置)

RoCEv2 无损三件套:PFC + ECN + 大 buffer 队列。不配置 = NCCL 性能腰斩甚至超时挂死。

NVIDIA Spectrum(Cumulus/ONYX)示例:

# ONYX(Mellanox 交换机)
interface ethernet 1/1-1/30 mtu 9216 force
# 全局开启 RoCE 无损(ONYX 有一键配置)
roce mode lossless
# 或手工等价配置:
lldp dcbx enable
interface ethernet 1/1-1/30 traffic-class 3 pfc enable
interface ethernet 1/1-1/30 traffic-class 3 buffer strict-priority
interface ethernet 1/1-1/30 ecn minimum-threshold 150000 maximum-threshold 1500000

华为 CE 示例:

dcb pfc enable
interface 100GE1/0/1
 mtu 9216
 dcb pfc enable mode manual
 dcb pfc 3 enable                # 优先级 3 开 PFC
 dcb ets enable
 qos queue 3 ecn low-limit 150 high-limit 1500   # ECN 门限

服务器侧对应(第 10 章 NCCL 环境变量):

  • NCCL_IB_GID_INDEX=3(RoCEv2)
  • 网卡 DSCP/PFC 优先级映射与交换机一致(默认 priority 3)

验收方法:配置完成后两台服务器跑 ib_write_bw 应 ≥95Gb/s;训练池 NCCL AllReduce busbw ≥9GB/s。不达标先查这里。


第 3 章 服务器初始化

3.1 GPU 服务器 BIOS 设置(30 台逐台)

项目推荐值原因
Above 4G DecodingEnabled8 卡 BAR 空间大,必须开,否则显卡点不亮/识别不全
Resizable BAR (Re-Size BAR)Enabled提升显存映射性能
SR-IOVEnabled网卡 VF 与虚拟化需要
IOMMU / VT-dDisabled(裸金属 GPU 推荐关)裸金属 + 容器场景开启会增加 DMA 开销;若后续要 GPU 直通 VM 再开
CPU Performance ProfileMaximum Performance关闭节能,降低 jitter
C-States / C1EDisabled训练同步敏感
NUMAEnabled(默认)记住拓扑,训练时做 NUMA 绑定
PCIe 链路速率Gen5 x16(确认 8 卡全部协商成功)装完系统用 lspci -vv 验证 LnkSta
Boot 模式UEFI
BMC/IPMI静态 IP 172.16.0.x,开 Redfish带外批量管理

3.2 固件升级清单

  • 主板 BIOS、BMC 固件 → 厂商最新稳定版
  • ConnectX-7 固件:mlxfwmanager(MFT 工具包)升级到最新 GA
  • RTX PRO 6000 VBIOS:随机型厂商基线即可,驱动安装后 nvidia-smi -q | grep -i vbios

3.3 虚拟化宿主机与 VM 创建(KVM 示例)

宿主机装 Ubuntu 24.04 + KVM:

bash
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst

# 桥接到管理网 VLAN(例:宿主机 ens3 在 VLAN10)
# netplan 建 br0 桥,VM 挂 br0

# 创建一台控制面 VM(其余改名字/资源/MAC 重复执行)
virt-install \
  --name gpu-cp-01 --vcpus 16 --memory 32768 \
  --disk path=/var/lib/libvirt/images/gpu-cp-01.qcow2,size=200,bus=virtio \
  --network bridge=br0,model=virtio,mac=52:54:00:10:01:11 \
  --cdrom /iso/ubuntu-24.04-live-server-amd64.iso \
  --cpu host-passthrough --os-variant ubuntu24.04 \
  --graphics vnc,listen=0.0.0.0 --noautoconsole

VM 规划与反亲和:

VMvCPU/内存/磁盘宿主机
gpu-cp-01 / mgmt-01 / harbor16C32G/200G,8C16G/100G,8C16G/2TB宿主机 A
gpu-cp-02 / mgmt-02 / bastion同上宿主机 B
gpu-cp-03 / mgmt-03同上宿主机 A(或第三台)

Harbor 的 2TB 数据盘单独挂一个 virtio 盘(/dev/vdb/data/harbor),与系统盘分离。

3.4 Ubuntu 24.04 安装要点(所有节点)

  • Subiquity 安装,最小化(minimized),只勾选 OpenSSH Server。
  • 分区:系统盘 LVM 默认即可;数据 NVMe 盘先不分,装完系统再格式化。
  • 主机名严格按规划(gpu-train-01 等),安装时直接填对。
  • 安装源:内网环境建议先搭一个临时 apt 源(外网机器 apt-mirror 或用 ubuntu ISO 做本地源),否则 apt install 会失败。最小必需包列表:net-tools iproute2 ethtool rdma-core ibverbs-utils perftest keepalived ca-certificates curl

第 4 章 Ubuntu 24.04 系统基线(所有节点)

4.1 基线脚本

bash
#!/bin/bash
# base-init.sh —— 所有节点(CP VM + 30 台 Worker)
set -e
sudo timedatectl set-timezone Asia/Shanghai

# NTP 指向内网堡垒机
sudo sed -i 's/^#NTP=.*/NTP=10.10.0.5/' /etc/systemd/timesyncd.conf
sudo systemctl restart systemd-timesyncd

# 关 swap
sudo swapoff -a && sudo sed -i '/swap/d' /etc/fstab

# 内核模块与转发
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
vm.max_map_count                    = 262144
EOF
sudo sysctl --system

# 禁用 nouveau
cat <<EOF | sudo tee /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
EOF
sudo update-initramfs -u

# hosts 内网解析(无内网 DNS 时)
cat <<EOF | sudo tee -a /etc/hosts
10.10.0.10 harbor.example.com
10.10.0.14 rancher.example.com
10.10.1.10 api.gpu-cluster.example.com
EOF

# 常用工具
sudo apt install -y net-tools ethtool curl wget htop iotop nvme-cli

echo "完成,请重启: sudo reboot"

4.2 数据盘格式化(GPU Worker,本地 NVMe 模型盘)

bash
# 4 块 NVMe 做 RAID0(追求容量+带宽;要求可靠性可换 RAID10)
sudo apt install -y mdadm
sudo mdadm --create /dev/md0 --level=0 --raid-devices=4 /dev/nvme0n1 /dev/nvme1n1 /dev/nvme2n1 /dev/nvme3n1
sudo mkfs.xfs /dev/md0
sudo mkdir -p /data
echo '/dev/md0 /data xfs defaults,noatime 0 0' | sudo tee -a /etc/fstab
sudo mount -a
df -h /data    # 约 30TB(4×7.68)
sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf
sudo update-initramfs -u

4.3 netplan:bond0 + 计算口(GPU Worker)

yaml
# /etc/netplan/50-cluster.yaml(gpu-train-01 示例,口名按 ip link 实际改)
network:
  version: 2
  ethernets:
    ens1f0np0: {mtu: 9000}                       # 管理网 100G 口1 → 管理SW-A
    ens1f1np0: {mtu: 9000}                       # 管理网 100G 口2 → 管理SW-B
    ens2f0np0:                                   # CX-7 计算口 → 计算网SW
      mtu: 9000
      addresses: [192.168.100.11/24]
  bonds:
    bond0:
      interfaces: [ens1f0np0, ens1f1np0]
      mtu: 9000
      addresses: [10.10.2.11/24]
      routes: [{to: default, via: 10.10.2.1}]
      nameservers: {addresses: [10.10.0.5]}
      parameters:
        mode: 802.3ad
        lacp-rate: fast
        mii-monitor-interval: 100
        transmit-hash-policy: layer3+4
bash
sudo netplan apply
cat /proc/net/bonding/bond0 | grep -E "Mode|MII Status|Speed"   # 双口 up、200G

控制面 VM/管理 VM:单网卡 netplan 配静态 IP 即可(无需 bond)。

4.4 RDMA 环境验证(GPU Worker 计算口)

bash
sudo apt install -y rdma-core ibverbs-utils perftest infiniband-diags
ibv_devices                        # 应列出 mlx5_x(CX-7)
show_gids                          # 确认 RoCEv2 的 GID index(通常 3)
ibstat | grep -E "State|Rate"      # Active / 100 Gb/sec

# 两台互测带宽(一台做服务端,另一台做客户端)
ib_write_bw -d mlx5_0 --report_gbits                 # 服务端
ib_write_bw -d mlx5_0 --report_gbits 192.168.100.12  # 客户端 → 期望 ≥95 Gb/s

不达标排查顺序:MTU 是否端到端 9000 → 交换机 PFC/ECN → 线缆/光模块 → 固件版本。

4.5 防火墙端口(如启用 ufw)

组件端口
RKE2 server9345/tcp、6443/tcp、etcd 2379-2380/tcp
RKE2 全节点8472/udp(cilium vxlan)、10250/tcp
NodePort30000-32767/tcp
建议集群内网段全放通,仅限制外部访问 6443/30080 等

第 5 章 Harbor 私有镜像仓库(独立 VM)

5.1 安装 Docker + Harbor

bash
# Harbor VM(10.10.0.10),数据盘挂 /data/harbor
sudo mkfs.xfs /dev/vdb && sudo mkdir -p /data/harbor
echo '/dev/vdb /data/harbor xfs defaults 0 0' | sudo tee -a /etc/fstab && sudo mount -a

# Docker 离线包安装(外网机器提前下载 deb 拷入)
sudo dpkg -i containerd.io_*.deb docker-ce_*.deb docker-ce-cli_*.deb docker-compose-plugin_*.deb
sudo systemctl enable --now docker

# Harbor 离线安装包
tar xf harbor-offline-installer-v2.12.*.tgz && cd harbor
cp harbor.yml.tmpl harbor.yml

harbor.yml 关键配置:

yaml
hostname: harbor.example.com
http:
  port: 80                     # 内网起步用 http;建议后期配内网 CA 切 https(改动见下)
harbor_admin_password: 'xxx'
database:
  password: 'xxx'
data_volume: /data/harbor
trivy:
  ignore_unfixed: false
  skip_update: true            # 内网无法更新漏洞库,跳过
bash
sudo ./install.sh --with-trivy
docker compose ps        # 约 10 个容器 Up
# 浏览器访问 http://harbor.example.com,admin 登录

5.2 项目与机器人账户规划

Harbor 项目内容
gpu-cluster业务镜像(pytorch、vllm、nccl-tests、模型镜像)
platform平台组件镜像(gpu-operator、rancher、kueue、lws、multus、monitoring 全套)
library基础镜像(cuda、ubuntu、busybox)

创建机器人账户:系统管理 → 机器人账户 → 新建 robot$puller,权限:所有项目只读拉取,永不过期(或按安全策略定期轮换),记下 token

5.3 镜像同步(内网成败的关键一步)

5.3.1 流程

外网中转机:拉取镜像 → docker save / skopeo 打包 → 拷入内网 Harbor VM → docker load → 打 tag → push

5.3.2 中转机批量导出脚本

bash
# 外网中转机执行;images.txt 见附录 A
mkdir -p /export/images
while read img; do
  docker pull "$img"
done < images.txt
docker save -o /export/gpu-images.tar $(cat images.txt | tr '\n' ' ')
# helm chart 同步(需要 helm 与 helm-push 插件或直接下载 tgz)
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia && helm repo update
helm pull nvidia/gpu-operator --version 25.3.2 -d /export/charts/
# 同理 pull: rancher、network-operator、kueue、kube-prometheus-stack 等

5.3.3 Harbor VM 导入推送脚本

bash
# push-images.sh —— 在 Harbor VM 执行
set -e
docker load -i /export/gpu-images.tar
HARBOR=harbor.example.com
docker login $HARBOR -u admin -p '<密码>'

# 规则:docker.io/x/y:tag → $HARBOR/library/y:tag(或按附录 A 的映射表)
#      nvcr.io/nvidia/y:tag → $HARBOR/platform/y:tag(或 gpu-cluster)
while read img; do
  repo=$(echo "$img" | sed -E 's#^(docker.io/|nvcr.io/nvidia/|quay.io/|registry.k8s.io/|ghcr.io/)##')
  # 按需指定目标项目(示例统一进 platform,业务镜像单独处理)
  dst="$HARBOR/platform/$repo"
  docker tag "$img" "$dst"
  docker push "$dst"
done < images.txt

helm chart 推送:开启 Harbor Chart 仓库(ChartMuseum)或用 OCI:helm push xxx.tgz oci://harbor.example.com/platform。本文命令中 harbor-chartmuseum/platform/xxx 表示 ChartMuseum 路径。

5.4 RKE2 全节点 registries.yaml(统一镜像入口)

所有 CP VM 和 30 台 Worker 都要配置(在安装 RKE2 之前放好):

yaml
# /etc/rancher/rke2/registries.yaml
mirrors:
  docker.io:
    endpoint: ["http://harbor.example.com"]
  nvcr.io:
    endpoint: ["http://harbor.example.com"]
  quay.io:
    endpoint: ["http://harbor.example.com"]
  registry.k8s.io:
    endpoint: ["http://harbor.example.com"]
configs:
  "harbor.example.com":
    auth:
      username: xxx
      password: <机器人token>

切 https 后:在 configs 加 tls.ca_file: /etc/rancher/rke2/harbor-ca.crt,并把 CA 拷到每个节点 /usr/local/share/ca-certificates/update-ca-certificates


第 6 章 管理集群与 Rancher 安装

6.1 管理 RKE2 集群(mgmt-01~03)

bash
# 三台管理 VM 通用(离线 artifact 方式:外网机器下载以下文件拷入 /opt/rke2-artifacts)
#   rke2.linux-amd64.tar.gz、rke2-images.linux-amd64.tar.zst、sha256sum-amd64.txt、install.sh
sudo mkdir -p /opt/rke2-artifacts /etc/rancher/rke2

# mgmt-01(首节点)
sudo INSTALL_RKE2_VERSION="v1.35.6+rke2r1" \
     INSTALL_RKE2_ARTIFACT_PATH=/opt/rke2-artifacts sh install.sh

sudo tee /etc/rancher/rke2/config.yaml <<EOF
token: "xxx"
tls-san:
  - 10.10.0.14
  - rancher.example.com
EOF
# registries.yaml 按 5.4 放置
sudo systemctl enable --now rke2-server
sudo journalctl -u rke2-server -f    # 等待 "rke2 is up and running"

mkdir -p ~/.kube && sudo cp /etc/rancher/rke2/rke2.yaml ~/.kube/config && sudo chown $USER ~/.kube/config
echo 'export PATH=$PATH:/var/lib/rancher/rke2/bin' >> ~/.bashrc && source ~/.bashrc
kubectl get nodes
bash
# mgmt-02 / mgmt-03:相同安装,config.yaml 改为:
sudo tee /etc/rancher/rke2/config.yaml <<EOF
server: https://10.10.0.11:9345
token: "xxx"
tls-san:
  - 10.10.0.14
  - rancher.example.com
EOF
sudo systemctl enable --now rke2-server

三台 keepalived 提供 Rancher VIP 10.10.0.14(配置模板见 7.4,改 IP 与网卡即可)。

6.2 安装 Rancher

bash
# helm 二进制离线拷入管理集群
curl -Lo helm.tar.gz https://get.helm.sh/helm-v3.17.0-linux-amd64.tar.gz   # 外网机器下载后拷入
tar xf helm.tar.gz && sudo install linux-amd64/helm /usr/local/bin/

helm install rancher harbor-chartmuseum/platform/rancher \
  -n cattle-system --create-namespace \
  --version 2.12.x \
  --set hostname=rancher.example.com \
  --set replicas=3 \
  --set rancherImage=harbor.example.com/platform/rancher \
  --set systemDefaultRegistry=harbor.example.com \
  --set useBundledSystemChart=true

kubectl -n cattle-system rollout status deploy/rancher
# 访问 https://rancher.example.com(或 http 按 bootstrap 配置),设置 admin 密码

--set systemDefaultRegistry=harbor.example.com 是内网关键:Rancher 下发到被纳管集群的 agent 镜像全部从 Harbor 拉。

6.3 Rancher 纳管 GPU 集群

第 7 章建好 GPU 集群后:

  1. Rancher UI → Cluster Management → Import Existing → 任意集群
  2. 拷贝生成的注册命令,在 GPU 集群执行:
bash
kubectl apply -f https://rancher.example.com/v3/import/<token>_<clusterid>.yaml
kubectl -n cattle-system get pods    # cattle-cluster-agent Running 即纳管成功

纳管后可在 Rancher UI 完成:节点查看/驱逐、Project/命名空间与 RBAC、监控告警开启、集群快照备份。


第 7 章 GPU 集群 RKE2 部署

7.1 首控制面节点(gpu-cp-01)

bash
sudo mkdir -p /opt/rke2-artifacts /etc/rancher/rke2
# artifact 与 registries.yaml 就位后:
sudo INSTALL_RKE2_VERSION="v1.35.6+rke2r1" \
     INSTALL_RKE2_ARTIFACT_PATH=/opt/rke2-artifacts sh install.sh

sudo tee /etc/rancher/rke2/config.yaml <<EOF
token: "xxx"
tls-san:
  - 10.10.1.10
  - api.gpu-cluster.example.com
cni: cilium
disable:
  - rke2-ingress-nginx          # 不用 ingress(NodePort 方案),减少组件
cluster-cidr: 10.42.0.0/16
service-cidr: 10.43.0.0/16
EOF

sudo systemctl enable --now rke2-server
mkdir -p ~/.kube && sudo cp /etc/rancher/rke2/rke2.yaml ~/.kube/config && sudo chown $USER ~/.kube/config
echo 'export PATH=$PATH:/var/lib/rancher/rke2/bin' >> ~/.bashrc && source ~/.bashrc
kubectl get nodes

7.2 控制面扩容(gpu-cp-02/03)

bash
sudo tee /etc/rancher/rke2/config.yaml <<EOF
server: https://10.10.1.11:9345
token: "xxx"
tls-san: ["10.10.1.10"]
EOF
sudo systemctl enable --now rke2-server
kubectl get nodes    # 3 台 Ready

7.3 etcd 快照(控制面数据备份,重要)

bash
# 每天定时快照到 NFS/管理机
sudo tee /etc/cron.d/rke2-etcd-snapshot <<'EOF'
0 2 * * * root /var/lib/rancher/rke2/bin/rke2 etcd-snapshot save --name daily-$(date +\%F) --etcd-snapshot-retention 14
EOF

7.4 API 高可用 VIP(三台 CP 装 keepalived)

bash
sudo apt install -y keepalived
sudo tee /etc/keepalived/keepalived.conf <<EOF
vrrp_instance VI_1 {
    state MASTER               # cp-02/03 改为 BACKUP
    interface ens3             # VM 网卡名(ip link 确认)
    virtual_router_id 51
    priority 100               # BACKUP: 90 / 80
    advert_int 1
    authentication { auth_type PASS auth_pass 11111111 }
    virtual_ipaddress { 10.10.1.10/24 }
}
EOF
sudo systemctl enable --now keepalived
ip a | grep 10.10.1.10
# ~/.kube/config 的 server 改为 https://10.10.1.10:6443

7.5 30 台 GPU Worker 加入(节点池标签 + taint)

bash
# 每台 Worker(以训练池 gpu-train-01 为例)
sudo mkdir -p /opt/rke2-artifacts /etc/rancher/rke2
# registries.yaml 按 5.4 就位

sudo INSTALL_RKE2_VERSION="v1.35.6+rke2r1" INSTALL_RKE2_TYPE="agent" \
     INSTALL_RKE2_ARTIFACT_PATH=/opt/rke2-artifacts sh install.sh

sudo tee /etc/rancher/rke2/config.yaml <<EOF
server: https://10.10.1.10:9345
token: "xxx"
node-label:
  - "node-role.kubernetes.io/gpu-worker=true"
  - "gpu.nvidia.com/model=rtx-pro-6000"
  - "gpu-cluster.io/pool=train"          # 推理池=infer,开发池=dev
node-taint:
  - "gpu-cluster.io/pool=train:NoSchedule"
EOF

sudo systemctl enable --now rke2-agent

控制面验证:

bash
kubectl get nodes -L gpu-cluster.io/pool
kubectl describe node gpu-train-01 | grep -A2 Taints

业务 Pod 进池的标准写法(平台模板统一注入):

yaml
tolerations:
- {key: gpu-cluster.io/pool, operator: Equal, value: train, effect: NoSchedule}
nodeSelector: {gpu-cluster.io/pool: train}

批量部署 30 台:建议用 Ansible(inventory 按 train/infer/dev 分组),playbook 内容就是 4.1/4.2/4.3/7.5 的命令模板化;或用 Rancher 纳管后以 Fleet 下发。


第 8 章 GPU 能力接入与虚拟化(节点池化最佳实践)

8.1 虚拟化方案对比与选型结论

方案隔离级别粒度适用场景结论
整卡最强1 卡训练、超大模型推理训练池 20 台
MIG硬件级硬隔离(显存/算力/SM)RTX PRO 6000:每卡最多 4 个 1g.24gb多租户推理(≤70B 单实例放不下的模型用整卡)推理池 8 台
Time-Slicing无隔离(共享显存,时间片轮转)任意份数开发调试、Notebook、CI开发池 2 台
NVIDIA vGPU硬件级需企业 License + vGPU Manager虚拟化桌面场景本方案不用
HAMi软件显存/算力限流MB/百分比级需要按显存精确计费切分备选,默认不装

核心原则:一张卡只用一种切分方式,一类节点只服务一类业务,用 label + taint 隔离。

8.2 安装 GPU Operator

bash
# 镜像已全部同步 Harbor platform 项目
helm install gpu-operator harbor-chartmuseum/platform/gpu-operator \
  -n gpu-operator --create-namespace --version 25.3.x \
  --set operator.repository=harbor.example.com/platform \
  --set driver.enabled=true \
  --set driver.version=570.133.20 \
  --set driver.repository=harbor.example.com/platform \
  --set toolkit.enabled=true \
  --set devicePlugin.enabled=true \
  --set dcgmExporter.enabled=true \
  --set migManager.enabled=true \
  --set validator.repository=harbor.example.com/platform

kubectl -n gpu-operator get pods -w     # 等待全部 Running(driver 编译安装需 5~15 分钟)

验证 GPU 可见:

bash
kubectl run gpu-test --rm -it --restart=Never \
  --image=harbor.example.com/library/cuda:12.8.0-base-ubuntu24.04 \
  --overrides='{
    "spec":{
      "tolerations":[{"key":"gpu-cluster.io/pool","operator":"Equal","value":"train","effect":"NoSchedule"}],
      "nodeSelector":{"gpu-cluster.io/pool":"train"},
      "containers":[{
        "name":"gpu-test",
        "image":"harbor.example.com/library/cuda:12.8.0-base-ubuntu24.04",
        "command":["nvidia-smi","-L"],
        "resources":{"limits":{"nvidia.com/gpu":1}}
      }]
    }}'
# 期望输出:GPU 0: NVIDIA RTX PRO 6000 Blackwell ...

节点 GPU 拓扑确认(训练性能基础):

bash
kubectl debug node/gpu-train-01 -it --image=harbor.example.com/library/ubuntu:24.04 -- chroot /host nvidia-smi topo -m
# 8 卡之间 PIX/PXB 为优;跨 socket 的 SYS 路径尽量避免(训练框架用 CUDA_VISIBLE_DEVICES 排序规避)

8.3 训练池(20 台):默认整卡,无需操作

kubectl describe node gpu-train-01 | grep nvidia.com/gpu 应显示 8

8.4 推理池(8 台):启用 MIG

bash
# 整卡切 4 个 1g.24gb 实例(8 台共 8×8×4=256 个实例)
for n in gpu-infer-0{1..8}; do
  kubectl label node $n nvidia.com/mig.config=all-1g.24gb --overwrite
done
kubectl -n gpu-operator logs -l app=nvidia-mig-manager -f     # 观察切分
kubectl get node gpu-infer-01 -o json | jq '.status.allocatable' | grep mig
# 期望:nvidia.com/mig-1g.24gb: "32"

临时整卡:某台需跑 70B+ 大模型时 kubectl label node gpu-infer-08 nvidia.com/mig.config=all-disabled --overwrite(先 drain 该节点)。

8.5 开发池(2 台):Time-Slicing

yaml
# time-slicing-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: time-slicing-config
  namespace: gpu-operator
data:
  dev-pool: |-
    version: v1
    sharing:
      timeSlicing:
        resources:
        - name: nvidia.com/gpu
          replicas: 8
bash
kubectl apply -f time-slicing-config.yaml
helm upgrade gpu-operator harbor-chartmuseum/platform/gpu-operator \
  -n gpu-operator --reuse-values \
  --set devicePlugin.config.name=time-slicing-config
# 只对开发池节点生效:
kubectl label node gpu-dev-01 gpu-dev-02 nvidia.com/device-plugin.config=dev-pool
kubectl get node gpu-dev-01 -o json | jq '.status.allocatable."nvidia.com/gpu"'
# 期望:64(8 卡 × 8 份)

提醒用户:Time-Slicing 不隔离显存,8 个副本共享 96GB,适合能自控显存的开发场景。


第 9 章 多租户体系

9.1 组织模型

Rancher Project = 团队(team-algo-a / team-algo-b / inference-serving)
  └─ Namespace = 业务/环境(team-algo-a-train / team-algo-a-dev)
       ├─ ResourceQuota(GPU/CPU/内存/RDMA 配额)
       ├─ LimitRange(容器默认资源,防止裸 Pod 打满节点)
       ├─ NetworkPolicy(默认拒绝跨命名空间)
       └─ LocalQueue(Kueue 队列,见第 11 章)
Rancher 角色:Project Owner(管成员)/ Member(用资源)/ Read-only

9.2 命名空间模板

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: team-algo-a-train
  labels: {gpu-cluster.io/team: algo-a}
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: gpu-quota
  namespace: team-algo-a-train
spec:
  hard:
    requests.nvidia.com/gpu: "32"                # 训练池给该团队 32 整卡
    rdma/rdma_shared_device_a: "32"
    requests.cpu: "512"
    requests.memory: 2Ti
---
apiVersion: v1
kind: LimitRange
metadata:
  name: defaults
  namespace: team-algo-a-train
spec:
  limits:
  - default: {cpu: "4", memory: 16Gi}
    defaultRequest: {cpu: "2", memory: 8Gi}
    type: Container
---
# 推理命名空间(MIG 配额示例)
apiVersion: v1
kind: ResourceQuota
metadata:
  name: gpu-quota
  namespace: inference-serving
spec:
  hard:
    requests.nvidia.com/mig-1g.24gb: "64"
---
# 默认网络隔离
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: team-algo-a-train
spec:
  podSelector: {}
  policyTypes: [Ingress, Egress]

9.3 强制池隔离

  • 业务 YAML 全部由平台模板注入 tolerations + nodeSelector
  • 可选增强:装 OPA Gatekeeper,策略"带 GPU request 的 Pod 必须带池 nodeSelector,且与命名空间标签匹配",杜绝跨池调度。

第 10 章 计算网接入(Multus + RDMA)

10.1 安装 Multus

bash
kubectl apply -f multus-daemonset-thick.yml    # YAML 中镜像已改 Harbor
kubectl -n kube-system get pods -l app=multus

10.2 macvlan 辅网(推理池 vLLM 多机 TP 用)

yaml
apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: compute-net
  namespace: kube-system
spec:
  config: |
    {
      "cniVersion": "0.3.1",
      "type": "macvlan",
      "master": "ens2f0np0",
      "mode": "bridge",
      "mtu": 9000,
      "ipam": {
        "type": "whereabouts",
        "range": "192.168.100.100-192.168.100.250/24",
        "routes": [{"dst": "192.168.100.0/24"}]
      }
    }

Pod 引用:k8s.v1.cni.cncf.io/networks: kube-system/compute-net,NCCL 用 NCCL_SOCKET_IFNAME=net1

10.3 RDMA 共享设备插件(训练池 NCCL over RoCEv2)

bash
helm install network-operator harbor-chartmuseum/platform/network-operator \
  -n network-operator --create-namespace \
  --set rdmaSharedDevicePlugin.deploy=true \
  --set rdmaSharedDevicePlugin.image.repository=harbor.example.com/platform/k8s-rdma-shared-dev-plugin \
  --set rdmaSharedDevicePlugin.resources[0].name=rdma_shared_device_a \
  --set rdmaSharedDevicePlugin.resources[0].ifNames='[ens2f0np0]' \
  --set rdmaSharedDevicePlugin.resources[0].rdmaHcaMax=63
kubectl -n network-operator get pods
kubectl describe node gpu-train-01 | grep rdma        # allocatable 出现 rdma/rdma_shared_device_a: 63

训练 Pod 资源与 NCCL 环境变量(模板,两个章节都会引用):

yaml
resources:
  limits:
    nvidia.com/gpu: 8
    rdma/rdma_shared_device_a: 1
env:
- {name: NCCL_IB_HCA, value: "mlx5_2"}          # ibv_devices 输出中计算口对应设备名,按实际改
- {name: NCCL_IB_GID_INDEX, value: "3"}          # show_gids 确认 RoCEv2
- {name: NCCL_IB_DISABLE, value: "0"}
- {name: NCCL_SOCKET_IFNAME, value: "eth0"}
- {name: NCCL_DEBUG, value: "INFO"}

第 11 章 Kueue 队列调度

11.1 为什么需要

多机训练/批量推理任务需要 gang 调度(要么全部 Pod 一起起,要么排队等待),否则会出现"半个任务的 Pod 占着 GPU 等另一半"死锁。Kueue 是 K8s 官方批调度方案,与 Kubeflow Job 原生集成。

11.2 安装

bash
kubectl apply --server-side -f kueue-v0.12.x-manifests.yaml   # 镜像已改 Harbor
kubectl -n kueue-system get pods

11.3 资源模型(与节点池对齐)

yaml
# ResourceFlavor:绑定训练池节点
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: train-8gpu
spec:
  nodeLabels: {gpu-cluster.io/pool: train}
  nodeTaints:
  - {key: gpu-cluster.io/pool, value: train, effect: NoSchedule}
---
# ClusterQueue:训练池总量
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: train-cq
spec:
  resourceGroups:
  - coveredResources: ["nvidia.com/gpu", "rdma/rdma_shared_device_a", "cpu", "memory"]
    flavors:
    - name: train-8gpu
      resources:
      - {name: nvidia.com/gpu, nominalQuota: 160}
      - {name: rdma/rdma_shared_device_a, nominalQuota: 160}
      - {name: cpu, nominalQuota: 4000}
      - {name: memory, nominalQuota: 40Ti}
  preemption:
    withinClusterQueue: LowerPriority
---
# 团队队列
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  name: algo-a-queue
  namespace: team-algo-a-train
spec:
  clusterQueue: train-cq
---
# 推理池(MIG 实例配额,用于批量离线推理任务排队)
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: mig-24g
spec:
  nodeLabels: {gpu-cluster.io/pool: infer}
  nodeTaints:
  - {key: gpu-cluster.io/pool, value: infer, effect: NoSchedule}
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: infer-cq
spec:
  resourceGroups:
  - coveredResources: ["nvidia.com/mig-1g.24gb"]
    flavors:
    - name: mig-24g
      resources:
      - {name: nvidia.com/mig-1g.24gb, nominalQuota: 256}

业务侧只需给 Job 加标签 kueue.x-k8s.io/queue-name: algo-a-queue 即进入队列;超额任务自动排队(Inadmissible),配额释放后自动调度。

bash
kubectl get clusterqueue train-cq            # 看 Flavors/Usage/Admitted
kubectl -n team-algo-a-train get workloads   # 排队情况

第 12 章 分布式训练(Kubeflow Training Operator)

12.1 安装

bash
# 外网机器 clone 仓库导出 YAML,镜像地址替换为 Harbor 后拷入内网
kubectl apply -k training-operator-manifests/overlays/standalone/
kubectl -n kubeflow get pods

12.2 NCCL 验收测试(2 机 16 卡 AllReduce)——先跑通再上业务

yaml
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
  name: nccl-test
  namespace: team-algo-a-train
  labels:
    kueue.x-k8s.io/queue-name: algo-a-queue
spec:
  pytorchReplicaSpecs:
    Master:
      replicas: 1
      template: &tpl
        spec:
          tolerations:
          - {key: gpu-cluster.io/pool, value: train, effect: NoSchedule}
          nodeSelector: {gpu-cluster.io/pool: train}
          containers:
          - name: pytorch
            image: harbor.example.com/gpu-cluster/pytorch:25.05-py3
            command: ["bash", "-c"]
            args:
            - |
              /opt/nccl-tests/build/all_reduce_perf -b 1G -e 8G -f 2 -g 8 \
                || torchrun --nnodes=2 --nproc_per_node=8 \
                   --rdzv_backend=c10d --rdzv_endpoint=$MASTER_ADDR:29500 \
                   /workspace/nccl_allreduce.py
            resources:
              limits:
                nvidia.com/gpu: 8
                rdma/rdma_shared_device_a: 1
            env:
            - {name: NCCL_IB_HCA, value: "mlx5_2"}
            - {name: NCCL_IB_GID_INDEX, value: "3"}
            - {name: NCCL_IB_DISABLE, value: "0"}
            - {name: NCCL_SOCKET_IFNAME, value: "eth0"}
            - {name: NCCL_DEBUG, value: "INFO"}
    Worker:
      replicas: 1
      template: *tpl

验收标准:100G RoCE 单轨 AllReduce busbw ≥ 9 GB/s;单机 8 卡 busbw 视 PCIe 拓扑 ≥ 40 GB/s。不达标按 4.4/2.4.2 排查。

12.3 正式训练最佳实践

要点建议
并行策略8 卡机内 TP/PP(PCIe 互联),跨机 DP/EP;70B 级全参微调建议 ≥8 机
框架Megatron-LM / DeepSpeed(NGC pytorch 镜像自带),PyTorchJob 或 MPIJob
数据训练集放节点 /data(本地 NVMe RAID0),DataLoader num_workers≥8pin_memory=true
Checkpoint写本地 NVMe + 异步同步到 NFS/Ceph;按 Kueue 抢占策略保留最近 2 个
弹性torchrun --rdzv-backend=c10d + Kueue 失败自动重排队
NUMA镜像内用 nvidia-smi topo -m 确定 CPU affinity,必要时 numactl 绑核

第 13 章 vLLM 推理服务与生产力大模型部署推荐

13.1 推理服务总体设计

  • 编排:LeaderWorkerSet(LWS)—— 多机多卡推理的标准方案,Leader/Worker 一组原子扩缩容。
  • 引擎:vLLM(OpenAI 兼容 API),continuous batching + PagedAttention。
  • 暴露:NodePort(30000-32767 固定端口)+ 内网 HAProxy 固定入口(可选增强)。
  • 模型权重:节点本地 NVMe /data/models 预置(hostPath 只读挂载,启动最快),由 model-syncer DaemonSet 从 Harbor OCI / 内网对象存储分发。

13.1.1 安装 LWS

bash
kubectl apply --server-side -f lws-v0.6.x-manifests.yaml   # 镜像已改 Harbor
kubectl -n lws-system get pods

13.1.2 模型分发 DaemonSet(每台推理/开发节点预置)

bash
# 简易版:首次人工 scp/rsync 到每台 /data/models/<模型名>
# 规范版:model-syncer DaemonSet,容器内跑 rsync 从内网文件服务器拉取
mkdir -p /data/models/{Qwen3-32B,DeepSeek-R1-0528,Qwen2.5-Coder-32B-Instruct,bge-m3,bge-reranker-v2-m3}

13.2 生产力大模型部署推荐(23TB 显存怎么用)

原则:少数超大模型撑起"智能上限",一批中等模型扛起"日常生产力吞吐"

层级模型部署形态资源用途
旗舰DeepSeek-R1-0528(671B,FP8)8 机 64 卡 TP64(或 4 机 32 卡 + FP8)训练池闲时/推理池整卡节点,显存约 700GB复杂推理、代码架构、深度分析(智能上限)
主力Qwen3-235B-A22B(FP8)4 机 32 卡 TP32~250GB 显存日常高质量问答/写作
吞吐主力Qwen3-32B / Qwen2.5-32B-Instruct单卡整卡 ×N 副本(推理池整卡节点)每副本 1 卡日常问答、翻译、摘要,走量
代码Qwen2.5-Coder-32B-Instruct单卡 ×N 副本每副本 1 卡接 IDE(Continue/Cline),程序员工效核心
轻量Qwen3-14B / 8BMIG 1g.24gb 实例 ×N每副本 1 实例客服、分类、Embedding 前置处理
RAG 必备bge-m3(embedding)+ bge-reranker-v2-m3MIG 实例各 2~4 实例企业知识库检索
多模态(可选)Qwen2.5-VL-32B/72B整卡 TP图片/文档理解

推理池 8 台(64 卡)参考分配:2 台整卡节点跑旗舰(TP16 跨机)+ 4 台 MIG(128 实例)跑 14B/32B/embedding/reranker + 2 台整卡节点跑 32B/Coder 各 8 副本。训练池白天训练、夜间可承接旗舰模型批量推理(离线批处理任务走 Kueue infer-cq)。

13.3 多机整卡推理示例(旗舰模型 TP16,2 机 16 卡)

yaml
apiVersion: leaderworkerset.x-k8s.io/v1
kind: LeaderWorkerSet
metadata:
  name: vllm-flagship
  namespace: inference-serving
spec:
  replicas: 1
  leaderWorkerTemplate:
    size: 2                                  # 2 节点 × 8 卡 = TP16
    restartPolicy: RecreateGroupOnPodRestart
    leaderTemplate:
      metadata:
        annotations:
          k8s.v1.cni.cncf.io/networks: kube-system/compute-net
      spec:
        tolerations:
        - {key: gpu-cluster.io/pool, value: infer, effect: NoSchedule}
        nodeSelector: {gpu-cluster.io/pool: infer}
        hostPID: true                        # ray 需要
        containers:
        - name: vllm
          image: harbor.example.com/gpu-cluster/vllm-openai:v0.9.x
          command: ["bash", "-c"]
          args:
          - |
            ray start --head --port=6379 --num-gpus=8 && sleep 5 && \
            vllm serve /data/models/Qwen3-235B-A22B-FP8 \
              --tensor-parallel-size 16 \
              --served-model-name qwen3-235b --port 8000 \
              --max-model-len 32768 --gpu-memory-utilization 0.92 \
              --enable-expert-parallel
          env:
          - {name: NCCL_SOCKET_IFNAME, value: "net1"}
          - {name: HF_HUB_OFFLINE, value: "1"}
          ports: [{containerPort: 8000}, {containerPort: 6379}]
          resources:
            limits: {nvidia.com/gpu: 8}
          readinessProbe:
            httpGet: {path: /health, port: 8000}
            initialDelaySeconds: 300
            periodSeconds: 10
          volumeMounts: [{name: models, mountPath: /data/models, readOnly: true}]
        volumes:
        - name: models
          hostPath: {path: /data/models, type: Directory}
    workerTemplate:
      metadata:
        annotations:
          k8s.v1.cni.cncf.io/networks: kube-system/compute-net
      spec:
        tolerations:
        - {key: gpu-cluster.io/pool, value: infer, effect: NoSchedule}
        nodeSelector: {gpu-cluster.io/pool: infer}
        hostPID: true
        containers:
        - name: vllm-worker
          image: harbor.example.com/gpu-cluster/vllm-openai:v0.9.x
          command: ["bash", "-c"]
          args: ["ray start --address=$(LWS_LEADER_ADDRESS):6379 --num-gpus=8 --block"]
          env:
          - {name: NCCL_SOCKET_IFNAME, value: "net1"}
          resources:
            limits: {nvidia.com/gpu: 8}
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-flagship
  namespace: inference-serving
spec:
  type: NodePort
  selector:
    leaderworkerset.sigs.k8s.io/name: vllm-flagship
    role: leader
  ports:
  - {port: 8000, targetPort: 8000, nodePort: 30080}

验证:

bash
curl http://10.10.2.31:30080/v1/models
curl http://10.10.2.31:30080/v1/chat/completions -H 'Content-Type: application/json' -d '{
  "model": "qwen3-235b",
  "messages": [{"role":"user","content":"用一句话解释 RoCEv2"}]
}'

13.4 MIG 实例推理示例(32B 模型,单实例一个副本)

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-qwen3-32b
  namespace: inference-serving
spec:
  replicas: 4                                # 4 个 MIG 实例副本
  selector:
    matchLabels: {app: vllm-qwen3-32b}
  template:
    metadata:
      labels: {app: vllm-qwen3-32b}
    spec:
      tolerations:
      - {key: gpu-cluster.io/pool, value: infer, effect: NoSchedule}
      nodeSelector: {gpu-cluster.io/pool: infer}
      containers:
      - name: vllm
        image: harbor.example.com/gpu-cluster/vllm-openai:v0.9.x
        args:
        - serve
        - /data/models/Qwen3-32B
        - --port=8000
        - --gpu-memory-utilization=0.9
        - --max-model-len=16384
        - --served-model-name=qwen3-32b
        env:
        - {name: HF_HUB_OFFLINE, value: "1"}
        ports: [{containerPort: 8000}]
        resources:
          limits:
            nvidia.com/mig-1g.24gb: 1
        readinessProbe:
          httpGet: {path: /health, port: 8000}
          initialDelaySeconds: 120
        volumeMounts: [{name: models, mountPath: /data/models, readOnly: true}]
      volumes:
      - name: models
        hostPath: {path: /data/models, type: Directory}
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-qwen3-32b
  namespace: inference-serving
spec:
  type: NodePort
  selector: {app: vllm-qwen3-32b}
  ports:
  - {port: 8000, targetPort: 8000, nodePort: 30081}

13.5 统一入口与应用接入(把算力变成生产力)

┌─────────────┐   ┌──────────────────────┐
│  HAProxy VM │──▶│ NodePort 30080 旗舰模型 │  ← OpenAI 兼容 API
│ 10.10.0.20  │──▶│ NodePort 30081 32B模型 │
│ (固定入口)   │──▶│ NodePort 30082 Coder   │
└──────┬──────┘   └──────────────────────┘

  ┌────┴─────┬───────────┬───────────┬────────────┐
  │ OpenWebUI│ Continue/ │ Dify/RAG  │ 内部系统 API │
  │ (对话门户)│ Cline(IDE)│ (知识库)   │ 集成        │
  └──────────┴───────────┴───────────┴────────────┘

HAProxy 配置示例:

# /etc/haproxy/haproxy.cfg 片段
frontend ai_gateway
    bind *:80
    use_backend flagship if { path_beg /v1 } { hdr(X-Model) qwen3-235b }
    default_backend qwen32b

backend flagship
    balance roundrobin
    server infer1 10.10.2.31:30080 check
    server infer2 10.10.2.32:30080 check

backend qwen32b
    balance roundrobin
    server infer3 10.10.2.33:30081 check
    server infer4 10.10.2.34:30081 check

生产力落地组合推荐

  1. Open WebUI(部署在无 GPU 的管理 VM):统一对话门户,接所有 vLLM 端点,支持多用户/RBAC/知识库。
  2. Continue.dev / Cline 插件:开发团队 IDE 直连 qwen2.5-coder-32b 端点,代码补全/重构/审查。
  3. Dify + bge-m3 + reranker:企业知识库 RAG,文档问答。
  4. 批量离线推理:文档翻译/数据清洗类任务用 Kueue infer-cq 排队跑训练池闲时资源。

第 14 章 监控告警体系

bash
helm install monitoring harbor-chartmuseum/platform/kube-prometheus-stack \
  -n monitoring --create-namespace \
  --set prometheus.prometheusSpec.retention=30d \
  --set grafana.adminPassword='xxx'

# GPU Operator 的 dcgm-exporter 自带 ServiceMonitor,自动被 Prometheus 采集
# Grafana 导入 Dashboard:12239(NVIDIA DCGM Exporter)
# NodePort 暴露:
kubectl patch svc monitoring-grafana -n monitoring \
  -p '{"spec":{"type":"NodePort","ports":[{"port":80,"targetPort":3000,"nodePort":30300}]}}'

告警规则建议(Alertmanager 推送到企业微信/钉钉/邮件)

指标阈值含义
DCGM_FI_DEV_GPU_TEMP> 85℃GPU 过热(查机房散热/风扇)
DCGM_FI_DEV_XID_ERRORS> 0GPU 硬件错误(立即处理,Xid 79/48/63 等)
DCGM_FI_DEV_FB_USED / FB_FREE> 95% 持续显存水位(MIG 多租户重点)
DCGM_FI_DEV_GPU_UTIL == 0 且 Pod 在跑持续 10min任务挂死/数据加载瓶颈
节点 node_up / kubeletdown节点故障
Kueue pending_workloads> N队列积压

另外建议装 Loki + Promtail 采集 Pod 日志,NCCL 排障时 NCCL_DEBUG=INFO NCCL_DEBUG_SUBSYS=INIT,NET 的日志非常关键。


第 15 章 整体验收 Checklist

基础设施

  • [ ] 交换机:管理网 MLAG 双活正常,拔一根光纤业务无感知;计算网 PFC/ECN 已配
  • [ ] 每节点 cat /proc/net/bonding/bond0:双口 up、802.3ad、总速率 200G
  • [ ] 跨节点 ib_write_bw ≥ 95 Gb/s;MTU 端到端 9000
  • [ ] IPMI 全部可达,可远程开关机

集群

  • [ ] 33 节点 Ready(3 CP + 30 Worker),Rancher UI 已纳管
  • [ ] kubectl get nodes -L gpu-cluster.io/pool:20 train / 8 infer / 2 dev,taint 正确
  • [ ] 资源呈现:训练池 nvidia.com/gpu: 8/台;推理池 nvidia.com/mig-1g.24gb: 32/台;开发池 nvidia.com/gpu: 64/台
  • [ ] 任意 1 台 CP VM 关机,API VIP 仍可用;etcd 快照任务在跑

GPU 能力

  • [ ] 训练池整卡 Pod nvidia-smi -L 正常
  • [ ] MIG 实例 Pod 只见自己 24GB 实例,互不影响
  • [ ] 开发池单卡可调度 8 个 Time-Slicing Pod

性能

  • [ ] NCCL 双机 AllReduce busbw ≥ 9 GB/s(100G RoCE)
  • [ ] vLLM 旗舰模型 TP16 启动成功,首 token 延迟与吞吐符合预期

平台能力

  • [ ] Kueue:超额任务 Inadmissible 排队,资源释放后自动调度
  • [ ] 多租户:超配额被拒、跨池调度被拒、跨命名空间网络不通
  • [ ] 推理 API:NodePort 各端口返回正常,HAProxy 入口统一可用
  • [ ] Grafana 12239 面板 240 卡数据齐全;Xid 告警测试触发
  • [ ] 全部 Pod 镜像来自 harbor.example.com(无任何外网依赖)
  • [ ] 节点重启后:bond 恢复、GPU Operator 自愈、MIG 配置保持、LWS 服务自动拉起

第 16 章 常见问题速查

问题排查路径
Pod Pending,GPU allocatable 为 0device-plugin 是否运行 → 池 label/taint 与 Pod toleration → ResourceQuota → Kueue 配额
Kueue 任务一直 Inadmissiblekubectl describe workload;ResourceFlavor 的 nodeLabels/nodeTaints 与节点一致性;nominalQuota 余量
NCCL 跨机卡死/极慢NCCL_SOCKET_IFNAMEshow_gids GID index → 交换机 PFC/ECN → MTU 端到端 → ib_write_bw 单机对测 → 固件
ib_write_bw 不达标MTU → 线缆/光模块(换 DAC 测试)→ 交换机端口 counters(PFC pause/丢包)→ CX-7 固件
MIG 切分失败/自动回退卡上有残留进程(先 drain)→ 驱动 ≥570 → nvidia-smi -mig 1 → mig-manager 日志
Time-Slicing Pod 被 OOMKill时间片不隔离显存:副本显存之和 > 96GB;减少 replicas 或改 MIG
vLLM 启动失败模型路径/权限 → HF_HUB_OFFLINE=1 → MIG 24GB 放不下(32B FP16 需 ~70GB,用整卡或 AWQ/FP8)→ 日志看 KV cache 计算
vLLM 多机 ray 连不上compute-net IP 是否通(跨节点 ping net1 IP)→ hostPID → 6379 端口
Harbor 拉镜像失败registries.yaml auth/endpoint → 机器人 token 权限 → http/https 模式一致 → harbor 容器状态
Rancher 纳管 agent 失败systemDefaultRegistry 是否指向 Harbor → agent 镜像是否存在 → cattle-system 日志
RKE2 agent 加入失败token 一致性 → 9345 连通(VIP 状态)→ 节点时间同步(NTP)
GPU 掉卡(nvidia-smi 少卡)dmesg 看 PCIe/Xid 错误 → 供电/温度 → 重插/换槽位 → IPMI 看硬件日志
训练 loss 异常波动先查 Xid 错误和 GPU 温度(坏卡 Silent Error)→ 再看数据/代码

附录 A 镜像同步清单(images.txt 核心版)

# 平台
rancher/rancher:v2.12.x
rancher/fleet-agent:v0.13.x
rancher/shell:v0.5.x
nvcr.io/nvidia/gpu-operator:v25.3.x
nvcr.io/nvidia/driver:570.133.20-ubuntu24.04
nvcr.io/nvidia/k8s-device-plugin:v0.17.x
nvcr.io/nvidia/container-toolkit:1.17.x
nvcr.io/nvidia/dcgm-exporter:4.x.x-ubuntu22.04
nvcr.io/nvidia/cloud-native/k8s-mig-manager:v0.10.x
nvcr.io/nvidia/cloud-native/k8s-rdma-shared-dev-plugin:v1.5.x
ghcr.io/k8snetworkplumbingwg/multus-cni:v4.2.x
ghcr.io/k8snetworkplumbingwg/whereabouts:v0.8.x
registry.k8s.io/leaderworkerset/lws:v0.6.x
registry.k8s.io/kueue/kueue:v0.12.x
kubeflow/training-operator:v1-xxx
# 监控(kube-prometheus-stack 全套)
quay.io/prometheus/prometheus:v3.x
quay.io/prometheus-operator/prometheus-operator:v0.8x
docker.io/grafana/grafana:11.x
quay.io/prometheus/node-exporter:v1.9.x
registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.15.x
# 业务
nvcr.io/nvidia/pytorch:25.05-py3
docker.io/vllm/vllm-openai:v0.9.x
nvcr.io/nvidia/cuda:12.8.0-base-ubuntu24.04
docker.io/library/ubuntu:24.04
docker.io/library/busybox:latest
# 应用层(生产力)
ghcr.io/open-webui/open-webui:main
docker.io/ollama/ollama:latest          # 可选

完整清单以实际 helm chart values 里的 image 字段为准,部署前用 helm template | grep image: 逐一核对。

附录 B 调池与运维速记

bash
# 节点从推理池迁回训练池
kubectl drain gpu-infer-08 --ignore-daemonsets --delete-emptydir-data
kubectl label node gpu-infer-08 nvidia.com/mig.config=all-disabled --overwrite
kubectl label node gpu-infer-08 gpu-cluster.io/pool=train --overwrite
kubectl taint node gpu-infer-08 gpu-cluster.io/pool=infer:NoSchedule-
kubectl taint node gpu-infer-08 gpu-cluster.io/pool=train:NoSchedule
kubectl uncordon gpu-infer-08
# 记得同步调整 Kueue train-cq / infer-cq 的 nominalQuota

# 驱动升级(滚动,灰度先行)
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
helm upgrade gpu-operator ... --set driver.version=575.x.x
# 观察一台没问题后逐台进行

# 查看 GPU 分配全景
kubectl get nodes -o custom-columns=NAME:.metadata.name,POOL:.metadata.labels."gpu-cluster\.io/pool",GPU:.status.allocatable."nvidia\.com/gpu",MIG:.status.allocatable."nvidia\.com/mig-1g\.24gb"

附录 C 术语速查

术语说明
RDMA远程直接内存访问,网卡直读写对端内存,绕过 CPU/内核
RoCEv2跑在 UDP/IP 以太网上的 RDMA,CX-7 支持
PFC / ECN以太网无损机制:按优先级暂停 + 拥塞标记,RoCE 必备
MIGNVIDIA 多实例 GPU,单卡硬件级切分为多个隔离实例
Time-SlicingGPU 时间片共享,无显存隔离
LWSLeaderWorkerSet,多机推理编排 CRD
KueueK8s 原生批任务队列/配额调度器
Gang 调度一组 Pod 要么全部调度要么都不调度
NCCLNVIDIA 多卡/多机集合通信库(AllReduce 等)
TP / PP / DP / EP张量并行 / 流水线并行 / 数据并行 / 专家并行