本文最后更新于28 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
一、Docker 基础与 AI 容器化价值
1. 核心概念
Docker 是开源容器化平台,将应用及其依赖打包成标准化容器单元。
- 虚拟机 vs 容器:
- 虚拟机:完整操作系统 + 应用 + 依赖,重量级(GB 级),启动慢
- 容器:仅应用 + 依赖库,轻量级(MB 级),共享宿主机内核,启动快
2. 容器化四大核心价值
| 价值 | 说明 |
|---|---|
| 环境一致性 | 一次构建,处处运行;开发 / 测试 / 生产环境完全一致,解决 “我这能跑你那不能跑” 问题 |
| 资源隔离性 | 不同项目 / 模型环境隔离,互不干扰;可同时运行不同 CUDA、Python 版本的服务 |
| 可移植性 | 服务器、云主机、Kubernetes 集群均可无缝迁移 |
| 交付效率高 | 拉取镜像即可运行,部署、启动、回滚速度快,支持 CI/CD 流水线 |
3. AI 服务容器化的必要性
AI 模型部署依赖链复杂:操作系统 → NVIDIA 驱动 → CUDA/cuDNN → Python → PyTorch/Transformers → 数十个依赖库,各组件版本严格耦合。
- 手动配置效率低、一致性差,多项目共存极易依赖冲突
- 容器化将整套环境打包成镜像,彻底解决环境依赖与复现性问题,是生产级模型服务、K8s 部署的标准基础设施
二、Ubuntu 22.04 Docker 安装(⭐)
安装步骤
- 更新系统包索引
apt update
- 安装基础依赖
apt install apt-transport-https ca-certificates curl software-properties-common gnupg lsb-release
- 添加 Docker 官方 GPG 密钥(国内阿里云镜像源)
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
- 添加 Docker APT 软件源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
- 更新索引并安装 Docker
apt update
apt install docker-ce docker-ce-cli containerd.io
- 启动服务并设置开机自启
systemctl start docker
systemctl enable docker
- 配置镜像加速 编辑
/etc/docker/daemon.json,添加国内镜像源:
{
"registry-mirrors": [
"https://docker.1ms.run/",
"https://docker.m.daocloud.io",
"https://docker.imgdb.de",
"https://docker-0.unsee.tech",
"https://docker.hlmirror.com",
"https://docker.xuanyuan.me",
"https://cjie.eu.org",
"https://rvjdf6u3.mirror.aliyuncs.com"
]
}
重启服务生效:
systemctl daemon-reload
systemctl restart docker
- 验证安装
docker info | grep -A 5 Registry # 查看镜像源是否生效
docker --version
三、NVIDIA Container Toolkit(⭐)
1. 核心作用
默认 Docker 容器无法访问宿主机 GPU 硬件。NVIDIA Container Toolkit 是容器引擎与宿主机 NVIDIA 驱动之间的桥梁,运行时动态将 GPU 设备节点、驱动库文件注入容器,让容器内应用可以调用 GPU。
2. 工作原理
- 驱动留在宿主机:不把驱动打包进镜像,驱动必须安装在宿主机 OS 上
- 运行时动态注入:容器启动时通过 OCI Hook 触发,自动识别宿主机的
/dev/nvidia*设备节点、驱动库文件,挂载到容器隔离环境中 - 类比:容器是密封太空舱,Toolkit 是智能对接管道,按需对接 GPU “资源接口”,既保证隔离又能使用硬件
3. 安装配置步骤
- 添加 NVIDIA 软件源与 GPG 密钥
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
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/$distribution/libnvidia-container.list" | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
- 安装工具包
apt update
apt install -y nvidia-container-toolkit
- 配置 Docker 运行时
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker # 关键步骤,配置后必须重启Docker
4. 验证与 GPU 参数
基础验证:容器内执行 nvidia-smi
docker run --rm --name test --gpus all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi
输出与宿主机一致则说明 GPU 透传成功。
--gpus参数用法
--gpus all:映射所有 GPU--gpus 2:映射任意 2 块 GPU--gpus '"device=0,1"':指定使用 0 号和 1 号 GPU--gpus '"device=GPU-UUID"':通过 UUID 精确指定
5. 自定义 GPU 镜像构建示例
构建 PyTorch GPU 应用镜像,推荐直接使用官方 CUDA/PyTorch 基础镜像,避免重复配置环境:
# 基础镜像:官方预装CUDA+cuDNN+PyTorch
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]
构建运行:
docker build -t my-pytorch-app .
docker run --rm --gpus all my-pytorch-app
四、Docker 部署 Ollama(⭐)
1. 私有仓库配置(内网环境)
- 在
daemon.json中添加私有仓库地址,允许 HTTP 访问:
{
"insecure-registries": ["192.168.100.149"]
}
- 重启 Docker 并登录仓库:
systemctl daemon-reload && systemctl restart docker
docker login 192.168.100.149 -u 0331admin -p Admin@123
2. 拉取镜像并启动容器
# 拉取镜像
docker pull 192.168.100.149/gpuimages/ollama:latest
# 启动容器
docker run -d \
--name=ollama \
--gpus=all \
-v ollama:/root/.ollama \
-p 11434:11434 \
192.168.100.149/gpuimages/ollama:latest
3. 关键参数说明
| 参数 | 作用 |
|---|---|
--gpus=all | 授予容器访问所有 GPU 权限 |
-v ollama:/root/.ollama | 挂载数据卷,持久化模型文件,容器重建不丢失 |
-p 11434:11434 | 端口映射,宿主机 11434 端口映射容器内服务端口 |
4. 容器内模型管理
# 进入容器
docker exec -it ollama bash
# 拉取模型
ollama pull qwen:7b
# 查看模型列表
ollama list
- 服务地址:
http://宿主机IP:11434,API 与原生部署完全一致
五、Docker 部署 vLLM
1. 镜像拉取
docker pull 192.168.100.149/gpuimages/vllm:latest
2. 启动容器
docker run -d \
--name vllm-qwen \
--gpus all \
--network host \
--ipc=host \
--shm-size 16g \
-e VLLM_USE_MODELSCOPE=True \
-e MODELSCOPE_CACHE=/root/.cache/modelscope \
-v /data/modelscope:/root/.cache/modelscope \
192.168.100.149/gpuimages/vllm:latest \
Qwen/Qwen2-1.5B-Instruct \
--tensor-parallel-size 1 \
--max-model-len 4096 \
--gpu-memory-utilization 0.9 \
--max-num-seqs 32
3. 关键配置详解
| 参数 | 作用 | 重要性 |
|---|---|---|
--network host | 使用宿主机网络,减少网络转发损耗,提升性能 | 高 |
--ipc=host | 使用宿主机 IPC 命名空间,支持进程间高速通信 | 高 |
--shm-size 16g | 设置共享内存 16GB,vLLM 高并发场景需要大共享内存 | 高 |
-e VLLM_USE_MODELSCOPE=True | 开启 ModelScope 源,国内加速下载模型 | 中 |
-v /data/modelscope:... | 挂载模型缓存目录,避免重复下载 | 中 |
- 服务地址:
http://宿主机IP:8000/v1,兼容 OpenAI API 标准
六、Docker 部署 Open WebUI(⭐)
1. 启动容器
docker run -d \
--name open-webui \
-p 3000:8080 \
--restart always \
-v open-webui:/app/backend/data \
-e ENABLE_RAG_WEB_SEARCH=false \
-e ENABLE_RAG_HYBRID_SEARCH=false \
-e ENABLE_OLLAMA_API=true \
192.168.100.149/gpuimages/open-webui:latest
2. 环境变量说明
| 参数 | 作用 |
|---|---|
-p 3000:8080 | 宿主机 3000 端口映射 WebUI 的 8080 端口 |
-v open-webui:/app/backend/data | 持久化用户数据、对话记录、配置 |
--restart always | 开机自启,异常自动重启 |
ENABLE_RAG_WEB_SEARCH=false | 关闭联网搜索,纯离线运行 |
3. 后端对接
- 对接 Ollama:界面设置 → Ollama 连接 → 填写
http://宿主机IP:11434 - 对接 vLLM:界面设置 → 外部连接 → 添加 OpenAI 接口
http://宿主机IP:8000/v1 - 访问地址:
http://宿主机IP:3000,首次访问注册管理员账号
七、高频汇总
- 为什么 AI 大模型服务要做容器化? 答:AI 模型依赖链长且版本耦合严格,手动部署环境一致性差、易冲突、迁移难。容器化将整套运行环境打包,保证开发 / 测试 / 生产环境一致,支持快速部署、弹性扩缩、版本回滚,是生产级服务和 K8s 编排的基础。
- NVIDIA Container Toolkit 的工作原理是什么? 答:驱动安装在宿主机,不打包进镜像;容器启动时通过 OCI Hook 机制,动态将宿主机的 GPU 设备节点(
/dev/nvidia*)、驱动库文件、环境变量注入容器隔离空间,让容器内应用透明调用 GPU,同时保持容器的隔离性。 - 容器访问 GPU 的核心参数是什么?有哪些用法? 答:核心参数是
--gpus。支持all(全部 GPU)、指定数量、指定设备 ID、指定 UUID 等多种粒度的 GPU 分配。 - vLLM 容器部署为什么要用 host 网络和大共享内存? 答:
- host 网络减少 Docker NAT 转发的性能损耗,降低推理延迟;
- vLLM 的连续批处理、PagedAttention 机制依赖大量进程间通信,大共享内存(
--shm-size)和--ipc=host能保障通信效率,避免高并发下出现瓶颈。
- 容器化部署中,模型文件为什么推荐用数据卷挂载? 答:容器本身是无状态的,删除重建后数据会丢失。将模型、缓存、用户数据挂载到宿主机数据卷,可持久化存储,避免重复下载模型,同时方便容器升级、迁移。