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用于镜像的离线迁移- 定期清理悬空镜像,保持本地环境整洁
镜像管理看似简单,但做不好会出大问题。我见过有人把生产环境的镜像误删了,导致回滚失败。也见过有人本地堆了上百个镜像,磁盘爆满。嗯,这些坑我都踩过,希望你看了这一章能少走弯路。