2、环境准备:搭建实验环境,包括Linux服务器、Docker、Kubernetes集群(minikube或k3s)、GPU驱动与CUDA环境验证
vLLM 作为高性能的大模型推理引擎,其生产级部署离不开容器化与编排调度。本章将带领你从零搭建一套可复现的实验环境,覆盖 Linux 服务器基础配置、Docker 运行时安装、轻量级 Kubernetes 集群(minikube 或 k3s)的构建,以及 GPU 驱动与 CUDA 环境的验证。这套环境不仅是后续章节操作的基础,更是理解 vLLM 在 GPU 资源调度、显存管理、自动扩缩容等机制的前提。我们将以“最小化依赖、最大化可控性”为原则,确保每一步都可验证、可回滚。
上图展示了本章实验环境的整体架构与验证路径。从底层 Linux 服务器开始,依次叠加 GPU 驱动与 CUDA、Docker 容器运行时,最终构建 Kubernetes 集群并部署 vLLM 服务。右侧的验证清单是每个环节是否就绪的关键判据。下面我们将按照“底层到上层”的顺序,逐步完成每个组件的安装与验证。
2.1 Linux 服务器基础配置与检查
实验环境的稳定性首先取决于操作系统层面的合理配置。无论是物理机、云主机还是虚拟机,都需要确保内核版本、CPU 架构、内存和磁盘满足 vLLM 与 Kubernetes 的基本要求。vLLM 在推理时对 CPU 指令集(如 AVX2)和内存带宽敏感,因此建议使用现代 x86_64 或 ARM64 架构的服务器。
核心原理:为什么需要关闭 Swap?
Kubernetes 的 kubelet 默认要求节点关闭 Swap,因为 Swap 会导致 Pod 的内存使用量无法精确统计,进而影响调度决策和 OOM(Out Of Memory)Killer 的行为。对于 vLLM 这类显存密集型应用,内存交换会显著增加推理延迟,甚至导致 GPU 与 CPU 之间的数据同步超时。因此,在安装 Kubernetes 之前,必须通过 swapoff -a 命令临时关闭,并编辑 /etc/fstab 永久禁用。
操作流程:基础环境检查与配置
- 检查内核与操作系统版本:执行
uname -r和cat /etc/os-release,确保内核 ≥ 5.4(推荐 6.x),操作系统为 Ubuntu 22.04+ 或 CentOS 9+。 - 关闭防火墙或放行必要端口:Kubernetes 需要 6443、10250 等端口,Docker 需要 2375(可选)。在实验环境可直接
systemctl stop firewalld或ufw disable。 - 配置主机名与 hosts 解析:设置静态主机名,并在
/etc/hosts中添加集群节点 IP 映射,避免 DNS 解析问题。 - 加载内核模块:Kubernetes 依赖
overlay和br_netfilter模块,执行modprobe overlay和modprobe br_netfilter,并写入/etc/modules-load.d/k8s.conf。 - 调整 sysctl 参数:创建
/etc/sysctl.d/k8s.conf,设置net.bridge.bridge-nf-call-iptables = 1和net.ipv4.ip_forward = 1,然后执行sysctl --system生效。
lscpu 确认 CPU 支持 AVX2 指令集,通过 free -h 确认内存充足。此时若直接安装 Docker 而不关闭 Swap,后续创建 Kubernetes 集群时 kubelet 会报错 Failed to start ContainerManager,错误日志中会明确提示 “Running with swap on is not supported”。因此,务必在初始化集群前完成 Swap 的永久关闭。
常见误区与复盘
- 误区一:忽略 cgroup 驱动一致性。Docker 默认使用
cgroupfs,而 kubelet 推荐使用systemd。若两者不一致,会导致节点状态异常。解决方法是统一配置 Docker 的exec-opts为native.cgroupdriver=systemd。 - 误区二:磁盘空间预留不足。vLLM 模型文件(如 7B 参数模型约 15GB)和容器镜像(约 5GB)需要充足空间。建议根分区预留 100GB 以上,并单独挂载数据盘用于存储模型。
- 误区三:忘记设置 IP 转发。Pod 之间的通信依赖 iptables 转发,若
net.ipv4.ip_forward未开启,会导致 Service 无法访问。
2.2 Docker 与 NVIDIA Container Toolkit 安装
Docker 是容器化部署的基础,而 NVIDIA Container Toolkit 则让容器能够访问宿主机 GPU。vLLM 的官方镜像默认基于 CUDA 12.x 构建,因此宿主机驱动版本必须兼容。本节将介绍 Docker 的安装、GPU 运行时配置以及验证方法。
核心原理:Docker 如何调用 GPU?
Docker 本身并不直接管理 GPU,而是通过 NVIDIA Container Toolkit 提供的 nvidia-container-runtime 钩子,在容器启动时将宿主机的 GPU 设备节点(/dev/nvidia*)和驱动库(libcuda.so)注入到容器内。这样容器内的 CUDA 运行时就能直接与 GPU 通信,而无需在镜像中打包驱动。
操作流程:安装与配置
- 安装 Docker Engine:使用官方脚本
curl -fsSL https://get.docker.com | sh,或通过 apt/yum 源安装指定版本。 - 配置 Docker 用户组:将当前用户加入
docker组,避免每次使用sudo。 - 安装 NVIDIA Container Toolkit:添加 NVIDIA 官方 apt 源,执行
apt-get install -y nvidia-container-toolkit。 - 配置运行时:编辑
/etc/docker/daemon.json,添加"runtimes": {"nvidia": {"path": "nvidia-container-runtime", "runtimeArgs": []}},并设置"default-runtime": "nvidia"(可选)。 - 重启 Docker:
systemctl restart docker,然后执行docker info | grep -i runtime确认 nvidia 运行时已注册。
验证 GPU 可用性
# 查看宿主机 GPU 状态
nvidia-smi
# 运行一个 CUDA 测试容器
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi
如果第二条命令能正常输出 GPU 信息,说明 Docker 已成功透传 GPU。若报错 could not select device driver "" with capabilities: [[gpu]],则说明 Toolkit 未正确安装或 daemon.json 配置有误。
default-runtime: nvidia,这会导致所有容器都尝试使用 GPU,造成资源浪费。建议仅在需要 GPU 的容器或 Pod 中显式指定 runtime: nvidia。
案例拆解:驱动版本与 CUDA 版本不匹配
某实验环境安装了 NVIDIA Driver 525 和 CUDA 12.0,但 vLLM 镜像要求 CUDA 12.4。运行容器时出现 libcudart.so.12: cannot open shared object file 错误。分析后发现,宿主机驱动 525 最高支持 CUDA 12.0,而镜像内的 CUDA 12.4 运行时需要驱动 ≥ 535。解决方法是升级驱动至 535 或更高版本,并重新安装 Toolkit。此案例说明,驱动版本是硬性约束,必须满足镜像内 CUDA 的最低要求。
2.3 Kubernetes 集群搭建:minikube 与 k3s 对比及选型
Kubernetes 集群是 vLLM 服务编排的载体。对于实验环境,minikube 和 k3s 是最常用的两种轻量级方案。它们各有优劣,选择取决于你的资源限制和功能需求。
| 对比维度 | minikube | k3s |
|---|---|---|
| 架构 | 单节点(可扩展多节点) | 单节点或集群,支持 ARM |
| 资源占用 | 约 2GB 内存 | 约 512MB 内存 |
| 安装复杂度 | 需额外安装 kubectl 和 driver | 单二进制文件,安装简单 |
| GPU 支持 | 需配置 nvidia-docker 和 device plugin | 内置 NVIDIA device plugin 支持 |
| 适合场景 | 本地开发、功能验证 | 边缘节点、资源受限环境 |
操作流程:使用 k3s 搭建单节点集群
- 安装 k3s:执行
curl -sfL https://get.k3s.io | sh -,默认会启用 containerd 作为运行时。 - 配置 kubectl:k3s 自带 kubectl,可通过
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml使用。 - 验证节点状态:
kubectl get nodes应显示 Ready 状态。 - 安装 NVIDIA Device Plugin:k3s 默认不安装,需手动部署 DaemonSet。执行
kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/main/nvidia-device-plugin.yml。 - 验证 GPU 可调度:
kubectl describe node <node-name> | grep -A 5 "nvidia.com/gpu",应显示可分配数量。
minikube start --driver=docker --container-runtime=containerd,并在启动参数中添加 --gpus=all 以启用 GPU 支持。但 minikube 对 GPU 的透传支持不如 k3s 稳定,因此本课程后续章节统一使用 k3s 作为演示环境。
常见误区与复盘
- 误区一:k3s 使用 containerd 而非 Docker。如果你习惯使用
docker ps查看容器,会发现 k3s 的 Pod 容器不可见。这是正常现象,应使用crictl或kubectl管理。 - 误区二:忘记部署 Device Plugin。即使宿主机有 GPU,若未部署 Device Plugin,Kubernetes 无法感知 GPU 资源,Pod 调度时会报
0/1 nodes are available: 1 Insufficient nvidia.com/gpu。 - 误区三:镜像拉取超时。k3s 默认镜像仓库为 Docker Hub,国内网络可能超时。建议配置镜像加速器或使用
registry.cn-hangzhou.aliyuncs.com等替代源。
2.4 GPU 驱动与 CUDA 环境验证
在完成集群搭建后,最后一步是验证 GPU 驱动和 CUDA 环境是否在整个容器化链路中正常工作。这不仅是环境就绪的标志,也是后续 vLLM 推理性能调优的基线。
核心原理:CUDA 版本兼容性矩阵
CUDA 有两大版本概念:驱动版本(Driver Version)和运行时版本(Runtime Version)。驱动版本决定了支持的最高 CUDA 版本,而运行时版本是编译和运行程序时使用的。vLLM 的 PyTorch 依赖通常要求 CUDA ≥ 11.8,推荐 12.1 或 12.4。你可以通过 nvidia-smi 查看驱动版本,通过 nvcc --version 查看运行时版本。
验证流程:从宿主机到 Pod 的完整链路
- 宿主机验证:执行
nvidia-smi,确认 GPU 型号、驱动版本和显存容量。 - Docker 验证:运行
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi,确认容器内可见 GPU。 - Kubernetes 验证:创建一个测试 Pod,使用
nvidia/cuda镜像,并声明resources.limits.nvidia.com/gpu: 1。进入 Pod 执行nvidia-smi。 - vLLM 验证:拉取 vLLM 镜像,运行一个最小推理任务(如
facebook/opt-125m模型),观察日志中的 GPU 利用率。
# 创建 GPU 测试 Pod
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: gpu-test
spec:
containers:
- name: cuda-test
image: nvidia/cuda:12.4.0-base-ubuntu22.04
command: ["nvidia-smi"]
resources:
limits:
nvidia.com/gpu: 1
EOF
# 查看日志
kubectl logs gpu-test
案例拆解:vLLM 首次推理失败排查
某次实验中,vLLM 容器启动后报错 CUDA error: no kernel image is available for execution on the device。通过 nvidia-smi 发现 GPU 为 A100(计算能力 8.0),而镜像内的 PyTorch 是为 CUDA 11.8 编译的,不支持 8.0 架构。解决方法是更换为支持 Ampere 架构的 PyTorch 镜像(如 pytorch/pytorch:2.1.0-cuda12.1-cudnn8-devel),或使用 vLLM 官方提供的 vllm/vllm-openai:latest 镜像,该镜像已针对主流 GPU 架构预编译。
nvidia-smi 的输出。务必在容器内运行一个实际的 CUDA 程序(如 deviceQuery 或 bandwidthTest),以确认计算能力与驱动完全匹配。否则,vLLM 可能在推理中途崩溃,且错误信息不直观。
总结复盘:环境就绪的最终检查清单
- ✅
nvidia-smi显示驱动版本 ≥ 535,GPU 状态为 P0。 - ✅
docker run --gpus all能正常执行 CUDA 程序。 - ✅
kubectl get nodes显示 Ready,且kubectl describe node中nvidia.com/gpu数量正确。 - ✅ 测试 Pod 能成功申请 GPU 资源并运行。
- ✅ vLLM 镜像能加载模型并完成一次推理请求,延迟在合理范围内。