2、基础设施准备:GPU节点要求与Kubernetes集群搭建
好,咱们直接进入正题。这一章要解决的核心问题就一个:怎么让Kubernetes认识你的GPU。说白了,vLLM推理环境跑在K8s上,GPU就是它的心脏。心脏都接不上,后面全是白搭。
我个人习惯把基础设施准备拆成三个步骤:GPU节点环境 → K8s集群搭建 → NVIDIA Device Plugin安装。每一步都有坑,我踩过不少,咱们一个个说。
核心逻辑图:下面这张图展示了从硬件到K8s识别GPU的完整链路。
2.1 GPU节点环境:驱动、CUDA、容器运行时
先说说GPU节点本身。你想想看,一台裸机服务器,插着A100或者V100,系统装好了,然后呢?
第一步:装NVIDIA驱动。 这个没啥好说的,去NVIDIA官网下载对应型号的驱动。我个人建议用nvidia-smi命令验证一下。跑一下这个命令:
nvidia-smi
如果能看到GPU列表、驱动版本、显存信息,说明驱动装好了。嗯,这里要注意:驱动版本最好 ≥ 525。为什么?因为vLLM依赖的CUDA版本对驱动有要求。我遇到过有人用470的老驱动,结果CUDA 12死活装不上,折腾了半天。
第二步:安装CUDA Toolkit。 其实对于容器化部署来说,宿主机上不一定要装完整的CUDA Toolkit。但我的习惯是装一个,方便调试。你可以用nvcc --version检查版本。
这里有个小技巧:驱动和CUDA的版本要匹配。比如驱动525对应CUDA 12.0,驱动535对应CUDA 12.2。不匹配的话,nvidia-smi能认卡,但nvcc会报错。
我的经验: 如果你用的是Ubuntu 22.04,直接用apt安装nvidia-driver-535最省事。别自己从官网下.run文件,容易把系统搞乱。我曾经手贱装了个.run,结果和系统自带的nouveau驱动冲突,黑屏了...嗯,从那以后我学乖了。
第三步:安装容器运行时。 这一步很多人会忽略。Docker默认用的是runc,它不认识NVIDIA GPU。你需要装nvidia-container-toolkit。
安装命令很简单:
# 添加NVIDIA容器工具包仓库
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
# 配置Docker运行时
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
装完之后,验证一下:
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi
如果能看到GPU信息,说明容器运行时配置成功了。这一步我建议你反复确认,因为后面K8s调用GPU也是走这个运行时。
2.2 Kubernetes集群搭建:kubeadm vs minikube
集群搭建这块,我分两种情况说。
情况一:生产环境或有多台GPU服务器 → 用kubeadm
kubeadm是官方推荐的集群搭建工具。步骤稍微多一点,但可控性强。我简单列一下核心步骤:
- 所有节点安装容器运行时(上面已经搞定了)
- 安装kubeadm、kubelet、kubectl
- 初始化控制平面:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 - 安装网络插件:推荐Flannel或Calico
- 加入工作节点:用
kubeadm join命令
这里有个坑:kubelet和容器运行时的cgroup驱动必须一致。我遇到过有人用systemd驱动,但Docker用的是cgroupfs,结果节点一直NotReady。解决办法是在kubelet配置里指定--cgroup-driver=systemd。
注意: 如果你用的是containerd而不是Docker,记得在containerd配置里启用nvidia容器运行时。具体做法是修改/etc/containerd/config.toml,在plugins."io.containerd.grpc.v1.cri".containerd.runtimes下添加nvidia配置。这个坑我踩过,不配的话Pod永远拿不到GPU。
情况二:单机测试或学习环境 → 用minikube
minikube就简单多了。一条命令启动一个单节点集群:
minikube start --driver=docker --gpus all
注意那个--gpus all参数,它会让minikube自动配置NVIDIA GPU支持。我个人觉得minikube适合快速验证,但生产环境还是老老实实用kubeadm。
2.3 NVIDIA Device Plugin安装
好,现在集群搭好了,节点也装了驱动和运行时。但K8s还不知道节点上有GPU。你运行kubectl describe node,看不到nvidia.com/gpu这个资源。
这时候就需要NVIDIA Device Plugin了。它本质上是一个DaemonSet,运行在每个GPU节点上,负责向Kubelet汇报GPU资源。
安装方式很简单:
# 创建DaemonSet
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml
# 验证是否安装成功
kubectl get pods -n kube-system | grep nvidia-device-plugin
如果Pod状态是Running,再检查一下节点资源:
kubectl describe node <your-gpu-node> | grep -A5 "Capacity"
你应该能看到类似这样的输出:
nvidia.com/gpu: 8
nvidia.com/gpu: 8
看到这个,说明K8s已经认识你的GPU了。后面部署vLLM的时候,只需要在Pod的resources里声明nvidia.com/gpu: 1,K8s就会自动调度到有GPU的节点上。
一个小细节: Device Plugin默认会暴露所有GPU。如果你只想暴露部分GPU(比如8卡机器只暴露4卡),可以设置环境变量NVIDIA_VISIBLE_DEVICES。我有个项目就是这么干的,把GPU分给不同的租户用。
2.4 验证整个链路
最后,咱们跑一个测试Pod,验证整个链路是否通畅:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
containers:
- name: cuda-test
image: nvidia/cuda:12.2.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
EOF
查看Pod日志:
kubectl logs gpu-test
如果能看到GPU信息,恭喜你,基础设施准备完毕!
说实话,这一套流程我前前后后搭过不下20次。每次换新集群、换新驱动版本,总会冒出一些新问题。但核心逻辑不变:驱动 → 运行时 → K8s → Device Plugin,一层层验证,别跳步。
公众号:蓝海资料掘金营,微信deep3321