4、Docker镜像管理:镜像的获取、查看、删除与导入导出

镜像管理,说白了就是Docker世界的「物资管理」。你想想看,没有镜像,容器就是空中楼阁。我刚开始接触Docker时,最常干的事就是拉镜像、看镜像、删镜像——这三板斧玩熟了,基本就入门了。

这一章,咱们就把镜像的整个生命周期走一遍。从获取到清理,从导入到导出,全给你捋清楚。

4.1 镜像的获取:docker pull

要跑容器,先得有镜像。怎么来?最直接的方式就是从镜像仓库拉取。

核心命令:

docker pull [选项] [仓库地址/]镜像名[:标签]

举个例子,拉一个Nginx最新版:

docker pull nginx:latest

这条命令会从Docker Hub官方仓库拉取标签为latest的Nginx镜像。如果不写标签,默认也是latest。

几个实用场景:

  • 指定版本: docker pull nginx:1.25.3 —— 我建议生产环境一定要指定版本,别用latest,否则哪天镜像更新了,你的容器可能就炸了。
  • 从私有仓库拉取: docker pull registry.example.com/myapp:v1.0 —— 公司内部一般都有自己的仓库。
  • 拉取时指定平台: docker pull --platform linux/amd64 nginx —— 我在Mac M1上就经常用这个,拉取x86架构的镜像。

小技巧: 拉取大镜像时,可以加个 -q 参数(静默模式),只显示镜像ID,不显示进度条。适合脚本里用。

4.2 查看本地镜像:docker images

拉下来的镜像存在哪?存在本地。怎么查看?用 docker images 或者 docker image ls

docker images

输出大概长这样:

REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 605c77e624dd 2 weeks ago 187MB
ubuntu 22.04 2dc39ba059dc 4 weeks ago 77.8MB
redis 7.2 e4a35914679d 3 weeks ago 117MB

几个常用变体:

  • docker images -a —— 显示所有镜像,包括中间层镜像。嗯,这个我平时用得不多,但排查问题时很有用。
  • docker images --digests —— 显示镜像的摘要(SHA256值),可以用来精确识别镜像版本。
  • docker images --filter "dangling=true" —— 只显示悬空镜像(没有标签的镜像)。这个后面清理时会用到。

我个人习惯: 每周一上班第一件事,就是跑一遍 docker images,看看本地有哪些镜像。时间久了,本地会堆积很多无用的镜像,占磁盘空间。

4.3 镜像的删除与清理

镜像多了怎么办?删呗。但删除有讲究,不能乱删。

4.3.1 删除单个镜像

docker rmi [镜像ID或镜像名:标签]

比如:

docker rmi nginx:latest
docker rmi 605c77e624dd

注意: 如果镜像正在被容器使用,直接删除会报错。得先停掉并删除容器,或者加 -f 强制删除。但我建议别用 -f,容易出问题。

4.3.2 批量删除

有时候想清一批镜像,一个个删太慢了。可以用组合命令:

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

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

警告: docker image prune -a 会删除所有没有被容器使用的镜像。如果你有重要的镜像只是暂时没跑容器,也会被删掉。我建议执行前先确认一下。

更精准的批量删除:

# 删除所有名称为nginx的镜像
docker rmi $(docker images -q nginx)

# 删除所有标签为none的镜像(悬空镜像)
docker rmi $(docker images -f "dangling=true" -q)

我曾经在CI/CD流水线上吃过亏——脚本里用了 docker image prune -a,结果把构建缓存全清了,下次构建慢得要死。后来我改成只清理悬空镜像,问题就解决了。

4.4 镜像的导入导出:docker save/load

有时候网络不好,或者要在离线环境部署,就需要把镜像导出成文件,再导入到另一台机器。

4.4.1 导出镜像:docker save

docker save -o 输出文件名.tar 镜像名:标签

举个例子:

docker save -o nginx.tar nginx:latest

这条命令会把nginx:latest镜像打包成一个tar文件。你可以把这个文件拷贝到U盘、传到内网服务器,随便你。

导出多个镜像:

docker save -o all-images.tar nginx:latest ubuntu:22.04 redis:7.2

4.4.2 导入镜像:docker load

到了目标机器上,怎么恢复?用 docker load

docker load -i nginx.tar

执行完后,用 docker images 就能看到导入的镜像了。

避坑指南: 我曾经遇到过一个问题——导出的tar文件有2GB,但导入后镜像大小只有几百MB。为什么?因为 docker save 保存的是完整镜像层,而 docker images 显示的是压缩后的虚拟大小。别被这个数字吓到,实际占用的磁盘空间就是tar文件的大小。

4.4.3 save/load 与 export/import 的区别

很多人会混淆这两组命令。我简单说一下:

命令 作用对象 保留历史 常用场景
docker save/load 镜像 保留完整层历史 镜像迁移、备份
docker export/import 容器 不保留历史,扁平化 容器快照、最小化镜像

我的建议: 日常镜像迁移,用 save/load 就够了。除非你要把容器里的改动打包成一个新镜像,才考虑 export/import

4.5 实战:镜像管理全流程

最后,我分享一个我常用的镜像管理脚本,你可以参考:

#!/bin/bash
# 镜像管理小工具

# 1. 查看所有镜像
echo "=== 当前本地镜像 ==="
docker images

# 2. 清理悬空镜像
echo "=== 清理悬空镜像 ==="
docker image prune -f

# 3. 导出重要镜像
echo "=== 导出重要镜像 ==="
docker save -o backup-$(date +%Y%m%d).tar nginx:latest ubuntu:22.04

# 4. 显示磁盘占用
echo "=== 磁盘占用 ==="
docker system df

这个脚本我每周跑一次,确保本地镜像不会太乱。你想想看,如果本地堆了几十个没用的镜像,不仅占磁盘,还影响 docker images 的查看效率。

核心要点回顾:

  • docker pull 拉取镜像,记得指定版本标签
  • docker images 查看本地镜像,配合 -f 过滤更高效
  • docker rmi 删除镜像,小心别删了正在用的
  • docker save/load 用于镜像的离线迁移
  • 定期清理悬空镜像,保持本地环境整洁

镜像管理看似简单,但做不好会出大问题。我见过有人把生产环境的镜像误删了,导致回滚失败。也见过有人本地堆了上百个镜像,磁盘爆满。嗯,这些坑我都踩过,希望你看了这一章能少走弯路。