Appearance
镜像管理
镜像管理处理的事情围绕一条主线:镜像从哪里来、怎么构建、怎么打标签、怎么清理、怎么迁移。容器运行问题里,有一部分其实不是容器问题,而是镜像来源不清楚、标签指向模糊、构建过程不可复现。
镜像的分层
Docker 镜像是分层的。每一层是一次文件系统变更——基础系统、安装依赖、复制应用文件、设置启动命令,各是一层。
镜像层只读,容器运行时在镜像上面加一层可写层。容器里写入的新文件、修改的配置、临时日志都在这一层。删除容器时,可写层通常也随之消失。
查看镜像层信息:
bash
docker history nginx:1.26 # 各层大小和构建指令
docker image inspect nginx:1.26 # 入口命令、架构、环境变量等元数据镜像层多不一定坏,关键是大文件和构建缓存有没有留在最终镜像里。编译工具、包管理缓存、临时压缩包经常是镜像体积大的主要原因。
标签和摘要
镜像名的完整格式:
text
registry.example.com/library/nginx:1.26| 部分 | 说明 |
|---|---|
registry.example.com | 镜像仓库地址,不写默认是 Docker Hub |
library/nginx | 命名空间和镜像名 |
1.26 | 标签 |
标签是人给镜像起的名字,摘要 digest 是镜像内容的哈希。标签可以被重新指向,digest 永远对应同一种内容。
bash
docker pull nginx:1.26
docker image inspect nginx:1.26 --format '{{index .RepoDigests 0}}' # 查看镜像 digest生产发布记录里只写 nginx:latest 基本没有复盘价值。至少记录 镜像名:版本标签,关键服务再补 digest——回滚时能确认拉到的是同一个内容。
同一个镜像 ID 可以有多个标签。删掉一个标签不一定释放磁盘,只有没有容器和任何标签引用时,镜像层才可能被清理。
拉取、打标签和删除
bash
docker pull redis:7.2
docker tag redis:7.2 registry.example.com/base/redis:7.2
docker images registry.example.com/base/redis
docker rmi registry.example.com/base/redis:7.2 # 只删本地标签,不影响远端仓库docker commit——临时保存现场
docker commit 把容器的当前文件系统保存成镜像:
bash
docker run -dit --name debug centos:7 bash
docker exec debug yum install -y net-tools # 容器里临时装排查工具
docker commit debug registry.example.com/tmp/centos-nettools:debugcommit 适合临时保存现场做排查,不适合作为长期构建方式。它不会记录每一步为什么这么改,也很难复现。正式镜像还是写 Dockerfile,把依赖、文件、用户和启动命令放进版本控制。
构建上下文和 .dockerignore
构建时最后那个 . 是构建上下文路径。Docker 会把整个目录发给构建器,目录里无关文件太多时,构建变慢,镜像里也可能误 COPY 进去不该进去的东西。
.dockerignore 用来从构建上下文里排除文件:
dockerignore
# 版本库和本地缓存不需要进入构建上下文
.git
node_modules
*.log
tmp/
# 本地环境文件不要打进镜像
.env.dockerignore 不是安全边界,但能防止误打包。配置密钥、备份包、测试数据这类东西要从构建上下文里排掉。
镜像导入导出
离线环境用 save/load 迁移镜像:
bash
docker pull nginx:1.26
docker save nginx:1.26 -o nginx-1.26.tar # 导出镜像层和标签
docker load -i nginx-1.26.tar # 在离线机器导入
docker images nginxdocker export/import 处理的是容器文件系统,不保留镜像历史和部分元数据。迁移正式镜像用 save/load,不是 export/import。
镜像清理
bash
docker system df # 镜像、容器、volume、构建缓存的磁盘占用
docker system df -v # 更细的逐项查看
docker image prune # 清理没有标签且没有被容器引用的镜像层
docker builder prune # 清理 buildx/buildkit 构建缓存
docker system prune # 清理所有未使用对象docker system prune -a 会清掉所有未被容器引用的镜像,范围很大。生产机器上清理前先看 docker system df 和运行中的容器,避免把回滚需要的镜像删掉。
镜像管理的检查维度
| 方向 | 检查点 |
|---|---|
| 来源 | 官方镜像、内部仓库、维护者、更新时间 |
| 版本 | 标签是否固定,是否记录 digest |
| 构建 | Dockerfile 是否可复现,是否有 .dockerignore |
| 大小 | 构建缓存、包管理缓存、编译工具是否留在最终镜像 |
| 安全 | 是否用 root、是否包含密钥、是否做漏洞扫描 |
| 清理 | 本地镜像、构建缓存、旧标签是否有保留策略 |
镜像管理乱了以后,发布和回滚都会变得含糊。容器跑得再稳,也架不住镜像标签指向不清、构建过程不可复现。