linux - 来自各种 docker 映像的相同文件是否会在 k8s 节点中页面缓存一次?
问题描述
摘自https://docs.docker.com/storage/storagedriver/overlayfs-driver/
页面缓存。OverlayFS 支持页面缓存共享。访问同一文件的多个容器共享该文件的单个页面缓存条目。
这是在分层 docker 镜像的上下文中,多个容器访问同一个镜像。然而,在我的部署中,我可以看到在 Kubernetes 集群的不同但配置相似的节点上运行的相同映像在页面缓存利用率方面非常稳定(及时)差异。两个节点都没有可能导致不同回收率的缓存压力。
所以,我想知道the same file
在上面的摘录中是否可以引用通过哈希验证的“相同性”,并且该文件实际上可能是各种 docker 图像的一部分?
有问题的差异大约为 30-60MB,这与我的容器使用的 python/libgc 库一致。overlayfs
如果公共共享库在页面缓存节点范围内的级别“重复数据删除”,这一切都是有意义的。根据
https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt的第 2.3 段,页面缓存将在首次接触的基础上计入 cgroup
因此,与节点相比,在节点上运行的映像(其他 docker 映像使用相同的 python 库)将显示页面缓存的利用率较低,这些库仅由我的容器使用。
我知道重复数据删除方面有很多想法,例如https://lwn.net/Articles/636943/Y2015:
Chinner 发言描述了这个问题,即一个系统上可能运行着一百个容器,所有容器都基于单个根文件系统的快照。这意味着页面缓存中将有一百个 glibc 副本,因为它们来自具有不同 inode 的不同命名空间,因此不会共享数据。
不,我没有使用 KSM,所以无需提及。我希望有一些对源代码的引用来阐明这种行为。
解决方案
经过进一步调查,很明显,来自不相关容器/pod 的内容在可能存在合理安全风险的节点上共享。
根据https://docs.docker.com/storage/storagedriver/,Dockerfile 中的每一行可以代表 0,1 层或多层。例如,我当前的构建FROM ubuntu
在我的图像中提供了三个基础层:
# docker inspect ubuntu
:
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/22abb0d6b77061cc1e3a04de4d3c83be15e60b87adebf9b7b2fa9adc0fbb0f2d/diff:/var/lib/docker/overlay2/7ab02c0180d53cfa2f444a10650a688c8cebd0368ddb2cea1dba7f01b2008d37/diff:/var/lib/docker/overlay2/3ee0e4ab0518c76376a4023f7c438cc6a8d28121eba9cdbed9440cfc7474204e/diff",
如果我进一步说RUN apt-get -y install python
,docker 将创建一个包含该命令生成的所有文件夹、文件和时间戳的层。该层将是tar
'd 并且 sha256 将从 tar 文件中获取。在上面的 ubuntu 示例中,您可以看到夹层具有 sha256sum:3ee0e4ab0518c76376a4023f7c438cc6a8d28121eba9cdbed9440cfc7474204e
一旦我的镜像由 Kubernetes 集群编排,该层将被膨胀到运行镜像的节点上的标准位置。将创建一个指向图层文件夹的链接 - 链接的唯一原因是缩短路径,如下所述:https ://docs.docker.com/storage/storagedriver/overlayfs-driver/ 。因此,运行从 ubuntu 构建的映像的节点将具有类似于:
# ls -l /var/lib/docker/overlay2/l |grep 3ee0e4ab0518c76
lrwxrwxrwx 1 root root 72 Dec 13 15:40 VGN2ARTYLKI6LQWXSZSMKUQOQL -> ../3ee0e4ab0518c76376a4023f7c438cc6a8d28121eba9cdbed9440cfc7474204e/diff
请注意,这VGN2ARTYLKI6LQWXSZSMKUQOQL
是 a/ 节点唯一和 b/ 节点特定的。这个标识符将出现在容器的挂载中。根 cgroup 可以看到节点上的所有挂载,并且 pid 1 通常属于根 cgroup。所以有问题的层是这样共享的:
# grep `ls -l /var/lib/docker/overlay2/l |grep 3ee0e4ab0518c76 |awk '{print$9}'` /proc/1/mounts
overlay /var/lib/docker/overlay2/84ec5295eb902ab01b37451f9063987f5803a0ff4bc53ee27c1838f783f61f48/merged overlay rw,relatime,lowerdir=
/var/lib/docker/overlay2/l/7RBRYLLCPECAY5IXIQWNNFMT4L:
/var/lib/docker/overlay2/l/LK4X5JGJE327XH6STN6DHMQZUI:
/var/lib/docker/overlay2/l/2RODCFKARIMWO2NUPHVP7HREVF:
/var/lib/docker/overlay2/l/DH43WT4W2DPJTMMKHJL46IPIXM:
/var/lib/docker/overlay2/l/DQBSRPR7QCKCXNT4QQHHC6L2TO:
/var/lib/docker/overlay2/l/N3NL6BAOEKFZYIAXCCFEHMRJC2:
/var/lib/docker/overlay2/l/VGN2ARTYLKI6LQWXSZSMKUQOQL,upperdir=/var/lib/docker/overlay2/84ec5295eb902ab01b37451f9063987f5803a0ff4bc53ee27c1838f783f61f48/diff,workdir=/var/lib/docker/overlay2/84ec5295eb902ab01b37451f9063987f5803a0ff4bc53ee27c1838f783f61f48/work 0 0
overlay /var/lib/docker/overlay2/89ce211716bd81100b99ecacc3c9da7af602029b2724d01db41d5efad37f43e6/merged overlay rw,relatime,lowerdir=
/var/lib/docker/overlay2/l/SQEWZDFCQQX6EKH7IZHSFXKLBN:
/var/lib/docker/overlay2/l/TJFM5IIGAQIKCMA5LDT6X4NUJK:
/var/lib/docker/overlay2/l/DQBSRPR7QCKCXNT4QQHHC6L2TO:
/var/lib/docker/overlay2/l/N3NL6BAOEKFZYIAXCCFEHMRJC2:
/var/lib/docker/overlay2/l/VGN2ARTYLKI6LQWXSZSMKUQOQL,upperdir=/var/lib/docker/overlay2/89ce211716bd81100b99ecacc3c9da7af602029b2724d01db41d5efad37f43e6/diff,workdir=/var/lib/docker/overlay2/89ce211716bd81100b99ecacc3c9da7af602029b2724d01db41d5efad37f43e6/work 0 0
两个覆盖挂载意味着该层在从这个版本的 ubuntu 映像构建的 2 个正在运行的容器之间共享。或者更简洁:
# grep `ls -l /var/lib/docker/overlay2/l |grep 3ee0e4ab0518c76 |awk ‘{print$9}’` /proc/1/mounts |wc -l
2
这证实了内容在不相关的容器之间共享,并解释了我看到的页面缓存利用率的差异。是否存在安全风险?理论上,攻击者可以在 ubuntu 包装器中植入恶意代码,并设计一个产生相同 sha256 的随机数。在实践中是否存在风险?应该不会这么多吧……
推荐阅读
- maven - 将第三方 jar 部署为项目自己构建的 jar?
- android - JSON解析中的Android GSON可能存在错误?
- python - 根据条件从字典中删除键:值对?
- javascript - 如何使用nodejs使代理将流量重定向到最近的集群?
- neo4j - Bolt 协议是否适用于 Traefik?
- java - 启动时服务中的 NoClassDefFoundError。jce_policy-8.zip 是安全的罪魁祸首吗?
- visual-studio-code - VS Code 扩展依赖未安装
- r - R ggplot 将 geom_raster 转换为气泡图
- sql-server - 查询从两个表中获取数据并将它们一起返回
- angular - 是否可以使用 Angular CLI 搭建新环境?