AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 671259
Accepted
Philip Couling
Philip Couling
Asked: 2021-10-01 03:12:06 +0800 CST2021-10-01 03:12:06 +0800 CST 2021-10-01 03:12:06 +0800 CST

docker容器是否为从同一层映射但不同图像的文件内存共享RAM?

  • 772

我不能 100% 确定这是 U&L 问题还是SO问题。总的来说,我将它发布在 U&L 上,因为它与操作系统相关。

背景

据我所知,Linux 将通过将共享库(.so 文件)映射为写时复制来加载共享库(.so 文件)。这样做的一个优点是,共享同一个大型库的多个进程都将共享相同的物理 RAM,用于该库的大部分内容。

Docker 不一定会发生这种情况,因为进程在基于“映像”的自己的“容器”中运行,并且每个映像都包含它自己的共享库副本。这是故意的。它允许程序附带它们自己的依赖项(库),这些依赖项可能与系统上已安装的库有很大不同。

因此,在 docker 主机上本地运行的程序不会与在 docker 容器中运行的程序共享相同的库内存,因为 docker 容器中的程序已映射到库的不同副本。

Docker 层解释

Docker 镜像是分层创建的。每一层都添加到较低的一层,有时会覆盖现有文件。并非每个文件都在每一层中更改。

Docker 允许您通过向旧图像添加新层来创建新图像。发生这种情况时,您最终会得到多个共享相同图层的图像。这些图像共享一些相同文件的相同副本。

Docker 将这些层分开保存,至少在运行时之前是这样。例如:从 Docker Hub 拉取图像,Docker 通过获取每个图像的组成层来获取图像。它只获取它还没有的层。

我不知道的

在创建或运行容器时,Docker 必须将这些层组装成一个单一的连贯文件系统。我不知道它是怎么做到的。它可能:

  • 将文件复制到一个地方
  • 在一处创建硬链接
  • 使用覆盖文件系统

根据它的作用,源自同一层的文件可能是相同的副本,或者它们可能是文件系统上的完全相同的文件。

这最终会影响文件被多个进程映射到内存时发生的情况。

我真正想发现什么?

我想知道从两个不同的图像运行两个容器是否会为源自单个层的单个共享库共享相同的 RAM。

docker mmap
  • 1 1 个回答
  • 736 Views

1 个回答

  • Voted
  1. Best Answer
    Stephen Kitt
    2021-10-01T03:44:21+08:002021-10-01T03:44:21+08:00

    至少在某些配置中,是的,容器可以共享不同映像中同一层中的文件的内存映射。

    这是一个实验来证明这一点。我正在使用两个不同的图像,一个基于另一个:

    $ docker history 5f35156022ae
    IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
    5f35156022ae   7 weeks ago    COPY scripts/shared/ . # buildkit               1.05MB    buildkit.dockerfile.v0
    <missing>      7 weeks ago    WORKDIR /opt/shipyard/scripts                   0B        buildkit.dockerfile.v0
    ...
    
    $ docker history 569bf4207a08
    IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
    569bf4207a08   7 weeks ago    /bin/sh -c #(nop)  CMD ["sh"]                   0B        
    ed9510deb54e   7 weeks ago    /bin/sh -c #(nop)  ENTRYPOINT ["/opt/shipyar…   0B        
    c3e0351f0dd2   7 weeks ago    /bin/sh -c #(nop) WORKDIR /go/src/github.com…   0B        
    a476f9f2b118   7 weeks ago    /bin/sh -c #(nop)  ENV DAPPER_OUTPUT=/go/src…   0B        
    29a76c4ff3e7   7 weeks ago    /bin/sh -c #(nop)  ENV DAPPER_ENV=QUAY_USERN…   0B        
    2f4a590d61ef   7 weeks ago    /bin/sh -c #(nop)  ARG PROJECT                  0B        
    5f35156022ae   7 weeks ago    COPY scripts/shared/ . # buildkit               1.05MB    buildkit.dockerfile.v0
    <missing>      7 weeks ago    WORKDIR /opt/shipyard/scripts                   0B        buildkit.dockerfile.v0
    ...
    

    我启动了两个容器,仅使用入口点 shell:

    $ pstree -p
    ...
               ├─containerd-shim(530457)─┬─bash(530477)
               │                         ├─{containerd-shim}(530458)
    ...
               ├─containerd-shim(530622)─┬─entry(530643)───sh(530685)
               │                         ├─{containerd-shim}(530624)
    ...
    

    让我们检查一下这两个 shell 使用的 C 库:

    $ sudo grep libc-2.33 /proc/{530477,530685}/maps
    /proc/530477/maps:7fc127f81000-7fc127fa7000 r--p 00000000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530477/maps:7fc127fa7000-7fc1280f4000 r-xp 00026000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530477/maps:7fc1280f4000-7fc128140000 r--p 00173000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530477/maps:7fc128140000-7fc128141000 ---p 001bf000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530477/maps:7fc128141000-7fc128144000 r--p 001bf000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530477/maps:7fc128144000-7fc128147000 rw-p 001c2000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530685/maps:7f6a5df94000-7f6a5dfba000 r--p 00000000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530685/maps:7f6a5dfba000-7f6a5e107000 r-xp 00026000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530685/maps:7f6a5e107000-7f6a5e153000 r--p 00173000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530685/maps:7f6a5e153000-7f6a5e154000 ---p 001bf000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530685/maps:7f6a5e154000-7f6a5e157000 r--p 001bf000 00:1f 3117                       /usr/lib64/libc-2.33.so
    /proc/530685/maps:7f6a5e157000-7f6a5e15a000 rw-p 001c2000 00:1f 3117                       /usr/lib64/libc-2.33.so
    

    两个映射库具有相同的设备和 inode,因此它们是同一个文件,并且它们的映射将在可能的情况下共享。

    • 2

相关问题

  • 无法从私有注册表中提取 kubernetes 中的图像

  • 连接到 docker 主机!

  • Dockerfile 中 VOLUME 指令的目的是什么?

  • 如何在 RHEL 7 上离线安装 docker?

  • 我只需要运行这个脚本文件一次吗?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve