从 GPU 容器常用命令到镜像加速、代理、多架构构建和离线分发,分清配置范围,减少拉取超时与环境差异。
Docker 基本使用与镜像源配置(2026)
拿到一台 GPU 节点,第一步往往是拉取 PyTorch 或 vLLM 镜像。但“拉不下来”可能对应完全不同的问题:访问超时、身份认证失败、请求限流、镜像标签不存在,或镜像根本没有目标 CPU 架构的版本。
有效的配置从分清这些问题开始。本文先给出常用命令,再说明 Docker Hub mirror、网络代理和内部仓库的边界,最后覆盖多架构构建与离线交付。
说明
适用范围:命令以 Linux、Bash、rootful Docker Engine 和 systemd 为主;GPU 部分面向已安装兼容 NVIDIA 驱动的 Linux 主机。Docker Desktop、Rootless Docker、独立 BuildKit 和 Kubernetes 的 containerd 使用各自的配置入口。本文核对的是更新日期时的官方文档,未把任何公共地址描述为所有网络下都能访问。
一、先掌握这些命令
先确认 Docker 客户端连接的目标,避免把本地操作发送到另一台服务器:
docker context show
docker version
docker info日常操作可以按“镜像 → 容器 → 数据”来记。下面用 IMAGE、CONTAINER 和 FILE 表示需要替换的实际名称或路径,不要原样执行占位符。
| 目的 | 命令 | 要点 |
|---|---|---|
| 拉取指定版本 | docker pull IMAGE:TAG | 尽量使用明确版本;标签仍可变化 |
| 查看本地镜像 | docker image ls | 本地已有镜像不代表远端标签没有更新 |
| 查看容器,包括已退出的容器 | docker ps -a | 区分容器名与镜像名 |
| 进入运行中的容器 | docker exec -it CONTAINER sh | 镜像未必包含 Bash,精简镜像也可能没有 shell |
| 查看应用日志 | docker logs --tail 200 -f CONTAINER | 查看的是日志驱动可提供的容器输出 |
| 复制文件 | docker cp FILE CONTAINER:/path/ | 适合临时操作;持久数据优先使用挂载 |
| 停止并删除示例容器 | docker stop CONTAINER,然后 docker rm CONTAINER | 删除前确认可写层中没有需要保留的结果 |
| 导出 / 导入镜像 | docker save -o image.tar IMAGE:TAG / docker load -i image.tar | 不包含挂载卷的数据 |
先用一个小型 Web 容器验证基本运行与端口映射:
docker run -d --name web-demo \
-p 127.0.0.1:8080:80 \
nginx:1.28-alpine
curl -I http://127.0.0.1:8080
docker logs --tail 50 web-demo这里只绑定本机回环地址。需要对外开放时,再按服务入口与防火墙设计选择绑定地址。
GPU 容器:先验证驱动,再验证容器
--gpus 不会自动安装宿主机驱动或 NVIDIA Container Toolkit。先在宿主机运行 nvidia-smi;然后按发行版完成 Toolkit 安装,并配置 Docker 运行时。下面两条命令会修改 Docker 配置并重启服务,应先按第四节备份,并在允许中断的时段执行:
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker使用与驱动兼容的 CUDA 镜像验证设备可见性:
docker run --rm --gpus all \
nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
# Bash 中指定第 0、1 张设备;需主机实际存在这两张卡
docker run --rm --gpus '"device=0,1"' \
nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi这个检查证明容器能够访问 GPU 管理接口,不等于训练框架和 CUDA 扩展已经通过运行验证。生产镜像还需要执行实际计算或推理测试。NVIDIA Toolkit 安装与配置 · 官方验证示例
训练时,数据集、模型缓存和输出目录应明确挂载到容器外。--rm 会在退出后删除容器,不应把唯一一份检查点留在容器可写层中;挂载路径属于 Docker daemon 所在主机,使用远程 context 时尤其要注意。Bind mount 说明
二、Docker Hub 的限制,先看账号与网络出口
截至本文更新日期,Docker 官方列出的拉取额度为:
| 访问方式 | 每 6 小时的拉取额度 |
|---|---|
| 未登录 | 每个 IPv4 地址或 IPv6 /64 子网 100 次 |
| 已登录的 Personal 账号 | 200 次 |
| 已认证的 Pro / Team / Business 账号 | 不设该项固定拉取额度,仍受公平使用与滥用限制约束 |
一组共享公网出口的节点,匿名访问时可能共同消耗额度;不能把它理解为“每台机器各有 100 次”。此外,Docker Hub 还有独立的滥用限流机制,同样可能返回 HTTP 429。Docker Hub 使用限制
个人环境可以先执行 docker login。CI 应通过密钥管理注入访问令牌,配合 --password-stdin 登录,避免把令牌写进命令历史、镜像构建参数或仓库。登录可以改变拉取额度的归属,但无法修复 DNS、TLS 或路由问题。Docker 登录说明
三、镜像加速、代理与私有仓库,不是同一个设置
下载失败之前,先分清三条访问路径:目标仓库、发起请求的进程和网络配置,需要一一对应。
registry-mirrors 主要用于 Docker Hub 的镜像拉取,不能用来把 ghcr.io、nvcr.io 和所有其他 Registry 自动改写到同一个地址。网络代理解决 daemon 的出站访问;内部仓库则提供显式的镜像存储与分发地址。Docker Hub mirror 的范围
常见镜像服务的适用范围
下面列的是服务方说明与适用边界,不是速度排行榜,也不是从读者节点完成的连通性测试。
| 服务 | 地址或入口 | 当前应如何理解 |
|---|---|---|
| 阿里云 ACR 镜像加速 | 控制台分配的 https://<id>.mirror.aliyuncs.com | 官方已说明停止同步最新镜像,且有个人开发场景等限制;不宜作为通用生产首选。官方说明 |
| DaoCloud 公共镜像服务 | Hub mirror:https://docker.m.daocloud.io;显式改写前缀:m.daocloud.io/ | 项目公开说明存在白名单、限流和同步延迟;按具体仓库、版本和 digest 验证。项目文档 |
| 腾讯云内网加速 | https://mirror.ccs.tencentyun.com | 腾讯云文档将其列为内网加速地址,应在相应云网络中使用;不是通用公网方案。官方说明 |
| 1Panel 文档所列加速地址 | https://docker.1panel.live | 服务方仍在配置文档中列出该地址;不由此推导目标镜像一定存在或任意地区可用。官方说明 |
| 团队内部镜像仓库 | 平台提供的 Registry / Harbor / 云仓库地址 | 先确认网络范围、认证方式、同步规则和保留策略,再作为项目配置的一部分 |
旧教程中的地址可能发生访问范围变化、服务调整或内容停止更新。不应只凭域名能打开,就判断“大模型镜像一定能完整拉取”;也不宜在没有逐项公告依据时,把一批镜像站统一写成“全部停服”。
四、配置 daemon.json:合并现有内容,再验证
Linux rootful Docker 通常使用 /etc/docker/daemon.json。不要直接用一段教程 JSON 覆盖整个文件:GPU 节点可能已经包含 runtimes,也可能有现成的存储、网络和代理配置。
先创建目录并备份已有文件:
sudo install -d -m 0755 /etc/docker
if sudo test -f /etc/docker/daemon.json; then
sudo cp -a /etc/docker/daemon.json \
"/etc/docker/daemon.json.bak.$(date +%Y%m%d-%H%M%S)"
fi
sudoedit /etc/docker/daemon.json下面是需要按现有配置合并的示例字段。示例使用 DaoCloud 的 Docker Hub mirror 演示格式;实际应替换为从目标节点验证过、且符合使用范围的地址。
{
"registry-mirrors": [
"https://docker.m.daocloud.io"
],
"max-concurrent-downloads": 3,
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}合并时保留原有字段,每个键只出现一次;如果已经配置了日志收集,不要机械地把日志驱动改成示例值。JSON 不支持注释,log-opts 的值需要使用字符串。日志驱动和选项的默认值调整,主要作用于之后创建的容器,已有容器不会自动获得新的日志配置。日志配置说明
max-concurrent-downloads 的默认值是 3。把它设成 10 不保证更快,在带宽受限或连接不稳定时反而可能增加失败。先记录默认配置下的表现,再调整。dockerd 参数参考
编辑后验证,成功再重启:
sudo dockerd --validate --config-file=/etc/docker/daemon.json
# 在确认可中断或完成任务迁移后执行
sudo systemctl restart docker
sudo systemctl --no-pager --full status docker
docker info --format '{{json .RegistryConfig.Mirrors}}'重启 daemon 可能停止正在运行的容器。live-restore 能在特定条件下保留容器运行,但不能把它当作任何变更都无中断的保证。验证配置失败时不要重启;启动失败时检查 journalctl -u docker,恢复对应备份并排查是否与 systemd 启动参数重复定义。Live restore 说明
docker info 显示镜像地址,只证明配置被读取,不能证明实际拉取命中了缓存。还需要用目标镜像测试,并结合 daemon 或缓存服务日志判断。
Docker Desktop 与 Rootless Docker
Docker Desktop 可在 Settings → Docker Engine 中合并对应引擎配置;网络代理应在 Desktop 的代理设置中配置,daemon.json 中的代理字段会被 Desktop 忽略。Rootless Docker 则使用用户级配置和用户级服务,不能照搬上面的系统路径与重启命令。Desktop 设置 · daemon 代理说明
五、GHCR、NGC、Quay 等仓库怎样访问
方法 A:给 Docker daemon 配置网络代理
如果组织提供了获准使用的 HTTP 代理,可在支持这些选项的 Docker Engine 中合并以下配置。地址是占位示例,需要替换;内部仓库应按实际域名加入 no-proxy。
{
"proxies": {
"http-proxy": "http://proxy.example.com:3128",
"https-proxy": "http://proxy.example.com:3128",
"no-proxy": "localhost,127.0.0.1,registry.example.com"
}
}这里代理的是 daemon 拉取镜像的网络访问。在当前终端中 export HTTPS_PROXY=...,不代表已经运行的 daemon 会继承;Dockerfile 中下载 Python 包或模型所需的代理,也要按构建环境另行配置。HTTPS 目标使用 HTTP 代理的 CONNECT 通道是常见配置,因此 https-proxy 的值不一定以 https:// 开头。官方代理配置
方法 B:按服务方规则显式改写镜像名
DaoCloud 当前推荐在原镜像名前添加 m.daocloud.io/,而不是把所有源站都拼到 docker.m.daocloud.io/ 后面。例如:
# Docker Hub:保留 docker.io/library 路径
docker pull m.daocloud.io/docker.io/library/alpine:3.21
# Kubernetes 公共仓库:使用当前仓库域名
docker pull m.daocloud.io/registry.k8s.io/pause:3.9
# NVIDIA NGC:仅在服务支持且上游镜像允许访问时使用
docker pull m.daocloud.io/nvcr.io/nvidia/pytorch:24.10-py3这种服务是 Registry 内容代理,不是“全协议加速器”。上游认证、许可、同步和服务白名单仍可能影响结果。不要把私有仓库凭据交给未经批准的公共代理;涉及私有镜像时,优先使用源站认证或内部同步流程。DaoCloud 使用规则
本地重新打标签只会增加镜像引用,不会配置后续下载路径:
docker tag m.daocloud.io/registry.k8s.io/pause:3.9 \
registry.k8s.io/pause:3.9之后执行 docker pull registry.k8s.io/pause:3.9,仍然是在请求原仓库。需要稳定复现时,应记录源站可信的 manifest digest,区分多架构索引与单平台 manifest;不要把本地 image ID 直接当成仓库 digest。
六、Buildx 多架构:先确认依赖,再选择构建节点
--platform linux/amd64,linux/arm64 表达的是目标平台,不会自动把所有二进制依赖变成 ARM 版本。基础镜像、Python wheel、CUDA 库和自定义扩展都需要支持目标平台。QEMU 可以帮助执行部分跨架构构建,但可能很慢,也不能替代 GPU 实机运行验证。多架构构建说明
先用一个不依赖 GPU 的最小项目确认链路。在 examples/multiarch/ 中保存下面两个文件。
hello.py:
import platform
print(f"Hello from {platform.system()} / {platform.machine()}")Dockerfile:
FROM python:3.12-slim-bookworm
WORKDIR /app
COPY hello.py .
CMD ["python", "hello.py"]下面的 registry.example.com/team/arch-demo:1.0 是占位地址,先替换为有推送权限的真实仓库,并完成登录:
cd examples/multiarch
docker buildx create --name ai-multi --driver docker-container --use
docker buildx inspect --bootstrap
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t registry.example.com/team/arch-demo:1.0 \
--push .
docker buildx imagetools inspect registry.example.com/team/arch-demo:1.0先检查 builder 输出的 Platforms。缺少目标平台时,按构建环境配置原生节点、模拟执行或交叉编译;已有同名 builder 时使用 docker buildx use ai-multi。对于 CUDA 扩展等重型编译,优先考虑原生构建节点。
--push 会把结果发布到指定仓库,目标不是本地镜像列表。是否支持把多平台结果整体加载到本地,取决于驱动、导出方式和 image store,不能把 --load 视为所有环境通用的替代品。构建与输出限制
docker pull 成功,为什么 build 仍然超时
使用 docker-container 驱动时,BuildKit 在独立容器中运行。不要假设 Docker Engine 的 mirror 配置会自动成为这个 builder 的配置。
需要为它设置 Hub mirror 时,可保存 examples/buildkitd.toml:
[registry."docker.io"]
mirrors = ["docker.m.daocloud.io"]从文章目录执行,创建一个使用该配置的独立 builder:
docker buildx create --name ai-multi-mirror \
--driver docker-container \
--buildkitd-config examples/buildkitd.toml \
--use --bootstrap替换 mirror 地址后再投入团队使用。独立 BuildKit 的网络代理、证书和认证也需要按它的运行环境配置;配置 Registry mirror 不会加速 Dockerfile 中的所有 HTTP 下载。Kubernetes 使用 containerd 时,同样应调整 containerd 的仓库配置,而非只改 Docker 的文件。BuildKit 官方配置
七、离线分发:镜像、架构和数据一起交代清楚
从镜像来源到目标节点,交付需要闭环:公网缓存、内部仓库和离线归档各有用途;每一步都保留版本与平台信息。
离线分发适合隔离网络或少量节点初始化。联网机器先拉取目标平台,再导出镜像。下面使用支持 save --platform 的 Docker 版本,该选项需要 API 1.48 或更高版本:
# 联网机器:目标是 amd64 节点
docker pull --platform linux/amd64 alpine:3.21
docker image inspect alpine:3.21 --format '{{.Os}}/{{.Architecture}}'
docker image save --platform linux/amd64 -o alpine-amd64.tar alpine:3.21
sha256sum alpine-amd64.tar > alpine-amd64.tar.sha256通过批准的文件传输方式,将归档及校验文件一起送到目标机器。在同一目录中执行:
sha256sum -c alpine-amd64.tar.sha256
docker load -i alpine-amd64.tar
docker image inspect alpine:3.21 --format '{{.Os}}/{{.Architecture}}'
docker run --rm --pull=never alpine:3.21 uname -m旧版本可以不加 save --platform,但仍须确认本地镜像存储中包含的是所需平台。docker save 只导出本地实际持有的镜像内容,不会自动补齐远端所有架构。归档 SHA-256 用于检查传输完整性,不等于验证镜像发布者身份。save 说明 · load 说明
另外,镜像包不包含挂载卷、宿主机目录中的模型与数据集,也不包含宿主机驱动。AI 服务的离线交付清单应同时记录镜像版本与平台、模型 revision、配置和系统运行前提。
不能笼统声称 save/load 比私有仓库更快。仓库可以复用已有层并服务多节点;归档传输、磁盘读写和导入也有成本,应按实际拓扑比较。
八、团队实践:把常用镜像同步到内部仓库
对于持续运行的 GPU 集群,推荐把经过验证的基础镜像和业务镜像同步到内部仓库,让生产节点显式使用内部地址。需要上游内容时,由受控的同步或构建流程访问源站,而不是每个节点各自依赖公共加速器。
单平台镜像的简单同步流程如下。示例中的目标域名和项目名需要替换,并提前确认仓库权限:
docker pull --platform linux/amd64 nginx:1.28-alpine
docker tag nginx:1.28-alpine registry.example.com/team/nginx:1.28-alpine-amd64
docker login registry.example.com
docker push registry.example.com/team/nginx:1.28-alpine-amd64该流程不应被当作保留整个多架构索引的通用办法;需要完整迁移多平台镜像时,使用支持复制索引及各平台 manifest 的仓库复制工具或产品能力,并检查目标端结果。
九章智算云等托管环境中的内部仓库地址、访问范围和预缓存清单,应以具体产品交付说明为准。只有取得可核验的测试记录,才适合对外发布吞吐数据:至少说明镜像大小、平台、首次拉取或缓存命中、并发节点数、网络带宽,以及是否把解压写盘计入耗时。
排障与清理,避免靠反复重试解决所有问题
| 现象 | 优先检查 |
|---|---|
i/o timeout、连接超时 | daemon 所在主机的 DNS、出口、代理及实际下载域名 |
429 / toomanyrequests | 登录状态、共享出口、源站或代理服务的限流规则 |
unauthorized / denied | 当前仓库的凭据、令牌权限、仓库是否私有 |
manifest unknown | 仓库路径、标签、镜像是否已同步 |
no matching manifest | 镜像是否提供目标 OS / CPU 架构 |
x509 相关错误 | 系统时间、CA 信任链、企业代理证书;不要直接改成不安全仓库 |
| 拉取成功但 GPU 不可用 | 宿主机驱动、Toolkit、设备授权与镜像兼容性 |
清理之前先查看占用:
docker system df
docker image ls
docker ps -adocker image prune 默认清理 dangling 镜像;加 -a 后,范围扩大为所有未被任何容器引用的镜像,包含有标签、刚下载、准备用于回滚的镜像。它不是“只清旧镜像”,不宜放进入门脚本自动执行。镜像清理范围
一套可维护的 Docker 环境,应能回答三件事:镜像来自哪里,当前配置作用于哪个进程,以及目标机器能否运行这份镜像。把这三点记录下来,比不断收集新的加速器地址更有助于团队复现和排障。
本文配图为原创示意。示例代码完成静态检查,未在读者网络、Docker daemon 或 GPU 节点进行拉取、构建和运行测试;文中保留了相应的验证步骤。
最后更新于
