2、环境准备:硬件要求与软件依赖

说实话,做NVSHMEM和Kubernetes的融合部署,环境准备这一步最容易被轻视。我见过太多人一上来就急着写代码,结果卡在驱动不兼容、网络不通这种基础问题上。嗯,咱们先把地基打牢。

2.1 硬件要求:GPU节点与高速网络

先聊聊硬件。NVSHMEM说白了就是让GPU之间能直接通信,不走CPU绕路。所以硬件选型很关键。

GPU节点

我个人习惯用NVIDIA A100或H100系列。为什么?因为它们支持NVLink和NVSwitch,GPU间带宽能到600GB/s以上。你想想看,如果用的是低端卡,NVSHMEM的优势根本发挥不出来。

核心要求:

  • GPU必须支持CUDA Compute Capability 7.0+(V100、A100、H100都行)
  • 节点内至少2块GPU(最好4块或8块,方便测试多卡通信)
  • 显存建议32GB以上(NVSHMEM的共享数据结构挺吃内存)

我在项目中遇到过用T4卡跑NVSHMEM的情况,结果性能惨不忍睹。说白了,T4没有NVLink,跨卡通信走PCIe,延迟直接翻10倍。所以别在这上面省钱。

InfiniBand / RoCE 网络

跨节点通信靠的是高速网络。这里有两个选择:

网络类型 带宽 延迟 我的建议
InfiniBand HDR100 100Gbps ~1μs 生产环境首选
InfiniBand HDR200 200Gbps ~0.7μs 大规模集群推荐
RoCE v2 100/200Gbps ~2-3μs 预算有限时可用

我个人更倾向InfiniBand。RoCE虽然便宜,但配置起来坑多。我曾经在RoCE上折腾了整整两天,就为了调通PFC流控。InfiniBand开箱即用,省心很多。

注意:不管选哪种网络,网卡必须支持GPUDirect RDMA。检查一下你的网卡型号,Mellanox ConnectX-5/6/7系列都支持,但有些国产网卡不一定行。

2.2 软件依赖:从驱动到集群

软件栈的版本匹配是个技术活。我整理了一个经过验证的组合,你照着来就行。

NVIDIA驱动与CUDA

驱动版本别追新,稳定最重要。我目前在用的组合:

# 驱动版本:535.154.05(长期支持版)
# CUDA版本:12.2(与NVSHMEM 2.11兼容)
# 安装命令
sudo apt install nvidia-driver-535
sudo apt install cuda-12-2

小技巧:装完驱动后,用 nvidia-smi topo -m 检查GPU拓扑。如果看到NVLink连接正常,说明硬件没问题。

Docker与容器运行时

Docker版本建议24.0以上。关键是nvidia-container-toolkit必须装,否则容器里用不了GPU。

# 安装nvidia-container-toolkit
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker

嗯,这里要注意:装完一定要重启Docker守护进程。我刚开始做的时候忘了这步,折腾了半天才发现容器里识别不到GPU。

Kubernetes集群

K8s版本建议1.28以上。需要安装以下组件:

  • kubelet / kubeadm / kubectl:集群管理三件套
  • NVIDIA GPU Operator:自动管理GPU驱动和容器运行时
  • RDMA Shared Device Plugin:让Pod能申请RDMA资源
  • NVPeerMemory:优化GPU间通信(可选但推荐)

我的经验:GPU Operator真是个好东西。以前手动装驱动、配runtime,每台节点都得折腾一遍。用了Operator之后,声明式配置,省了至少80%的运维时间。

2.3 操作系统配置

操作系统层面有几个关键参数要调。我直接给出一份经过验证的配置清单。

内核参数

# /etc/sysctl.d/99-nvshmem.conf
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
vm.max_map_count = 1048576
kernel.shmmax = 68719476736
kernel.shmall = 16777216

这些参数直接影响NVSHMEM的共享内存分配和网络性能。我曾经因为vm.max_map_count设得太小,导致大模型训练时内存映射失败,查了半天才找到原因。

HugePages配置

NVSHMEM强烈建议用2MB大页。配置方法:

# 分配4096个2MB大页(共8GB)
echo 4096 > /proc/sys/vm/nr_hugepages
# 持久化配置
echo "vm.nr_hugepages=4096" >> /etc/sysctl.conf

避坑指南:我曾经在BIOS里没开启IOMMU,结果大页分配成功了,但GPU DMA访问大页内存时直接报错。记得检查BIOS设置:VT-d(Intel)或IOMMU(AMD)必须开启。

NUMA亲和性

多路服务器要注意NUMA节点。我习惯用numactl工具检查:

# 查看NUMA拓扑
numactl --hardware
# 将GPU和CPU绑定到同一NUMA节点
numactl --cpunodebind=0 --membind=0 your_application

说白了,GPU和CPU如果在不同NUMA节点,跨节点访问内存会慢很多。我测试过,性能差距能有30%。

2.4 验证环境

所有配置完成后,跑个简单的验证脚本:

# 检查GPU可用性
nvidia-smi

# 检查NVLink状态
nvidia-smi topo -m

# 检查RDMA设备
ibstat

# 测试GPU间通信(用NVSHMEM自带的示例)
cd $NVSHMEM_HOME/examples
mpirun -np 4 ./simple_pingpong

如果所有检查都通过,恭喜你,环境准备好了。接下来就可以开始真正的NVSHMEM编程了。

最后提醒:把每一步的配置都记录下来。我习惯用Ansible写个playbook,下次部署新集群时直接跑一遍,省时省力。

NVSHMEM + Kubernetes 环境准备知识体系 硬件层 GPU节点(A100/H100) InfiniBand / RoCE 网络 NVLink / NVSwitch 系统软件层 NVIDIA驱动(535 LTS) CUDA 12.2 HugePages + NUMA配置 容器与编排层 Docker 24.0+ nvidia-container-toolkit Kubernetes 1.28+ Kubernetes 扩展组件 GPU Operator RDMA Device Plugin NVPeerMemory 从硬件到软件,层层依赖

这张图展示了整个环境准备的层次结构。从底层的GPU硬件和高速网络,到系统驱动和CUDA,再到容器运行时和K8s集群,最后是各种扩展组件。每一层都依赖下一层,缺一不可。

专注资料整理