强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Docker 完全指南 / 04 - 镜像管理

04 - 镜像管理

掌握 Docker 镜像的拉取、标记、推送、多架构构建与镜像层分析。


4.1 镜像基础概念

什么是镜像

Docker 镜像(Image)是一个只读的模板,包含运行应用程序所需的一切:代码、运行时、库、环境变量和配置文件。

镜像命名规范:
  [registry_host[:port]/][namespace/]repository[:tag|@digest]

  示例:
  nginx:alpine                    → Docker Hub, library/nginx, tag: alpine
  docker.io/library/nginx:alpine  → 完整地址
  ghcr.io/user/app:v1.0           → GitHub Container Registry
  harbor.example.com/prod/app:latest  → 私有仓库

镜像引用方式

引用方式 示例 说明
标签 (Tag) nginx:1.25 人类可读,可变
摘要 (Digest) nginx@sha256:abc123... 不可变,唯一标识
ID a1b2c3d4e5f6 镜像的短 ID
# 查看镜像的 digest
docker inspect --format '{{index .RepoDigests 0}}' nginx:alpine

# 使用 digest 拉取(确保精确版本)
docker pull nginx@sha256:xxxxx

4.2 镜像拉取(Pull)

# 拉取最新标签
docker pull nginx:latest

# 拉取指定版本
docker pull nginx:1.25-alpine

# 拉取所有标签(谨慎使用,数据量大)
docker pull -a nginx

# 从指定仓库拉取
docker pull ghcr.io/linuxserver/nginx:latest

# 拉取指定平台的镜像
docker pull --platform linux/arm64 nginx:alpine

镜像拉取流程

docker pull nginx:alpine

1. 解析镜像名: docker.io/library/nginx:alpine
2. 查询本地是否已有该镜像
3. 请求 Registry 获取 manifest
4. 解析 manifest,确定需要的层
5. 对比本地已有层,仅下载缺失的层
6. 并发下载各层(可配置并发数)
7. 验证每层的 SHA256 校验和
8. 解压并存储到本地 overlay2 目录
9. 创建镜像索引记录

4.3 镜像列表与查看

# 列出本地镜像
docker images
# 或
docker image ls

# 输出示例:
# REPOSITORY   TAG            IMAGE ID       CREATED        SIZE
# nginx        alpine         a1b2c3d4e5f6   2 weeks ago    41MB
# ubuntu       22.04          f1b2c3d4e5f6   1 month ago    77MB
# python       3.11-slim      d1b2c3d4e5f6   3 weeks ago    125MB

# 格式化输出
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

# 过滤镜像
docker images --filter "dangling=true"    # 悬空镜像
docker images --filter "before=nginx:alpine"
docker images --filter "reference=*nginx*"

# 查看镜像详细信息
docker inspect nginx:alpine

# 查看镜像历史(各层的构建命令)
docker history nginx:alpine

# 格式化查看历史
docker history nginx:alpine --format "table {{.CreatedBy}}\t{{.Size}}" --no-trunc

4.4 镜像标记(Tag)

# 为镜像添加新标签
docker tag nginx:alpine my-registry.com/nginx:v1.0

# 标记为多个标签
docker tag nginx:alpine my-nginx:latest
docker tag nginx:alpine my-nginx:v1.25
docker tag nginx:alpine my-nginx:stable

# 查看所有标签
docker images my-nginx
# REPOSITORY   TAG      IMAGE ID       SIZE
# my-nginx     latest   a1b2c3d4e5f6   41MB
# my-nginx     v1.25    a1b2c3d4e5f6   41MB
# my-nginx     stable   a1b2c3d4e5f6   41MB

注意: docker tag 不会创建新的镜像,只是为同一个镜像 ID 创建新的引用(别名)。它们共享相同的层。


4.5 镜像推送(Push)

# 1. 登录到 Docker Hub
docker login
# 输入用户名和密码

# 2. 登录到私有仓库
docker login harbor.example.com

# 3. 标记镜像(必须包含仓库地址)
docker tag my-app:latest my-dockerhub-user/my-app:v1.0

# 4. 推送镜像
docker push my-dockerhub-user/my-app:v1.0

# 5. 推送所有标签
docker push -a my-dockerhub-user/my-app

# 6. 登出
docker logout
docker logout harbor.example.com

推送流程

docker push my-user/my-app:v1.0

1. 检查认证信息(~/.docker/config.json)
2. 上传镜像 manifest
3. 检查远程仓库已有哪些层
4. 仅上传缺失的层(并行上传)
5. 每层上传前检查是否已存在(跨仓库去重)
6. 上传完成,manifest 关联各层

4.6 镜像删除与清理

# 删除指定镜像
docker rmi nginx:alpine

# 删除多个镜像
docker rmi nginx:alpine ubuntu:22.04

# 强制删除(即使有容器引用)
docker rmi -f nginx:alpine

# 删除所有悬空镜像(dangling images)
docker image prune

# 删除所有未使用的镜像
docker image prune -a

# 删除指定时间前的未使用镜像
docker image prune -a --filter "until=72h"

# 查看镜像占用空间
docker system df
# TYPE          TOTAL   ACTIVE  SIZE     RECLAIMABLE
# Images        15      5       2.5GB    1.8GB (72%)
# Containers    8       3       100MB    80MB (80%)
# Local Volumes 10      4       500MB    300MB (60%)
# Build Cache   20      0       1.2GB    1.2GB (100%)

4.7 多架构镜像(Multi-Architecture)

