Docker Build与Push底层原理及核心问题详解
Docker Build & Push底层原理详解
很多人都知道docker build用来构建镜像、docker push用来把镜像推送到仓库,但它们底层到底是怎么运行的?咱们结合你给出的Dockerfile来拆解清楚:
FROM alpine:latest RUN touch ~/tmp RUN touch ~/tmp2
你提到的没错,构建这个Dockerfile时,Docker会在/var/lib/docker/overlay2目录下为每一步指令创建增量文件系统层:
- 第一层:包含
alpine:latest完整的文件系统 - 第二层:只包含新增的
~/tmp文件 - 第三层:只包含新增的
~/tmp2文件
接下来针对你的两个核心问题逐一解答:
1. 镜像各层之间的实际关联是什么?是否存在包含所有镜像信息(含排序后的层列表)的json文件?
镜像的各层是通过父层哈希建立关联的,每一层的元数据里都会记录它的父层ID,Docker依靠这个关联关系,就能按顺序把所有层叠加起来,形成完整的镜像文件系统。
而且确实存在这样的JSON文件!Docker会为每个镜像和层生成对应的元数据文件:
- 针对整个镜像,在
/var/lib/docker/image/overlay2/imagedb/content/sha256/目录下,会有一个以镜像ID命名的JSON文件,里面包含排序后的完整层列表、镜像配置信息(比如环境变量、入口命令)、父镜像信息等核心内容。 - 每一层也有自己的元数据文件,存放在
/var/lib/docker/image/overlay2/layerdb/sha256/目录下,记录了该层的父层ID、层哈希值,以及和overlay2文件系统相关的挂载信息。
这些JSON文件就像是镜像的"说明书",Docker通过它们明确该按什么顺序叠加哪些层,以及每个层的具体细节。
2. 执行docker push时,发送到Docker Registry的交付物是什么?是否是类似docker save生成的tar.gz包?
docker push发送的内容和docker save生成的tar包不完全一样,它是更高效的增量推送模式:
- 首先,Docker会先和Registry通信,通过层的哈希值比对,检查哪些层已经存在于Registry中。
- 只推送Registry中没有的层,每个层会被打包成单独的二进制大对象(blob);同时还会推送镜像的清单文件(Manifest)和配置文件(Config):
- 清单文件:记录镜像的所有层哈希、镜像标签、架构信息等,Registry靠它识别镜像的完整组成。
- 配置文件:就是咱们前面提到的包含层列表和镜像配置的JSON文件,Registry需要它来还原镜像的结构。
而docker save是把整个镜像(所有层+元数据)打包成一个tar.gz文件,适合本地备份或迁移,它会一次性打包所有内容,不会做增量检查。
总结来说,docker push是按需推送缺失的层和元数据,比直接推送整个tar包高效得多,尤其是当你推送的镜像和仓库里已有的镜像共享大量层时。
内容的提问来源于stack exchange,提问作者Flo
相关产品推荐
相关产品推荐

