第04章:Docker 镜像管理

第04章:Docker 镜像管理

本章目标:全面掌握 Docker 镜像的搜索、拉取、查看、构建、推送等操作,理解镜像标签和分层的管理策略。


4.1 镜像的命名规范

4.1.1 镜像名称的组成

复制代码
[registry-host[:port]/][namespace/]repository[:tag|@digest]

完整格式示例:
docker.io/library/nginx:latest
registry.cn-hangzhou.aliyuncs.com/myproject/myapp:v1.0
ghcr.io/owner/repo:sha-abc123
组成部分 说明 默认值
registry-host 镜像仓库地址 docker.io(Docker Hub)
namespace 命名空间/组织 library(官方镜像)
repository 镜像名称 必填
tag 标签(版本号) latest
digest 内容哈希 ---

4.1.2 官方镜像 vs 第三方镜像

bash 复制代码
# 官方镜像(省略 namespace 和 registry)
docker pull nginx          # 等价于 docker.io/library/nginx:latest

# 第三方镜像(需要指定 namespace)
docker pull bitnami/nginx  # docker.io/bitnami/nginx:latest

# 私有仓库镜像(需要指定 registry 地址)
docker pull registry.example.com:5000/myproject/myapp:v1.0

4.2 镜像的基本操作

4.2.1 搜索镜像

bash 复制代码
# 从 Docker Hub 搜索
docker search nginx

# 指定仓库搜索
docker search bitnami/nginx

# 按星标数过滤
docker search --filter=stars=100 nginx

# 限制输出数量
docker search --limit 5 nginx

4.2.2 拉取镜像

bash 复制代码
# 拉取最新版本(默认)
docker pull nginx

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

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

# 通过 digest 拉取(精确版本)
docker pull nginx@sha256:abc123def456...

# 从指定仓库拉取
docker pull registry.cn-hangzhou.aliyuncs.com/library/nginx:latest

4.2.3 查看本地镜像

bash 复制代码
# 列出所有本地镜像
docker images
docker image ls

# 以表格形式显示更多信息
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}\t{{.CreatedSince}}"

# 输出示例:
# REPOSITORY    TAG         SIZE      CREATEDSINCE
# nginx         1.25        187MB     2 weeks ago
# nginx         1.25-alpine 41MB      2 weeks ago
# python        3.11        912MB     3 weeks ago
# ubuntu        22.04       77.8MB    1 month ago

# 过滤镜像
docker images --filter "dangling=true"     # 悬空镜像(无标签)
docker images --filter "reference=nginx:*" # 指定仓库的镜像
docker images --filter "before=ubuntu:22.04"  # 在某个镜像之前创建的
docker images --filter "since=ubuntu:22.04"   # 在某个镜像之后创建的

# 显示镜像 ID
docker images -q

4.2.4 查看镜像详情

bash 复制代码
# 查看镜像完整元数据(JSON 格式)
docker image inspect nginx:latest

# 查看镜像的层信息
docker history nginx:latest

# 查看镜像大小
docker image inspect nginx:latest --format '{{.Size}}'
# 输出: 187425608 (字节)

# 转换为可读格式
docker system df -v  # 查看所有镜像的详细大小

4.2.5 删除镜像

bash 复制代码
# 删除指定镜像
docker rmi nginx:latest
docker image rm nginx:latest

# 批量删除
docker rmi $(docker images -q)                    # 删除所有镜像
docker rmi $(docker images --filter "dangling=true" -q)  # 删除悬空镜像
docker images -q --filter "reference=nginx*" | xargs docker rmi  # 删除 nginx 相关镜像

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

4.3 镜像标签管理

4.3.1 什么是镜像标签

标签(Tag)是给镜像起的"别名",用于标识不同版本:

复制代码
nginx:1.25        ← 精确版本
nginx:1.25-alpine ← 精确版本 + 变体
nginx:latest      ← 最新版本(不推荐生产使用)
nginx             ← 等价于 nginx:latest

4.3.2 为镜像打标签

