Qwen3.6-27B-AWQ 16 路统一 Docker vLLM 集群部署报告
4 × RTX 4090 (8卡) 服务器 | Docker + Nginx 负载均衡 | 32 GPU 并发推理
一、项目概述
本报告记录了将 4 台配备 8× NVIDIA GeForce RTX 4090 GPU 的服务器,通过 Docker 容器化技术部署 vLLM 推理服务,并通过 Nginx 构建 16 路负载均衡集群的完整过程。
集群目标:
- 对外提供统一的 OpenAI-compatible API 服务入口
- 支持 Qwen3.6-27B-AWQ 模型的高并发推理(32 张 GPU 并行)
- 实现自动故障恢复与开机自启动
- 单节点故障不影响整体服务可用性
二、硬件环境
服务器 | 内网 IP | GPU 型号 | GPU 数量 | 部署方式 |
GPU-00 | 10.255.xxx.00 | RTX 4090 (24GB) | 8 | Docker + systemd |
GPU-01 | 10.255.xxx.01 | RTX 4090 (24GB) | 8 | Docker + systemd |
GPU-02 | 10.255.xxx.02 | RTX 4090 (24GB) | 8 | Docker + systemd |
GPU-03 | 10.255.xxx.03 | RTX 4090 (24GB) | 8 | Docker + systemd |
总计:32 张 RTX 4090 = 768 GB GPU 显存
三、软件环境
操作系统 | Ubuntu 24.04 LTS (Noble) |
Docker | Docker 24.x + docker-compose 1.29.2 |
NVIDIA 驱动 | 580.159.03 |
CUDA 版本 | 13.0 / CUDA Toolkit 12.8 |
Python | 3.10.12 (deadsnakes PPA) |
vLLM | 0.20.2 (自定义构建) |
PyTorch | 2.11.0+cu128 |
Transformers | 5.8.0 |
四、部署架构
4.1 逻辑架构
互联网用户
↓
XXX.XXX.XXX.XXX:0101 (公网映射)
↓
Nginx (00 服务器)
├─ 00:8000 ── vLLM Docker (GPU 0,1)
├─ 00:8001 ── vLLM Docker (GPU 2,3)
├─ 00:8002 ── vLLM Docker (GPU 4,5)
├─ 00:8003 ── vLLM Docker (GPU 6,7)
├─ 0101:8000 ── vLLM Docker (GPU 0,1)
├─ 0101:8001 ── vLLM Docker (GPU 2,3)
├─ 0101:8002 ── vLLM Docker (GPU 4,5)
├─ 0101:8003 ── vLLM Docker (GPU 6,7)
├─ 02:8000 ── vLLM Docker (GPU 0,1)
├─ 02:8001 ── vLLM Docker (GPU 2,3)
├─ 02:8002 ── vLLM Docker (GPU 4,5)
├─ 02:8003 ── vLLM Docker (GPU 6,7)
├─ 03:8000 ── vLLM Docker (GPU 0,1)
├─ 03:8001 ── vLLM Docker (GPU 2,3)
├─ 03:8002 ── vLLM Docker (GPU 4,5)
└─ 03:8003 ── vLLM Docker (GPU 6,7)
4.2 负载均衡策略
Nginx 采用least_conn算法,将请求分发到当前连接数最少的后端实例。所有后端配置统一:
- Tensor Parallel = 2(每实例占用 2 张 GPU)
- max-model-len = 262,100(256K 上下文)
- kv-cache-dtype = fp8(节省显存)
- max-num-seqs = 8(每实例最大 8 条序列)
五、部署步骤详解
5.1 前置准备(每台服务器)
1. 安装 Docker 与 NVIDIA Container Toolkit
sudo apt-get update
sudo apt-get install -y docker.io docker-compose
# NVIDIA Container Toolkit
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
2. 创建 Docker 基础镜像
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y python3.10 python3.10-venv python3.10-dev python3-pip curl wget git && rm -rf /var/lib/apt/lists/*
RUN ln -sf /usr/bin/python3.10 /usr/bin/python3
RUN ln -sf /usr/bin/python3.10 /usr/bin/python
3. 复制 Python 虚拟环境
从 00 服务器 /opt/venv/vllm 复制到目标服务器,修复 python 软链接:
sudo rm -f /opt/venv/vllm/bin/python3 /opt/venv/vllm/bin/python
sudo ln -s /usr/bin/python3.10 /opt/venv/vllm/bin/python3
sudo ln -s /usr/bin/python3.10 /opt/venv/vllm/bin/python
5.2 Docker Compose 配置
每台服务器部署 4 个 vLLM 容器实例,每个实例使用 2 张 GPU:
services:
vllm-8000:
image: ubuntu-python310:22.04
runtime: nvidia
restart: always
ports: ["10.255.XXX.XX:8000:8000"]
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ['0', '1']
capabilities: [gpu]
environment:
- LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
- PATH=/opt/venv/vllm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- NCCL_CUMEM_ENABLE=0
- NCCL_P2P_DISABLE=1
volumes:
- /data/models:/data/models:ro
- /dev/shm:/dev/shm
- /opt/venv/vllm:/opt/venv/vllm:ro
- /usr/local/cuda:/usr/local/cuda:ro
shm_size: '16gb'
command: >
/opt/venv/vllm/bin/python3 -m vllm.entrypoints.cli.main serve
/data/models/Qwen3.6-27B-AWQ
--served-model-name Qwen3.6-27B-AWQ --trust-remote-code
--tensor-parallel-size 2 --gpu-memory-utilization 0.8
--max-model-len 262100 --kv-cache-dtype fp8
--disable-custom-all-reduce --enforce-eager
--distributed-executor-backend mp
--reasoning-parser qwen3 --enable-auto-tool-choice
--tool-call-parser qwen3_coder --block-size 16
--enable-prefix-caching --max-num-seqs 8
--port 8000 --host 0.0.0.0
--api-key sk-XXX-XXX-XXX-XXX
5.3 启动顺序(关键)
由于 NCCL 在容器内并发初始化会竞争 cuMem 资源,必须按顺序启动,每个实例间隔 60 秒:
# 必须先启动 8000,等待就绪后再启动 8001
docker-compose up -d vllm-8000
sleep 60 # 等待模型加载完成
docker-compose up -d vllm-8001
sleep 60
docker-compose up -d vllm-8002
sleep 60
docker-compose up -d vllm-8003
sleep 60
5.4 systemd 开机启动
编写 /usr/local/bin/vllm-cluster-start.sh 脚本,由 systemd 调用:
#!/bin/bash
COMPOSE_DIR="/home/hmtsgpu/vllm-deploy"
cd "$COMPOSE_DIR" || exit 1
rm -f /dev/shm/nccl-* 2>/dev/null || true
for svc in vllm-8000 vllm-8001 vllm-8002 vllm-8003; do
docker compose up -d "$svc"
port="${svc##*-}"
for i in {1..90}; do
sleep 2
status=$(curl -s -o /dev/null -w "%{http_code}" --max-time 2 "http://10.255.XXX.XX:${port}/health" 2>/dev/null || echo "000")
[ "$status" = "200" ] && break
done
[ "$svc" != "vllm-8003" ] && sleep 5
done
六、Nginx 负载均衡配置
在 00 服务器上部署 Nginx,作为统一 API 入口:
upstream all_vllm {
least_conn;
server 10.255.XXX.00:8000;
server 10.255.XXX.00:8001;
server 10.255.XXX.00:8002;
server 10.255.XXX.00:8003;
server 10.255.XXX.0101:8000;
server 10.255.XXX.0101:8001;
server 10.255.XXX.0101:8002;
server 10.255.XXX.0101:8003;
server 10.255.XXX.02:8000;
server 10.255.XXX.02:8001;
server 10.255.XXX.02:8002;
server 10.255.XXX.02:8003;
server 10.255.XXX.03:8000;
server 10.255.XXX.03:8001;
server 10.255.XXX.03:8002;
server 10.255.XXX.03:8003;
}
七、关键问题与解决方案
问题现象 | 根因分析 | 解决方案 |
8002/8003 NCCL cuMemCreate Segfault | GPU 4,5 NUMA 节点未注册,NCCL 无法分配 pinned memory | 重启服务器清理 cuMem 状态;或 BIOS 修复 NUMA 设置 |
Docker 无外网拉取镜像 | 服务器无外网访问 | 从 0101 导出 docker save 镜像,scp 传输后 docker load 导入 |
venv 复制后 Python 失效 | 软链接指向不存在的python3.10 | 重新 ln -s /usr/bin/python3.10 修复 |
docker-compose Permission denied | 用户不在 docker 组 | sudo usermod -aG docker $USER; newgrp docker |
Docker 启动失败: mkdir /var/lib/docker | /var/lib/docker 软链接指向不存在的 /data/docker | mkdir -p /data/docker 创建目标目录 |
Nginx 公网 000 / 本地 200 | 公网 IP 映射在外部防火墙 | 联系网管确认 NAT 映射规则 |
八、验证结果
8.1 16 路后端健康检查
服务器 | 8000 | 8001 | 8002 | 8003 |
00 | 200 | 200 | 200 | 200 |
01 | 200 | 200 | 200 | 200 |
02 | 200 | 200 | 200 | 200 |
03 | 200 | 200 | 200 | 200 |
8.2 公网 API 测试
测试命令:
curl -s http://XXX.XXX.XXX.XXX:0101/v1/chat/completions -H "Content-Type: application/json" -H "Authorization: Bearer sk-XXX-XXX-XXX-XXX" -d '{"model":"Qwen3.6-27B-AWQ","messages":[{"role":"user","content":"你好"}],"max_tokens":32}'
测试结果:✅ 返回完整 JSON,HTTP 200,模型正常响应
九、运维管理手册
9.1 常用命令
# 查看所有后端状态
for ip in 10.255.XXX.00 10.255.XXX.0101 10.255.XXX.02 10.255.XXX.03; do
echo "=== $ip ==="
for port in 8000 8001 8002 8003; do
curl -s -o /dev/null -w "$ip:$port → %{http_code}
" --max-time 2 http://$ip:$port/health
done
done
# 查看 Nginx 访问日志
sudo tail -f /var/log/nginx/vllm_access.log
# 重启整个集群
sudo systemctl restart vllm-cluster.service
# 查看单容器日志
docker compose -f ~/vllm-deploy/docker-compose.yml logs -f vllm-8002
9.2 自动恢复机制
三层防护:
- Docker 级:restart: always — 容器崩溃/退出后自动重启
- systemd 级:vllm-cluster.service — 系统开机按顺序启动全部实例
- Nginx 级:least_conn — 自动跳过不可用的后端,请求分发到健康节点
9.3 监控指标
建议监控项:
- 各后端 health 状态(每 5 分钟探测)
- Nginx access_log 中的请求延迟(rt, uct, uht, urt)
- GPU 显存使用率(nvidia-smi)
- Docker 容器重启次数(docker inspect .RestartCount)
十、总结
本次部署成功构建了 4 台服务器、16 路 vLLM 实例、32 张 RTX 4090 GPU 的推理集群。通过 Docker 容器化实现了环境统一和快速恢复,通过 Nginx 负载均衡实现了高可用和高并发。所有实例参数一致,运维管理标准化,为后续扩展和维护奠定了坚实基础。