Docker 镜像管理:从拉取到删除,再到分层原理
镜像管理,说白了就是 Docker 的命根子。
你想想看,没有镜像,容器跑什么?我刚开始接触 Docker 那会儿,总觉得镜像就是个“安装包”,拉下来用就完事了。后来线上出过一次事故,才明白这里面门道多着呢。今天咱们就把这块彻底掰开揉碎了讲一遍。
镜像仓库
镜像仓库,就是放镜像的地方,类似于代码的 Git 仓库。
Docker Hub 是最大的公共仓库,官方的 Nginx、Redis、MySQL 都在上面。但我们一般不会直接用,原因很简单:慢,特别慢。
我习惯用国内的加速器,比如阿里云、腾讯云、中科大的镜像站。还有一个方法就是自建仓库,用 Harbor 或者 Registry。
# 登录到一个仓库
docker login registry.example.com
# 登出
docker logout
拉取镜像
拉取镜像是使用 Docker 的起点。
我记得刚带新人时,总有人问我:“为什么我 pull 一个镜像那么慢?”原因很简单——没配加速器。
# 拉取最新版的 Ubuntu 镜像
docker pull ubuntu:latest
# 拉取指定版本的 Nginx
docker pull nginx:1.25.3
# 从私有仓库拉取
docker pull registry.example.com/myapp:v1.0.0
拉取过程其实分几步:
- 你输入
docker pull命令 - Docker 去仓库查这个镜像的 manifest
- 按 manifest 列出的 layer 列表,逐个下载
- 下载完成后解压到本地存储
docker pull 依赖的是 Docker daemon 的网络环境,不是你终端的环境。
查看镜像
拉下来的镜像存在哪里?如何管理?
# 列出本地所有镜像
docker images
# 或者
docker image ls
| 列名 | 含义 |
|---|---|
| REPOSITORY | 镜像来源仓库 |
| TAG | 标签,通常是版本号 |
| IMAGE ID | 镜像唯一标识,只显示前12位 |
| CREATED | 镜像构建时间 |
| SIZE | 镜像大小(注意是逻辑大小) |
还有一个我常用的命令,查看镜像的详细配置:
# 查看镜像的底层信息(JSON格式)
docker inspect nginx:1.25.3
# 只看分层信息
docker history nginx:1.25.3
docker history 这个命令很有用,它能告诉你这个镜像的“家族史”——每一层是谁创建的,做了哪些改动。我在排查镜像体积过大时,第一件事就是看 history,看看哪层引入了无用文件。
删除镜像
镜像越拉越多,磁盘报警了怎么办?删。
# 删除一个镜像
docker rmi nginx:1.25.3
# 按 IMAGE ID 删除
docker rmi abc123def456
# 删除所有未被使用的镜像(谨慎使用)
docker image prune -a
-f 参数强制删除。但我一般不建议强制删,容易出问题。
我见过一个案例:有人为了清理空间,对着一台生产机器执行了 docker image prune -a,结果所有没在运行的容器依赖的镜像全被删了,下次启动容器时重新下载,生生拖慢了上线流程。所以,清镜像之前,先想清楚哪些是真正没用的。
镜像分层原理
这是 Docker 最核心的设计,也是面试高频题。说人话就是:镜像是由一层一层只读文件系统堆叠而成的。
为什么这样做?
- 节省空间:多个镜像可以共享相同的底层。比如 Ubuntu:20.04 和 Ubuntu:22.04,有一部分底层是相同的,不用重复下载。
- 加速构建:Dockerfile 改动了最后几行,只需重新构建上面几层,底层直接拿缓存。
- 便于分发:层是增量更新的,网络传输只传变化的部分。
每一层本质上就是一个 Layer Diff,记录了文件和目录的变更。Docker 把这些层用 UnionFS(联合文件系统)叠加起来,对外呈现为一个完整的文件系统。
下面这张图描绘了镜像的层级结构:
看图就很清晰了:最下面是基础层,往上是操作系统层、运行时库、配置、应用层。最顶上那层是容器可写层,容器运行期间产生的文件改动都写在这里。
写时复制(Copy-on-Write) 是 Docker 的关键机制。容器启动时,所有镜像层保持只读,只有需要修改文件时,Docker 才把文件从底层复制到可写层进行修改。这样既节省空间,又不会污染原始镜像。
RUN,就会产生一层新镜像。所以,我会习惯把多个 RUN apt-get 合并成一个,以减少层数,也减少最终镜像体积。
还有一点你可能不知道:docker pull 下载的是分层压缩包,并不是整个镜像一次下载完。如果你网络中断,Docker 会从断点续传,已经下载好的层不会重新下载。这就是分层的另一个好处。
好了,镜像管理这块,我们核心讲了五件事:仓库、拉取、查看、删除和分层原理。记住这些,你日常用 Docker 就不会出大问题了。