bash 复制代码
# 给已有镜像打标签(相当于创建了一个新引用)
docker tag nginx:latest myregistry.com/nginx:v1.0
docker tag nginx:latest myregistry.com/nginx:production

# 标签不影响镜像内容,只是额外的引用
docker images myregistry.com/nginx
# REPOSITORY               TAG         SIZE
# myregistry.com/nginx     v1.0        187MB
# myregistry.com/nginx     production  187MB
# nginx                    latest      187MB   ← 原始标签仍在

4.3.3 标签策略最佳实践

策略 示例 适用场景
语义化版本 v1.2.3 正式发布
Git SHA commit-a1b2c3d 开发版本
日期标签 2024.06.15 定期构建
环境标签 stagingproduction 环境区分
多标签 同时打 v1.2.3latest 灵活引用
bash 复制代码
# 推荐:为同一镜像打多个标签
docker tag myapp:build-123 myregistry.com/myapp:v1.2.3
docker tag myapp:build-123 myregistry.com/myapp:latest

4.4 镜像的导入与导出

4.4.1 导出为 tar 文件

bash 复制代码
# 将镜像导出为 tar 文件
docker save -o nginx-backup.tar nginx:latest
docker save nginx:latest > nginx-backup.tar

# 导出多个镜像
docker save -o images-backup.tar nginx:latest python:3.11 ubuntu:22.04

# 导出所有镜像
docker save -o all-images.tar $(docker images -q)

4.4.2 从 tar 文件导入

bash 复制代码
# 从 tar 文件导入镜像
docker load -i nginx-backup.tar
docker load < nginx-backup.tar

# 导入后查看
docker images | grep nginx

4.4.3 容器导出为镜像

bash 复制代码
# 将运行中的容器状态导出为新镜像
# Step 1: 启动容器并做一些修改
docker run -it ubuntu:22.04 /bin/bash
# 在容器内安装一些软件...
apt-get update && apt-get install -y vim curl
exit

# Step 2: 导出容器为 tar
docker export <container-id> > my-ubuntu.tar

# Step 3: 将 tar 导入为新镜像
docker import my-ubuntu.tar my-ubuntu:v1.0

# 注意:export 会丢失镜像的元数据(如 CMD、ENV 等)
# 建议优先使用 docker commit

4.4.4 save vs export 对比

特性 docker save docker export
输入 镜像(image) 容器(container)
输出 保留所有层和元数据 合并为单层,丢失元数据
导入命令 docker load docker import
适用场景 备份、迁移镜像 创建简单的文件系统快照

4.5 镜像构建:commit 方式

4.5.1 docker commit 原理

bash 复制代码
# 基于容器的修改创建新镜像
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

# 示例:
# Step 1: 启动一个容器
docker run -it ubuntu:22.04 /bin/bash

# Step 2: 在容器中安装软件
apt-get update
apt-get install -y python3
python3 --version

# Step 3: 退出容器
exit

# Step 4: 基于容器创建镜像
docker commit <container-id> my-ubuntu-python:v1.0

# Step 5: 验证
docker run -it my-ubuntu-python:v1.0 python3 --version
# Python 3.10.12

4.5.2 commit 的局限性

问题 说明
不可追溯 无法知道镜像经历了哪些变更
不可重复 手动操作难以精确复现
体积膨胀 无法利用缓存机制优化
不符合最佳实践 应该使用 Dockerfile 构建

⚠️ 企业级规范:生产环境应使用 Dockerfile 构建镜像,docker commit 仅用于临时调试。


4.6 清理无用镜像

4.6.1 悬空镜像(Dangling Images)

bash 复制代码
# 悬空镜像:没有标签指向的镜像层
# 通常在重新构建镜像后产生

# 查看悬空镜像
docker images -f "dangling=true"

# 删除所有悬空镜像
docker image prune

# 同时删除未被容器使用的镜像
docker image prune -a

4.6.2 一键清理

bash 复制代码
# 清理所有未使用的资源(镜像、容器、网络、构建缓存)
docker system prune

# 更激进的清理(包括所有未使用的卷)
docker system prune -a --volumes

