K8S随笔 – overlay2容器分层原理

这篇博客简单分析一下docker的镜像分层存储的具体表现,以便有更加具体的认识。

基本概念

docker镜像是分层存储的,每一层包含了一些文件变动,靠上的层覆盖靠下层的同名文件,最后可以通过overlay2这种层叠文件系统把所有层的文件挂载到一个目录下。

镜像中的层都是read only的,在容器启动时会创建一个rw层覆盖在最上面,这样容器运行时就可以写数据到文件系统中了。

为了观察分层的原理,我通过docker下载一个centos镜像并分析只读层之间关系,然后启动一个容器观察可写层的创建。

下载镜像

我们下载centos:latest镜像:

查看镜像分层

然后看到了这样一段配置:

观察到3个Dir(先不用关心3个目录的含义)的父目录都是/data/docker/overlay2/223b0272cae907658e7da0cf4abe1642e3ee837a87fce1a32c4c9410523137e1,其实这就是centos镜像的最上层了。

里面包含了:

层的diff

每一层的变化的内容都放在diff目录下,我们查看一下centos最上层的内容:

这一层就是rootfs,每个linux系统都会包含这么一系列文件。

层的link

在该层目录下还有一个link文件,它的内容是该层223b0272cae907658e7da0cf4abe1642e3ee837a87fce1a32c4c9410523137e1的短名称:

根据短名称也可以找到该层,通过这样的路径:

可以看出,实际就是用短名称做了一个软链到该层的diff目录,也就是该层的内容。

据说用短名称是为了在最终mount overlay2层叠文件系统的时候节约资源之类的。

整个centos镜像只有一层,没有下层。

启动容器

接下来,我们拉起一个容器,以便观察docker创建的运行时rw层。

然后查看这个容器的配置:

然后看到这段信息:

这就是容器的rw层了,看一下里面包含什么:

接下来分析一下这几个目录。

层的lower

这是第一次出现,它记录了这一层下面有哪些层,这就是层叠的含义。

内容被:分割,每一部分是一个相对路径,指向了短名称软链接:

所以,当前层的下方有2个lower层(更低的层),这就是docker维护层关系的方式。

最低的那一层(223b0272cae907658e7da0cf4abe1642e3ee837a87fce1a32c4c9410523137e1)我们刚才说过,就是centos那一层,是rootfs。

那么81f38570d455c3b2152356ff8e02543009d8a6fae7f8b170a85a71b64a8991d7层是什么呢?它还是一个只读层,是容器启动时临时加的,我们看一下这一层的内容:

看样是一些为了运行容器而做的一层,叫做init层。

层的merged

rw层、init层、centos层一起被mount到merged目录,这就是层叠文件系统了,在里面可以看到所有这些层的文件。

我们看一下rw层的merged是什么:

可见,在overlay2 mount后可以看到下面rootfs的内容。

查看mount信息:

没错,该merged目录是一个overlay2的层叠文件系统,允许rw:

overlay on /data/docker/overlay2/81f38570d455c3b2152356ff8e02543009d8a6fae7f8b170a85a71b64a8991d7/merged type overlay (rw,relatime

它的下层是init和centos的只读层:

lowerdir=/data/docker/overlay2/l/5Z3QZHBNV2KRF7ZVVPN4JBPYLT:/data/docker/overlay2/l/NC5JBAXHT46SPZA2HYLEGFGXFB

最高层是rw层:

upperdir=/data/docker/overlay2/81f38570d455c3b2152356ff8e02543009d8a6fae7f8b170a85a71b64a8991d7/diff

在容器内创建一个文件:

然后观察rw层发生了变化:

完~

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~