> 适用范围:海光 DCU(本文实测 K100_AI 八卡、Ubuntu 22.04)服务器上首次部署容器化推理环境。不覆盖 Kubernetes 编排与多机分布式。
NVIDIA 机器上容器化推理有 nvidia-container-toolkit 全自动注入,DCU 上没有同等自动化的工具链,设备直通、驱动挂载、镜像来源都要手动处理。本笔记把这条路径整理成五个步骤,每步附配置依据;文末给出可直接勾选的验收清单。以下配置在笔者的机器上实际跑通,含两个付出过返工代价的细节,一并标注。
## 1. 安装与 daemon.json
```bash
apt install docker.io containerd # 实测 server 29.1.3
```
安装没有特殊之处,`/etc/docker/daemon.json` 有两项建议装完立即配置:
```json
{"data-root": "/data1/docker",
"log-driver": "json-file",
"log-opts": {"max-size": "200m", "max-file": "5"}}
```
| 配置 | 依据 | 不配的后果 |
|---|---|---|
| `data-root` 迁数据盘 | 深度学习镜像动辄几十 GB,模型卷也在大盘 | 镜像层挤占系统盘;已产生的层事后要手动迁移 |
| 日志限额 200m×5 | 推理服务长期运行日志持续增长(vLLM 每请求均有输出) | json-file 无上限增长,磁盘静默占满且难定位来源 |
## 2. 镜像来源:官方仓库而非 Docker Hub
DCU 深度学习镜像要求 torch/vLLM 为 HIP 适配版,需从官方镜像仓库获取:
```
image.sourcefind.cn:5000/dcu/admin/base/pytorch:2.3.0-ubuntu22.04-dtk24.04.3-py3.10
```
tag 解读:PyTorch 2.3.0 + Ubuntu 22.04 + **DTK 24.04.3** + Python 3.10,内置 vLLM 0.6.2。选镜像时注意 tag 是一整套栈组合,其中 DTK 版本与主机驱动的兼容性是第一判据——笔者实测 DTK 24.04.3 容器在 DTK 26.04 主机上运行正常(前向兼容)。
## 3. docker run 参数逐项说明
```bash
sudo docker run -dit \
--network=host \ # 主机网络,免端口映射
--name=deepseek_test \
--privileged \ # 调试期宽松项,生产应收紧(见下)
--device=/dev/kfd \ # 计算驱动接口
--device=/dev/dri \ # 渲染设备组
--ipc=host \
--shm-size=256G \ # 上限值,不占实存
--group-add video \ # /dev/dri 属组
--cap-add=SYS_PTRACE \ # 排障用
--security-opt seccomp=unconfined \ # 排障用
-u root \
--ulimit stack=-1:-1 \
--ulimit memlock=-1:-1 \
-v /opt/hyhal:/opt/hyhal:ro \ # ★ 用户态驱动,必挂
-v /data1/.../模型目录:/models/...:ro \
-v /data1/.../logs:/logs \
image.sourcefind.cn:5000/dcu/... \
bash # 常驻 shell,启停交给外部脚本
```
三处关键:
**kfd + dri + video 组(③④⑦)。** 这三项替代 NVIDIA 的 toolkit 自动注入。`/dev/kfd` 与 `/dev/dri` 缺任一项,容器内 `torch.cuda.is_available()` 返回 False 或设备数为 0;`/dev/dri` 属组为 video,容器进程默认不在组内,漏掉 `--group-add` 会出现「设备在但用不了」的状态。
**hyhal 挂载(⑫)。** `/opt/hyhal` 是主机上的用户态驱动,镜像内不含此组件,必须从主机只读挂载。缺失时的报错位置远离真实原因(常见为运行库找不到或设备初始化失败),是本清单中优先级最高的检查项。`:ro` 固定保留。
**特权参数取舍(②⑧⑨)。** 笔者记录的是调试期实测跑通的宽松组合;生产部署应收敛到最小集——实测必需项仅 `--device` 两节点 + `--group-add video` + hyhal 挂载,其余逐项裁剪验证。
## 4. 容器内工作流
服务启停由外部脚本控制,容器只承载环境。脚本注入与启动的标准流程:
```bash
# 注入脚本(勿将启动命令以嵌套 heredoc 直接塞进 docker run,
# 引号转义层级过深曾造成展开结果异常,返工一次)
sudo docker cp scripts/start_vllm.sh deepseek_test:/tmp/start_vllm.sh
sudo docker exec -u root deepseek_test chmod +x /tmp/start_vllm.sh
# 后台启动:清旧日志 → nohup 脱离 → 重定向
sudo docker exec -u root deepseek_test bash -c '
: > /logs/vllm_serve.log
( nohup /tmp/start_vllm.sh /logs/vllm_serve.log 2>&1 & )
sleep 3
ps -ef | grep "vllm serve" | grep -v grep
'
```
两点备忘:
- `docker exec 容器 ls /path/*.safetensors` 的通配符不展开(exec 无 shell),需写 `docker exec 容器 sh -c "ls ..."`;
- 清理进程用 `pkill -9 -f "vllm serve"`——默认信号对 vLLM 进程树不生效,worker 不退、端口残留。先杀服务再 `docker stop`,顺序颠倒会留下占用设备的残留进程。
## 5. 验收记录
容器启动后、加载模型前依次执行:
```bash
which vllm # CLI 存在
python -c "import torch; print(torch.cuda.is_available(), torch.cuda.device_count())"
# 期望 True 8 —— kfd/dri 直通成功判据
ls /opt/hyhal/ # 驱动组件就位
```
日志中如下告警为已知良性项,不需处理:`get hyhal driver version error, ... skip init hydmi`——容器读不到主机 `/sys/module/hydcu/version`,跳过的仅为监控初始化,推理功能不受影响。
## 收尾:容器定位
这套配置跑通后容器的角色即可明确:**验证期载体**。官方镜像开箱即跑、损坏重建零成本、整个栈组合由厂商背书;进入多实例长期生产后笔者将集群迁至裸机 conda 环境(省运行时开销、host 工具直接可用)。两者构成流水线的两段而非二选一。
## 附表:本次改造约束汇总
| 类别 | 条目 |
|---|---|
| 硬件/系统 | 海光 K100_AI × 8 / Ubuntu 22.04 |
| Docker | server 29.1.3;data-root=/data1/docker;日志 200m×5 |
| 镜像 | sourcefind.cn:5000 pytorch:2.3.0-ubuntu22.04-dtk24.04.3-py3.10(vLLM 0.6.2) |
| 必须项 | /dev/kfd + /dev/dri 直通、video 组、/opt/hyhal 只读挂载 |
| 已知良性告警 | get hyhal driver version error, skip init hydmi |