当docker容器与主机装载的卷一起启动时,磁盘I/O是什么?如何减少它?
在RHEL上运行带有主机装载卷的docker容器时,无论是从当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
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绑定装载