3. 容器运行时配置:Docker安装、NVIDIA Container Toolkit配置、GPU资源暴露验证

好,咱们进入第三章。这一章说白了,就是给K8s集群装上“眼睛”和“手脚”。

你想让vLLM跑在GPU上,首先得让容器能看到GPU。这步搞不定,后面全是白搭。我见过太多新手,镜像拉下来、Pod跑起来,结果一看日志——CUDA不可用。嗯,问题就出在容器运行时这层。

3.1 Docker安装:最基础的容器引擎

虽然K8s现在支持containerd直接作为运行时,但Docker依然是最广泛使用的工具。我个人习惯在节点上保留Docker,方便调试和排查问题。

核心要点:Docker不是K8s的必需品,但它是运维人员的瑞士军刀。

3.1.1 安装步骤(Ubuntu 22.04为例)

# 1. 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc

# 2. 安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release

# 3. 添加Docker官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# 4. 设置稳定版仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 5. 安装Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 6. 启动并设置开机自启
sudo systemctl start docker
sudo systemctl enable docker

# 7. 验证安装
sudo docker run hello-world

我的经验:安装完成后,记得把当前用户加入docker组,不然每次都要sudo。命令是 sudo usermod -aG docker $USER,然后退出重新登录。

3.1.2 配置Docker守护进程

对于GPU推理场景,Docker的默认配置可能不够。我建议调整以下参数:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  },
  "storage-driver": "overlay2",
  "default-runtime": "nvidia",
  "runtimes": {
    "nvidia": {
      "path": "nvidia-container-runtime",
      "runtimeArgs": []
    }
  }
}
EOF

sudo systemctl restart docker

这里有个坑——default-runtime设为nvidia后,所有容器默认都会尝试挂载GPU。如果你有些容器不需要GPU,记得在docker run时指定--runtime=runc。我曾经因为这个把CI构建节点搞崩过,所有构建容器都在抢GPU显存……

3.2 NVIDIA Container Toolkit:让容器看见GPU

Docker本身不认识GPU。你需要装一个“翻译官”——NVIDIA Container Toolkit。它的作用就是把宿主机的GPU设备映射到容器里。

一句话总结:没有这个工具,容器里的nvidia-smi就是“command not found”。

3.2.1 安装NVIDIA驱动

先确认宿主机有NVIDIA驱动:

nvidia-smi

如果没装,用这个命令装(以Ubuntu 22.04为例):

sudo apt-get install -y nvidia-driver-535
sudo reboot

注意:驱动版本别太老。vLLM要求CUDA 11.8以上,对应驱动版本至少520+。我建议直接上535或545,省心。

3.2.2 安装Container Toolkit

# 1. 配置仓库
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

# 2. 安装
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit

# 3. 配置运行时
sudo nvidia-ctk runtime configure --runtime=docker

# 4. 重启Docker
sudo systemctl restart docker

这里有个细节——nvidia-ctk runtime configure这个命令会自动修改Docker的daemon.json,添加nvidia运行时。如果你手动改过daemon.json,可能会冲突。我建议先跑这个命令,再手动调整其他参数。

3.3 GPU资源暴露验证:确认容器能用显卡

装完别急着部署vLLM。先验证一下,不然到时候排错很痛苦。

3.3.1 基础验证:容器内跑nvidia-smi

docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu22.04 nvidia-smi

如果输出和宿主机一致,说明GPU已经成功映射到容器里了。

我的习惯:我会用--gpus '"device=0,1"'指定具体GPU,而不是--gpus all。这样能避免不小心把生产卡和测试卡混用。

3.3.2 深入验证:检查CUDA可用性

光看nvidia-smi还不够。我遇到过驱动正常、nvidia-smi有输出,但PyTorch就是检测不到CUDA的情况。问题出在CUDA运行时库的版本不匹配。

docker run --rm --gpus all nvidia/cuda:12.2.0-runtime-ubuntu22.04 python3 -c "import torch; print(torch.cuda.is_available()); print(torch.cuda.device_count())"

如果返回TrueN(N为GPU数量),说明CUDA环境没问题。

3.3.3 K8s节点验证:让K8s识别GPU

在K8s节点上,还需要安装NVIDIA Device Plugin,这样K8s才能把GPU作为可调度资源。

# 使用DaemonSet部署
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.0/nvidia-device-plugin.yml

# 验证节点是否识别GPU
kubectl get nodes -o json | jq '.items[].status.capacity'

你应该能看到类似这样的输出:

{
  "cpu": "8",
  "memory": "32123456Ki",
  "nvidia.com/gpu": "2",
  "pods": "110"
}

看到nvidia.com/gpu了吗?这就是K8s知道节点有GPU的证据。

避坑指南:我曾经在混合GPU型号的集群上踩过坑——A100和V100混用,结果vLLM调度到了V100上,推理速度慢得离谱。后来我加了NodeSelector和资源限制才解决。建议你在部署前确认所有GPU型号一致,或者用节点标签做隔离。

3.4 本章知识体系

下面这张图帮你理清容器运行时配置的完整链路:

容器运行时配置链路 宿主机层 NVIDIA GPU驱动 + CUDA Toolkit + nvidia-smi验证 容器运行时层 Docker Engine + NVIDIA Container Toolkit + nvidia-container-runtime K8s集成层 NVIDIA Device Plugin + kubelet GPU资源注册 + nvidia.com/gpu vLLM推理服务 nvidia-smi docker run --gpus kubectl get nodes

这张图展示了从硬件到应用的完整链路。每一层都有对应的验证方法,确保问题能快速定位。

3.5 常见问题与排错

现象 可能原因 解决方法
docker run --gpus all 报错 NVIDIA Container Toolkit未安装或配置错误 重新执行 sudo nvidia-ctk runtime configure --runtime=docker
容器内nvidia-smi无输出 驱动版本不匹配或容器镜像缺少CUDA库 使用官方nvidia/cuda镜像,检查驱动版本
K8s节点不显示nvidia.com/gpu Device Plugin未部署或kubelet未重启 检查DaemonSet状态,重启kubelet
Pod调度失败,提示GPU资源不足 节点GPU已被其他Pod占用,或资源预留不足 使用 kubectl describe node 查看GPU分配情况

排错口诀:先宿主机、再容器、最后K8s。一层一层验证,别跳步。我见过有人花了两天排查K8s调度问题,结果发现是宿主机驱动没装……

好了,容器运行时配置就讲到这里。记住,这一步是地基,地基不稳,楼盖得再高也得塌。下一章咱们开始真正部署vLLM,到时候这些配置都会用上。


公众号:蓝海资料掘金营,微信deep3321