Skip to content

Docker 镜像管理 ​

1. 镜像引用 ​

完整引用形式:

text
[registry-host[:port]/]namespace/repository[:tag][@digest]

示例:

text
docker.io/library/nginx:1.29-alpine
registry.example.internal/team/api:2026.08.12
registry.example.internal/team/api@sha256:0123...
  • 未写 Registry 时通常使用 Docker Hub。
  • 未写 namespace 时可能落到默认命名空间。
  • 未写 tag 时使用 latest,但 latest 只是普通标签,不等于最新、安全或稳定。
  • digest 是内容标识;在 Registry 中同一摘要指向不可变内容。

2. 拉取镜像 ​

bash
docker pull nginx:alpine
docker pull --platform linux/arm64 nginx:alpine
docker pull registry.example.internal/team/api:2026.08.12

查看拉取后的 RepoDigest:

bash
docker image inspect nginx:alpine \
  --format '{{json .RepoDigests}}'

生产清单同时记录人类可读标签和 digest:

text
registry.example.internal/team/api:2026.08.12
registry.example.internal/team/api@sha256:...

按 digest 拉取并添加本地别名:

bash
docker pull registry.example.internal/team/api@sha256:REPLACE_ME
docker tag \
  registry.example.internal/team/api@sha256:REPLACE_ME \
  team-api:verified

3. 列出与筛选 ​

bash
docker image ls
docker image ls --all
docker image ls --digests
docker image ls --filter dangling=true
docker image ls --filter reference='registry.example.internal/team/*'
docker image ls --format 'table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}'

镜像表中显示的 SIZE 不能简单相加估算磁盘占用,因为不同镜像会共享层。使用:

bash
docker system df
docker system df -v

4. 标签 ​

docker tag 不复制层,只创建新的引用:

bash
docker tag team-api:build-1042 \
  registry.example.internal/team/api:2026.08.12

docker tag team-api:build-1042 \
  registry.example.internal/team/api:git-a1b2c3d

推荐标签组合:

  • 不可复用的构建号或 Git SHA;
  • 语义版本;
  • 可移动的环境别名仅用于发现,不作为最终审计凭据。

不推荐只推送 latest。回滚时无法知道它先前指向什么。

5. 镜像 ID、digest 与 diff ID ​

  • Image ID 通常是镜像配置对象的 digest。
  • Manifest digest 是 Registry 分发对象的 digest,常见于 RepoDigests。
  • Layer digest 标识压缩分发内容。
  • Diff ID 标识解压后的层内容。
  • 多平台 tag 指向 manifest index;不同平台有各自 manifest digest。

因此,本地 IMAGE ID 与 repo@sha256:... 不必相同。发布和部署通常记录 Registry manifest/index digest。

6. 检查镜像 ​

bash
docker image inspect nginx:alpine

docker image inspect nginx:alpine \
  --format 'user={{.Config.User}} entrypoint={{json .Config.Entrypoint}} cmd={{json .Config.Cmd}}'

docker image inspect nginx:alpine \
  --format 'os={{.Os}} arch={{.Architecture}} created={{.Created}}'

docker history --no-trunc nginx:alpine

docker history 可发现:

  • 不必要的大层;
  • 曾经写入层的命令;
  • 构建步骤顺序;
  • 可疑的 ARG/命令文本。

不要假设后续 RUN rm secret 能从前一层删除 secret;前一层仍保留内容。Secret 应使用 BuildKit secret mount。

7. 多平台镜像 ​

查看远端 manifest:

bash
docker buildx imagetools inspect nginx:alpine
docker buildx imagetools inspect \
  registry.example.internal/team/api:2026.08.12

显式运行某平台:

bash
docker run --rm --platform linux/amd64 alpine uname -m

模拟运行比原生慢,并可能遇到系统调用差异。生产应尽量部署对应架构的原生镜像。

8. 保存与加载 ​

save/load 用于镜像归档,可保留标签和层:

bash
docker image save \
  -o team-api.tar \
  registry.example.internal/team/api:2026.08.12

sha256sum team-api.tar > team-api.tar.sha256
sha256sum -c team-api.tar.sha256

docker image load -i team-api.tar

压缩传输:

bash
docker image save team-api:2026.08.12 | gzip > team-api.tar.gz
gzip -dc team-api.tar.gz | docker image load

离线包应包含:

  • 镜像归档;
  • SHA-256 校验文件;
  • 来源、tag、digest、平台和构建时间清单;
  • SBOM、签名/证明材料;
  • 导入和验证步骤。

9. export/import 与 save/load 的区别 ​

命令对象保留镜像层和历史常见用途
docker image save/load镜像是镜像离线搬运
docker container export/import容器 rootfs 快照否极少数文件系统迁移

export 不包含 volume 数据,并会扁平化文件系统,不适合作为常规镜像备份:

bash
docker container export old-container > rootfs.tar
docker image import rootfs.tar legacy-snapshot:manual

优先保留 Dockerfile、源码、锁文件和 CI 构建记录,而不是把手工修改的容器 export 成“黄金镜像”。

10. 删除镜像 ​

删除明确引用:

bash
docker image rm team-api:old
docker image rm sha256:IMAGE_ID

先预览悬空镜像:

bash
docker image ls --filter dangling=true

再清理:

bash
docker image prune

危险: docker image prune -a 会删除所有未被任何容器引用的镜像,包括仍准备回滚但当前未运行的镜像。生产执行前先导出清单、核对回滚窗口和 Registry 可用性。

按时间筛选:

bash
docker image prune --filter 'until=168h'

11. 复制 Registry 中的镜像 ​

简单方式是 pull/tag/push:

bash
docker pull source.example/team/api@sha256:REPLACE_ME
docker tag \
  source.example/team/api@sha256:REPLACE_ME \
  target.example/team/api:2026.08.12
docker push target.example/team/api:2026.08.12

注意多平台镜像用这种方式可能只处理当前平台变体。需要保留完整 index 时,使用支持 OCI copy 的受控工具并验证所有平台 manifest。

12. 镜像更新与缓存 ​

运行同一 tag 不保证自动拉取新内容:

bash
docker pull team-api:stable
docker run --pull=always team-api:stable

Compose:

bash
docker compose pull
docker compose up -d --pull always

生产环境更推荐 CI 解析并批准 digest,再把固定 digest 写入部署清单。

13. 镜像安全检查 ​

最低检查项:

bash
docker image inspect IMAGE
docker history --no-trunc IMAGE
docker scout cves IMAGE
docker scout sbom IMAGE

如果未安装 Scout,使用组织批准的扫描器。扫描结果必须结合:

  • 包是否实际可达;
  • 镜像基础发行版和支持期;
  • 漏洞是否已有修复版本;
  • 运行时权限和网络暴露;
  • 误报例外的所有者与到期时间。

14. 常见问题 ​

14.1 manifest unknown ​

检查 tag 拼写、仓库路径、认证权限和目标平台:

bash
docker login registry.example.internal
docker buildx imagetools inspect registry.example.internal/team/api:TAG

14.2 no matching manifest ​

镜像没有当前 OS/ARCH 变体。检查:

bash
docker info --format '{{.OSType}}/{{.Architecture}}'
docker buildx imagetools inspect IMAGE

14.3 拉取成功但运行的不是预期版本 ​

比较 digest,而不是只比较 tag:

bash
docker image inspect IMAGE --format '{{json .RepoDigests}}'
docker container inspect CONTAINER --format '{{.Image}}'

15. 官方参考 ​

继续阅读