gpt4 book ai didi

Docker 卷挂载 0 大小的文件

转载 作者:行者123 更新时间:2023-12-02 19:21:53 26 4
gpt4 key购买 nike

我正在运行一个 Docker 容器,其卷已安装到 /etc .

我使用以下命令创建容器:

$ docker container run -dt -v volume01:/etc alpine sh
81cf19f2c9ea23d79b900fe8f195fd333df376627710aa78f38f35cf565bfaf0

现在我看到卷目录中的一些文件大小为 0,例如 /etc/hosts文件:
# ls -ltrh /var/lib/docker/volumes/volume01/_data/hosts
-rwxr-xr-x 1 root root 0 26 nov 10:42 /var/lib/docker/volumes/volume01/_data/hosts

这个文件实际上不是空的,如果我检查 /etc/hosts的大小在容器中,它不是 0:
$ docker exec -ti 81cf19f2c9ea ls -lt /etc/hosts
-rw-r--r-- 1 root root 174 Nov 26 09:42 /etc/hosts

知道为什么会这样吗?

提前致谢!

最佳答案

你观察到的是一个非常有趣的效果。为了解释它,让我们来看看一些事实。

首先 :Docker 以非常特殊的方式处理少数文件( /etc/hosts/etc/hostname/etc/resolv.conf ),因为它们包含与网络相关的设置,对于不同的容器应该不同。

Docker 为每个容器生成这些文件并将它们保存在主机系统上。容器的文件系统具有这些文件的绑定(bind)挂载:

$ docker run alpine /bin/sh -c 'mount | grep etc'
/dev/sda1 on /etc/resolv.conf type ext4 (rw,relatime)
/dev/sda1 on /etc/hostname type ext4 (rw,relatime)
/dev/sda1 on /etc/hosts type ext4 (rw,relatime)

第二个 :在执行绑定(bind)挂载之前,Docker 必须确保它们的目标存在(因为内核要求挂载点在挂载时存在)。这种东西在所谓的初始化层中进行配置——一个安装在图像文件系统顶部并包含所需文件的只读层。事实上,Docker 只是删除了文件的原始版本(如果有的话)并在它们的位置创建 empty stubs

要检查这一点,请尝试运行特权容器并 umount(8) 任何这些特殊文件:
$ docker run -it --privileged alpine

/ # cd /etc

/etc # ls -li hosts
3156636 -rw-r--r-- 1 root root 174 Nov 27 09:37 hosts

/etc # umount hosts

/etc # ls -li hosts
3156653 -rwxr-xr-x 1 root root 0 Nov 27 09:37 hosts

第三个 : alpine 图像本身有这些文件,但它们的内容是中性默认值:
$ docker save alpine | tar xO 51667c1dd92cb4d851a7d6413545f5883b758f87251387e70ba531a4562e389f/layer.tar | tar xO etc/hosts
127.0.0.1 localhost localhost.localdomain
::1 localhost localhost.localdomain

因此,镜像文件系统包含这些文件的一个(默认)版本,容器文件系统的最顶层 RO 层(镜像文件系统 + init 层)具有这些文件的第二个(空)版本,而正在运行的容器(镜像文件系统 + 初始化层 + RW 层 + 所有挂载)具有这些文件的第三个版本。

现在,所有这些东西与音量有什么关系?

当您创建和使用非绑定(bind)卷时,Docker 会使用驻留在容器中卷的挂载点的文件填充卷的 _data 目录,即在您的示例中,当您运行
docker container run -dt -v volume01:/etc alpine sh

Docker 将容器的 /etc 复制到 /var/lib/docker/volumes/volume01/_data

问题是:上面讨论的特殊文件的哪个版本被复制了?答案是:来自 init 层的 stub ,因为副本是在从其最顶层创建容器之后执行的,而不是在运行时(当这些文件的“真实”版本被挂载时)。

因此,您在卷中观察到零大小的 /etc/hosts/etc/hostname/etc/resolv.conf ,尽管在运行时它们被这些文件的 Docker 管理版本的绑定(bind)挂载隐藏。

关于Docker 卷挂载 0 大小的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59048477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com