镜像获取:docker pull 命令详解、配置镜像加速器、从私有仓库拉取镜像、指定标签与摘要拉取

镜像怎么来?说白了,就两条路:要么自己用 Dockerfile 构建,要么从别人那拉下来。而 docker pull,就是我们跟镜像仓库打交道的核心命令。

我刚开始用 Docker 那会儿,觉得 pull 嘛,不就是 docker pull nginx 完事?后来线上环境出了几次事故,才意识到这里面的门道比想象中多。今天咱们就把 docker pull 掰开揉碎了讲清楚。

2.1 docker pull 的基本用法

先看最基础的命令格式:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

如果不指定标签,默认拉取 latest 标签。但我要提醒你——千万别在生产环境依赖 latest。为什么?

我遇到过这么个事:某次凌晨上线,同事拉了个 latest 镜像,结果跟上周测试环境里的行为完全不一样。查了半天才发现,有人刚 push 了新版本,latest 指向变了。从那以后,我团队里就立了规矩——生产环境必须指定具体版本号。

核心原则:永远使用明确的版本标签,避免 latest 带来的不确定性。

2.2 配置镜像加速器

在国内拉 Docker Hub 的镜像,那速度……嗯,懂的都懂。我第一次在公司搭 CI 环境时,一个 docker pull node:18 等了快半小时,差点把键盘砸了。

解决方案就是配置镜像加速器。说白了,就是在国内找个 Docker Hub 的缓存代理,拉镜像时走这个代理,速度能快几十倍。

配置方法很简单,编辑 Docker 的 daemon 配置文件:

# /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}

配置完记得重启 Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

小技巧:配置多个镜像源时,Docker 会按顺序尝试。如果第一个源挂了,会自动切换到下一个。我一般会配 2-3 个,防止单点故障。

验证加速器是否生效,可以看 pull 日志里的下载地址:

docker pull nginx:alpine
# 日志里会显示从 mirror 地址下载 layer

2.3 从私有仓库拉取镜像

大多数公司都有自己的私有仓库,毕竟核心镜像不能放公网上。私有仓库的地址格式是 registry.example.com/repo/image:tag。

拉取私有镜像前,必须先登录:

docker login registry.example.com
# 输入用户名和密码

登录成功后,就可以像拉公共镜像一样操作了:

docker pull registry.example.com/myapp/backend:v2.1.0

注意:如果私有仓库用的是自签名证书,Docker 默认会拒绝连接。需要在 daemon.json 里配置 insecure-registries,或者把 CA 证书加到系统信任链里。我建议用后者,更安全。

配置 insecure 仓库的方式:

{
  "insecure-registries": ["registry.example.com"]
}

2.4 指定标签与摘要拉取

标签(Tag)是给人看的,摘要是给机器校验的。同一个标签可以被多次覆盖指向不同的镜像,但摘要是镜像内容的哈希值,唯一且不可变。

获取镜像摘要的方法:

docker pull nginx:1.25
docker images --digests nginx:1.25
# 输出里会显示 DIGEST 列

或者直接用 inspect 查看:

docker inspect nginx:1.25 | grep -i digest

有了摘要,就可以用摘要拉取镜像,确保拉下来的内容绝对正确:

docker pull nginx@sha256:abc123def456...

我为什么强调这个?有一次我们 CI 流水线里用的 python:3.10-slim 标签,某天突然被官方更新了,底层基础镜像变了,导致我们的应用启动报错。如果当时用摘要锁定,就不会出这种问题。

拉取方式 优点 缺点 适用场景
image:latest 方便,自动获取最新 不可控,随时可能变 本地开发测试
image:1.25 语义化版本,可读性好 标签可能被覆盖 测试环境、预发布
image@sha256:... 不可变,内容绝对确定 可读性差,不方便记忆 生产环境、CI/CD

最佳实践:生产环境用摘要拉取,开发环境用标签拉取。CI 流水线里,先拉标签,再解析出摘要,后续步骤都用摘要。

2.5 镜像拉取流程全景图

下面这张图展示了 docker pull 的完整流程,从客户端发起请求到镜像层被解压到本地:

docker pull 完整流程 Docker 客户端 镜像仓库 Docker Hub(公共) 私有仓库 逐层下载(Layer) 并行下载,支持断点续传 本地镜像存储 /var/lib/docker/overlay2 镜像加速器 在客户端与仓库之间 添加缓存代理层

2.6 实战:一条完整的 pull 命令

把今天讲的知识点串起来,看一条生产级的 pull 命令长什么样:

# 1. 先登录私有仓库
docker login registry.mycompany.com

# 2. 拉取指定标签
docker pull registry.mycompany.com/backend/api:v3.2.1

# 3. 获取该镜像的摘要
DIGEST=$(docker inspect registry.mycompany.com/backend/api:v3.2.1 \
  | jq -r '.[0].RepoDigests[0]' \
  | cut -d'@' -f2)

# 4. 用摘要重新拉取,确保一致性
docker pull registry.mycompany.com/backend/api@${DIGEST}

# 5. 验证
docker images --digests | grep api

我的习惯:在 CI 脚本里,我会先拉标签版本,然后用 docker inspect 提取摘要,后续所有部署步骤都基于摘要。这样既保留了可读性,又保证了不可变性。

嗯,关于 docker pull 的核心内容就这些。记住三个关键点:配置加速器解决速度问题,登录私有仓库解决权限问题,用摘要解决一致性问题。把这三点做好,镜像拉取这块基本就不会出幺蛾子了。