Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当docker容器与主机装载的卷一起启动时,磁盘I/O是什么?如何减少它?_Docker_Docker Compose_Docker Volume_Overlayfs - Fatal编程技术网

当docker容器与主机装载的卷一起启动时,磁盘I/O是什么?如何减少它?

当docker容器与主机装载的卷一起启动时,磁盘I/O是什么?如何减少它?,docker,docker-compose,docker-volume,overlayfs,Docker,Docker Compose,Docker Volume,Overlayfs,在RHEL上运行带有主机装载卷的docker容器时,无论是从docker还是从docker compose,我都会在容器启动之前观察到大量磁盘I/O(使用DSAT)。 I/O与dockerd进程相关联,我可以通过装载或删除主机卷来明显增加或减少I/O。 如果我没有装载任何主机卷,容器将立即启动。如果我装载的卷覆盖了文件系统的很大一部分,那么I/O是非常重要的,在我的例子中,大约20 Gb,在容器启动之前大约需要三分钟。在某些情况下,这会导致docker compose up编排超时 典型的run

在RHEL上运行带有主机装载卷的docker容器时,无论是从
docker
还是从
docker compose
,我都会在容器启动之前观察到大量磁盘I/O(使用
DSAT
)。 I/O与
dockerd
进程相关联,我可以通过装载或删除主机卷来明显增加或减少I/O。 如果我没有装载任何主机卷,容器将立即启动。如果我装载的卷覆盖了文件系统的很大一部分,那么I/O是非常重要的,在我的例子中,大约20 Gb,在容器启动之前大约需要三分钟。在某些情况下,这会导致
docker compose up
编排超时

典型的run命令如下所示

docker run -it --rm --name my_container \
-v /host/app/src:/app:ro,z \                         # host volume defined here
-v my_ro_data:/data/read_only/files:ro,z \           # external named volume
-v /host/data/write:/data/container_output/files:z \ # another host volume
my/image:latest

无论卷是否是预定义的命名卷,也不管是否使用语法将其标记为只读,都会发生I/O。 但在定义外部命名卷时,如下所示:

docker volume create \
--driver local \
--opt type=none \
--opt o=bind \
--opt device=/host/data/files \
my_ro_data
我假设I/O与覆盖文件系统有关,但我找不到任何明确的解释,说明到底在写什么,在哪里写,以及如何优化配置,以便在容器启动之前需要更少的I/O。它显然不是整卷的内容,所以它似乎是某种差异?但是,假设我有某种大规模的数据管道,我想将容器指向主机源目录或目标目录,其中包含TB级的文件…如何装载主机卷而对容器启动延迟的影响较小

更新: 根据@BMitch的指导,我将重点放在与SELinux相关的
“:z”
标签上

简史: 最初(发布前一年左右),如果没有此标签,RHEL w/SELinux服务器上的docker容器无法访问装载的卷。尽管
--volumes from
是一个不同的cli选项,但它提供了解决访问问题时其他来源引用的最佳解释:

像SELinux这样的标签系统要求在标签上放置正确的标签 卷内容装入容器中。如果没有标签,安全性 系统可能会阻止容器内运行的进程 使用内容。默认情况下,Docker不会更改标签集 由操作系统提供。要更改容器上下文中的标签,可以添加 卷装载的两个后缀:z或:z中的任意一个。这些后缀 告诉Docker重新标记共享卷上的文件对象。z 选项告诉Docker两个容器共享卷内容。作为一个 结果,Docker使用共享内容标签标记内容。共享 卷标允许所有容器读取/写入内容。Z选项 告诉Docker使用私有非共享标签标记内容

此说明附有警告:其中:

使用Z绑定挂载系统目录,如/home或/usr 选项使主机无法运行,您可能需要 手动重新标记主机文件

所以我使用了
“:z”
,有时使用
”:ro,z”
,一切都很好

事实证明,这个标签导致了预启动磁盘I/O。我不太了解SELinux安全性和标签,但我认为I/O实际上是在装入卷时更改文件标签,因此文件越多,磁盘I/O越长

我的观察是,移除标签,而不做其他事情,会导致相同的行为。这意味着docker引擎现在的默认行为是将SELinux装入的卷视为标签为
“:z”
。我相信这是一种新的行为,可能是在过去一年中引入的……或者其他一些系统更改……因为现在卷可以在没有标签的情况下访问(或者标签是永久性的,允许后续docker访问)

但是,删除
:z
并不能解决I/O和长启动时间的问题。然后,我找到了哪些声明:z和:z都是潜在危险的选择,并给出了一条评论:

如果您的容器确实需要更广泛地访问系统目录, 然后在“docker run”中使用“--security opt label:disable” 命令是更好的选择。请注意,使用上述选项 相反,将禁用该容器的SELinux检查

所以我添加了这个选项,事实上,卷是可访问的,并且没有(或最小)磁盘I/O和启动延迟


也就是说,我真的不理解
--安全选项标签:禁用
的影响,并欢迎任何其他建议或解释。

有几种可能性,根据您的问题不清楚是哪种

如果它是覆盖文件系统,那将是意外的,因为没有文件复制来设置它。这也不能反映您的描述,因为它只发生在卷上,并且每个容器都有一个覆盖文件系统(假设图形驱动程序设置为覆盖)

对于无根docker守护进程(dockerd不是以根运行的),您可以看到图形驱动程序切换到本机,这确实意味着它为每个层和容器复制映像文件系统,这非常昂贵。但你们都会注意到这一点,因为使用了大量的磁盘空间,而且在没有卷的情况下也会发生这种情况

对于命名卷,当该卷为空且使用命名卷创建容器时,docker将使用映像的内容初始化命名卷。这包括所有文件、权限、所有权和其他元数据。当命名卷已经有数据时,将跳过此初始化步骤,并且主机卷不会发生此操作

如果您的问题特定于主机卷,那么我唯一能想到的就是在卷上使用“z”选项设置selinux标签。否则,命名卷和主机卷都是defa的Linux绑定装载