第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 第三方镜像
# 官方镜像(省略 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 搜索镜像
# 从 Docker Hub 搜索
docker search nginx
# 指定仓库搜索
docker search bitnami/nginx
# 按星标数过滤
docker search --filter=stars=100 nginx
# 限制输出数量
docker search --limit 5 nginx
4.2.2 拉取镜像
# 拉取最新版本(默认)
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 查看本地镜像
# 列出所有本地镜像
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 查看镜像详情
# 查看镜像完整元数据(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 删除镜像
# 删除指定镜像
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 为镜像打标签
# 给已有镜像打标签(相当于创建了一个新引用)
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 |
定期构建 |
| 环境标签 |
staging、production |
环境区分 |
| 多标签 |
同时打 v1.2.3 和 latest |
灵活引用 |
# 推荐:为同一镜像打多个标签
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 文件
# 将镜像导出为 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 文件导入
# 从 tar 文件导入镜像
docker load -i nginx-backup.tar
docker load < nginx-backup.tar
# 导入后查看
docker images | grep nginx
4.4.3 容器导出为镜像
# 将运行中的容器状态导出为新镜像
# 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 原理
# 基于容器的修改创建新镜像
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)
# 悬空镜像:没有标签指向的镜像层
# 通常在重新构建镜像后产生
# 查看悬空镜像
docker images -f "dangling=true"
# 删除所有悬空镜像
docker image prune
# 同时删除未被容器使用的镜像
docker image prune -a
4.6.2 一键清理
# 清理所有未使用的资源(镜像、容器、网络、构建缓存)
docker system prune
# 更激进的清理(包括所有未使用的卷)
docker system prune -a --volumes
# 查看 Docker 磁盘使用情况
docker system df
docker system df -v # 详细信息
4.6.3 磁盘使用分析
# 查看各类型资源占用
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
# Docker Scout 是 Docker 官方的镜像安全扫描工具
docker scout cves nginx:latest
docker scout recommendations nginx:latest
4.7.2 使用 Trivy(开源工具)
# 安装 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:镜像的基本操作
# 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 构建自定义镜像
# 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:磁盘清理
# 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 课后练习
- 基础题:拉取 3 个不同镜像(nginx、python、redis),查看它们的层结构和大小。
- 操作题:使用 docker save/load 完成镜像的备份和恢复流程。
- 进阶题:使用 Trivy 扫描 nginx:latest 镜像,分析其安全漏洞情况。
📖 下一章:Dockerfile 深度解析 ------ 掌握企业级 Dockerfile 编写技能