概念

多架构镜像允许同一镜像标签支持多种 CPU 架构(amd64、arm64 等):

manifest list (多架构清单):
  nginx:latest
    ├── linux/amd64  → sha256:aaa...
    ├── linux/arm64  → sha256:bbb...
    ├── linux/arm/v7 → sha256:ccc...
    └── linux/ppc64le → sha256:ddd...

docker pull nginx:latest
  → 自动选择当前平台对应的镜像

查看镜像支持的架构

# 查看镜像的多架构信息
docker manifest inspect nginx:alpine

# 输出中包含 platforms 字段:
# "platforms": [
#   { "architecture": "amd64", "os": "linux" },
#   { "architecture": "arm64", "os": "linux" },
#   ...
# ]

# 拉取指定平台的镜像
docker pull --platform linux/arm64 nginx:alpine

# 查看本地镜像的架构
docker inspect nginx:alpine | jq '.[0].Architecture'

使用 Buildx 构建多架构镜像

# 1. 创建新的 builder 实例
docker buildx create --name mybuilder --use
docker buildx inspect --bootstrap

# 2. 构建多架构镜像并推送到仓库
docker buildx build \
    --platform linux/amd64,linux/arm64,linux/arm/v7 \
    -t my-user/my-app:v1.0 \
    --push .

# 3. 仅构建(不推送,加载到本地)
docker buildx build \
    --platform linux/amd64 \
    -t my-app:latest \
    --load .

# 4. 查看 builder 实例
docker buildx ls

# 5. 清理 builder
docker buildx rm mybuilder

Buildx 多架构构建的 Dockerfile

# 多架构构建的最佳实践
FROM --platform=$BUILDPLATFORM node:20-alpine AS builder
ARG TARGETPLATFORM
ARG BUILDPLATFORM
ARG TARGETARCH

WORKDIR /app
COPY package*.json ./
RUN npm ci

COPY . .
RUN echo "Building for $TARGETPLATFORM on $BUILDPLATFORM" && \
    npm run build

FROM --platform=$TARGETPLATFORM node:20-alpine
COPY --from=builder /app/dist /app/dist
COPY --from=builder /app/node_modules /app/node_modules
WORKDIR /app
CMD ["node", "dist/index.js"]

4.8 镜像导出与导入

离线环境场景

# 导出镜像为 tar 文件
docker save -o nginx.tar nginx:alpine
docker save nginx:alpine ubuntu:22.04 > images.tar

# 导入 tar 文件
docker load -i nginx.tar

# 导出容器的文件系统(不含镜像元数据)
docker export my-container > container.tar

# 从文件系统创建新镜像
docker import container.tar my-image:imported

save vs export 对比

命令 输入 输出 镜像层 用途
docker save 镜像 tar(含所有层和元数据) 保留 完整镜像迁移
docker export 容器 tar(扁平化文件系统) 丢失 容器文件系统快照
docker load tar(save 的输出) 镜像 还原 导入镜像
docker import tar(export 的输出) 镜像(单层) 扁平化 创建单层镜像

4.9 镜像层分析

# 查看镜像的所有层
docker history nginx:alpine --no-trunc

# 使用 dive 工具分析镜像层(推荐安装)
# https://github.com/wagoodman/dive
dive nginx:alpine

# 查看镜像的详细配置
docker inspect nginx:alpine | jq '.[0].Config'

# 查看环境变量
docker inspect nginx:alpine | jq '.[0].Config.Env'

# 查看暴露的端口
docker inspect nginx:alpine | jq '.[0].Config.ExposedPorts'

# 查看入口点和命令
docker inspect nginx:alpine | jq '.[0].Config.Entrypoint'
docker inspect nginx:alpine | jq '.[0].Config.Cmd'

镜像配置关键字段

docker inspect nginx:alpine | jq '.[0].Config'
{
  "Hostname": "",
  "Env": [
    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
    "NGINX_VERSION=1.25.3"
  ],
  "Cmd": ["nginx", "-g", "daemon off;"],
  "ExposedPorts": { "80/tcp": {} },
  "Entrypoint": ["/docker-entrypoint.sh"],
  "Volumes": null,
  "WorkingDir": "",
  "User": ""
}

4.10 镜像安全基础

# 使用 Docker Scout 扫描镜像漏洞
docker scout cves nginx:alpine

# 快速概览
docker scout quickview nginx:alpine

# 比较两个镜像的安全状况
docker scout compare nginx:1.25-alpine nginx:1.24-alpine

# 使用 Trivy 扫描(第三方工具)
trivy image nginx:alpine

# 仅查看高危和严重漏洞
trivy image --severity HIGH,CRITICAL nginx:alpine

要点回顾

要点 核心内容
镜像引用 标签 (tag) 可变,摘要 (digest) 不可变
拉取优化 仅下载缺失层,可配置镜像源加速
多架构 使用 Buildx 构建 amd64/arm64 等多平台镜像
离线传输 docker save/load 保留完整层,export/import 扁平化
安全扫描 Docker Scout 或 Trivy 扫描镜像漏洞

注意事项

标签可变: latest 标签可以指向不同的镜像。生产环境务必使用具体版本号或 digest。

拉取并发: 如果网络带宽有限,可通过 daemon.json 调整 max-concurrent-downloads

悬空镜像: 构建过程中会产生悬空镜像(<none>:<none>),定期使用 docker image prune 清理。


下一步

05 - 容器管理:学习容器的创建、运行、管理和调试。