# 查看 Docker 磁盘使用情况
docker system df
docker system df -v  # 详细信息

4.6.3 磁盘使用分析

bash 复制代码
# 查看各类型资源占用
docker system df
# TYPE          TOTAL     ACTIVE    SIZE      RECLAIMABLE
# Images        15        5         2.8GB     1.9GB (67%)
# Containers    8         3         150MB     120MB (80%)
# Local Volumes 10        4         2.1GB     1.5GB (71%)
# Build Cache   50        0         3.2GB     3.2GB (100%)

# 按大小排序查看镜像
docker images --format "{{.Repository}}:{{.Tag}}\t{{.Size}}" | sort -t$'\t' -k2 -h -r

4.7 镜像安全扫描

4.7.1 使用 Docker Scout

bash 复制代码
# Docker Scout 是 Docker 官方的镜像安全扫描工具
docker scout cves nginx:latest
docker scout recommendations nginx:latest

4.7.2 使用 Trivy(开源工具)

bash 复制代码
# 安装 Trivy
# macOS
brew install trivy

# Linux
sudo apt-get install trivy

# 扫描镜像漏洞
trivy image nginx:latest
trivy image --severity HIGH,CRITICAL nginx:latest

# 输出 JSON 格式报告
trivy image -f json -o report.json nginx:latest

4.8 动手实验

实验 4.1:镜像的基本操作

bash 复制代码
# 1. 搜索并拉取镜像
docker search python
docker pull python:3.11-slim

# 2. 查看本地镜像
docker images python

# 3. 查看镜像历史
docker history python:3.11-slim

# 4. 导出镜像
docker save python:3.11-slim > python-backup.tar
ls -lh python-backup.tar

# 5. 删除镜像
docker rmi python:3.11-slim
docker images | grep python  # 确认已删除

# 6. 从备份恢复
docker load < python-backup.tar
docker images python

实验 4.2:使用 commit 构建自定义镜像

bash 复制代码
# 1. 启动基础容器
docker run -it --name my-custom ubuntu:22.04 /bin/bash

# 2. 在容器内安装软件
apt-get update
apt-get install -y curl vim git
mkdir -p /app
echo "Hello Custom Image" > /app/hello.txt

# 3. 退出容器
exit

# 4. 基于容器创建镜像
docker commit -m "Added curl vim git" my-custom my-ubuntu-custom:v1.0

# 5. 验证新镜像
docker run --rm my-ubuntu-custom:v1.0 cat /app/hello.txt
# Hello Custom Image

docker run --rm my-ubuntu-custom:v1.0 curl --version

# 6. 清理
docker rm my-custom

实验 4.3:磁盘清理

bash 复制代码
# 1. 查看磁盘使用
docker system df

# 2. 创建一些悬空镜像
for i in {1..5}; do
  docker build -t test-$i -<<EOF
FROM alpine:latest
RUN echo "test $i"
EOF
done

# 3. 查看悬空镜像
docker images -f "dangling=true"

# 4. 清理悬空镜像
docker image prune -f

# 5. 最终清理
docker system prune -f

4.9 本章小结

操作 命令 说明
搜索 docker search 在仓库中搜索镜像
拉取 docker pull 下载镜像到本地
列表 docker images 查看本地镜像
详情 docker inspect 查看镜像完整元数据
历史 docker history 查看镜像的构建历史
标签 docker tag 为镜像添加标签
导出 docker save 导出为 tar 文件
导入 docker load 从 tar 文件导入
提交 docker commit 基于容器创建镜像
删除 docker rmi 删除镜像
清理 docker image prune 清理无用镜像

4.10 课后练习

  1. 基础题:拉取 3 个不同镜像(nginx、python、redis),查看它们的层结构和大小。
  2. 操作题:使用 docker save/load 完成镜像的备份和恢复流程。
  3. 进阶题:使用 Trivy 扫描 nginx:latest 镜像,分析其安全漏洞情况。

📖 下一章:Dockerfile 深度解析 ------ 掌握企业级 Dockerfile 编写技能