第4章 Docker基础:Docker安装、镜像拉取、容器创建与基本操作
说到多机多卡训练的环境配置,Docker 几乎是绕不开的工具。我刚开始接触分布式训练时,最头疼的就是环境不一致——明明在开发机跑得好好的,到了集群上就各种报错。后来用了 Docker,这个问题才算彻底解决。
说白了,Docker 就是一个轻量级的虚拟化方案。它不像虚拟机那样要装一整套操作系统,而是直接共享宿主机的内核,只把应用和它需要的依赖打包在一起。你想想看,这对我们做深度学习的人来说有多方便?
4.1 Docker 安装
安装 Docker 其实很简单,但不同系统有些小差异。我个人的习惯是,不管用什么系统,都优先用官方推荐的安装方式。
Ubuntu / Debian 系
# 更新包索引
sudo apt-get update
# 安装依赖
sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加 Docker 官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 设置稳定版仓库
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装 Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
小提示:安装完成后,记得把当前用户加入 docker 组,这样就不用每次敲 sudo 了。
sudo usermod -aG docker $USER
newgrp docker
CentOS / RHEL 系
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
Windows / macOS
直接去 Docker 官网下载 Docker Desktop 安装包就行。嗯,这里要注意:Windows 用户记得开启 WSL2,不然性能会差很多。我在项目中遇到过有人用 Hyper-V 模式跑训练,结果 GPU 透传死活不生效,换成 WSL2 就好了。
4.2 镜像拉取与管理
镜像是什么?你可以把它理解成一个「模板」。这个模板里装好了操作系统、CUDA、cuDNN、PyTorch 等等,你拿来就能用。
常用镜像仓库
| 仓库地址 | 说明 |
|---|---|
| Docker Hub | 官方仓库,镜像最全,但国内访问慢 |
| NVIDIA NGC | NVIDIA 官方镜像,自带 CUDA、cuDNN,做深度学习首选 |
| 阿里云 ACR / 腾讯云 TCR | 国内镜像加速,拉取速度快 |
拉取镜像
# 从 Docker Hub 拉取 Ubuntu 镜像
docker pull ubuntu:20.04
# 从 NVIDIA NGC 拉取 PyTorch 镜像(推荐)
docker pull nvcr.io/nvidia/pytorch:23.12-py3
# 查看本地已有镜像
docker images
# 删除镜像
docker rmi ubuntu:20.04
重点:做多机多卡训练时,我强烈建议直接用 NVIDIA NGC 的 PyTorch 镜像。它里面已经配好了 NCCL、CUDA、cuDNN,省去了一大堆编译和调试的麻烦。我曾经自己从零搭环境,光 NCCL 的版本兼容问题就折腾了两天。
4.3 容器创建与基本操作
镜像拉下来之后,就要创建容器了。容器就是镜像的一个「运行实例」。你可以同时跑多个容器,它们之间互不干扰。
创建并启动容器
# 基本用法
docker run -it --name my_container ubuntu:20.04 /bin/bash
# 带 GPU 支持(做深度学习必备)
docker run -it --gpus all \
--name pytorch_container \
-v /home/user/data:/workspace/data \
-p 8888:8888 \
nvcr.io/nvidia/pytorch:23.12-py3
# 后台运行(detached 模式)
docker run -d --gpus all --name train_container \
nvcr.io/nvidia/pytorch:23.12-py3 \
python train.py
参数说明:
-it:交互式终端,进去之后可以敲命令--gpus all:让容器能访问所有 GPU-v:挂载目录,把宿主机的目录映射到容器里-p:端口映射,比如 Jupyter 的 8888 端口--name:给容器起个名字,方便管理
容器生命周期管理
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop pytorch_container
# 启动已停止的容器
docker start pytorch_container
# 进入正在运行的容器
docker exec -it pytorch_container /bin/bash
# 删除容器
docker rm pytorch_container
注意:容器删除后,里面的数据就没了。所以重要的代码和数据一定要通过
-v 挂载到宿主机上。我曾经有个同事,在容器里跑了三天训练,结果不小心把容器删了,模型权重全丢了……嗯,从那以后他每次都会挂载目录。
4.4 核心知识体系
下面这张图是我自己总结的 Docker 核心知识体系,你可以对照着看看自己掌握了哪些。
4.5 常用命令速查
| 命令 | 作用 | 示例 |
|---|---|---|
docker pull |
拉取镜像 | docker pull nvcr.io/nvidia/pytorch:23.12-py3 |
docker run |
创建并启动容器 | docker run -it --gpus all ubuntu bash |
docker exec |
进入运行中的容器 | docker exec -it container_name bash |
docker ps |
查看容器列表 | docker ps -a |
docker commit |
将容器保存为新镜像 | docker commit container_name my_image:v1 |
我的习惯:每次创建容器时,我都会把代码和数据目录挂载进去,然后在容器里只装运行时依赖。这样即使容器删了,代码和数据还在。另外,我会用
docker commit 把配置好的环境保存成新镜像,下次直接拉这个镜像就行,省得重复安装。
好了,Docker 基础就讲到这里。你只要把镜像拉取、容器创建、目录挂载和 GPU 透传这几个点搞明白,后面做多机多卡训练的环境配置就会顺畅很多。记住一点:容器是临时的,数据是永久的——挂载目录这个习惯,越早养成越好。