2、环境准备:搭建实验环境,包括Linux服务器、Docker、Kubernetes集群(minikube或k3s)、GPU驱动与CUDA环境验证

vLLM 作为高性能的大模型推理引擎,其生产级部署离不开容器化与编排调度。本章将带领你从零搭建一套可复现的实验环境,覆盖 Linux 服务器基础配置、Docker 运行时安装、轻量级 Kubernetes 集群(minikube 或 k3s)的构建,以及 GPU 驱动与 CUDA 环境的验证。这套环境不仅是后续章节操作的基础,更是理解 vLLM 在 GPU 资源调度、显存管理、自动扩缩容等机制的前提。我们将以“最小化依赖、最大化可控性”为原则,确保每一步都可验证、可回滚。

vLLM 容器化部署实验环境全景 Linux 服务器 Ubuntu 22.04 / CentOS 9 内核 ≥ 5.4,关闭 Swap GPU 驱动 + CUDA NVIDIA Driver ≥ 535 CUDA 12.1 / 12.4 Docker Engine 版本 ≥ 24.0 NVIDIA Container Toolkit Kubernetes 集群(minikube / k3s) Control Plane + Worker Node(GPU 节点) 支持 Device Plugin 与 Metrics Server vLLM 推理服务 Deployment + Service + HPA 验证清单 ✓ nvidia-smi 正常 ✓ docker run --gpus ✓ kubectl get nodes ✓ kubectl get pods ✓ vLLM 加载模型 ✓ 推理延迟测试

上图展示了本章实验环境的整体架构与验证路径。从底层 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 永久禁用。

操作流程:基础环境检查与配置

  1. 检查内核与操作系统版本:执行 uname -r 和 cat /etc/os-release,确保内核 ≥ 5.4(推荐 6.x),操作系统为 Ubuntu 22.04+ 或 CentOS 9+。
  2. 关闭防火墙或放行必要端口:Kubernetes 需要 6443、10250 等端口,Docker 需要 2375(可选)。在实验环境可直接 systemctl stop firewalld 或 ufw disable。
  3. 配置主机名与 hosts 解析:设置静态主机名,并在 /etc/hosts 中添加集群节点 IP 映射,避免 DNS 解析问题。
  4. 加载内核模块:Kubernetes 依赖 overlay 和 br_netfilter 模块,执行 modprobe overlay 和 modprobe br_netfilter,并写入 /etc/modules-load.d/k8s.conf。
  5. 调整 sysctl 参数:创建 /etc/sysctl.d/k8s.conf,设置 net.bridge.bridge-nf-call-iptables = 1 和 net.ipv4.ip_forward = 1,然后执行 sysctl --system 生效。
实战场景:假设你使用一台 8 核 32GB 内存的云服务器,并挂载了一块 NVIDIA A10 GPU。在安装完操作系统后,通过 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 通信,而无需在镜像中打包驱动。

操作流程:安装与配置

  1. 安装 Docker Engine:使用官方脚本 curl -fsSL https://get.docker.com | sh,或通过 apt/yum 源安装指定版本。
  2. 配置 Docker 用户组:将当前用户加入 docker 组,避免每次使用 sudo。
  3. 安装 NVIDIA Container Toolkit:添加 NVIDIA 官方 apt 源,执行 apt-get install -y nvidia-container-toolkit。
  4. 配置运行时:编辑 /etc/docker/daemon.json,添加 "runtimes": {"nvidia": {"path": "nvidia-container-runtime", "runtimeArgs": []}},并设置 "default-runtime": "nvidia"(可选)。
  5. 重启 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 是最常用的两种轻量级方案。它们各有优劣,选择取决于你的资源限制和功能需求。

对比维度minikubek3s
架构单节点(可扩展多节点)单节点或集群,支持 ARM
资源占用约 2GB 内存约 512MB 内存
安装复杂度需额外安装 kubectl 和 driver单二进制文件,安装简单
GPU 支持需配置 nvidia-docker 和 device plugin内置 NVIDIA device plugin 支持
适合场景本地开发、功能验证边缘节点、资源受限环境

操作流程:使用 k3s 搭建单节点集群

  1. 安装 k3s:执行 curl -sfL https://get.k3s.io | sh -,默认会启用 containerd 作为运行时。
  2. 配置 kubectl:k3s 自带 kubectl,可通过 export KUBECONFIG=/etc/rancher/k3s/k3s.yaml 使用。
  3. 验证节点状态:kubectl get nodes 应显示 Ready 状态。
  4. 安装 NVIDIA Device Plugin:k3s 默认不安装,需手动部署 DaemonSet。执行 kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/main/nvidia-device-plugin.yml。
  5. 验证 GPU 可调度:kubectl describe node <node-name> | grep -A 5 "nvidia.com/gpu",应显示可分配数量。
经验提醒:如果使用 minikube,需要先启动 Docker driver,然后执行 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 的完整链路

  1. 宿主机验证:执行 nvidia-smi,确认 GPU 型号、驱动版本和显存容量。
  2. Docker 验证:运行 docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi,确认容器内可见 GPU。
  3. Kubernetes 验证:创建一个测试 Pod,使用 nvidia/cuda 镜像,并声明 resources.limits.nvidia.com/gpu: 1。进入 Pod 执行 nvidia-smi。
  4. 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 架构预编译。

风险提示:在验证 CUDA 环境时,不要只关注 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 镜像能加载模型并完成一次推理请求,延迟在合理范围内。