【问题标题】:How to list Docker mounted volumes from within the container如何从容器中列出 Docker 挂载的卷
【发布时间】:2015-08-19 00:08:32
【问题描述】:

我想列出所有挂载卷的容器目录。

即能够获得我从中获得的类似信息

docker inspect --format "{{ .Volumes }}" <self>

但是在容器内并且没有在其中安装docker

我尝试了cat /proc/mounts,但找不到合适的过滤器。

【问题讨论】:

  • 尝试将-v /var/run/docker.sock:/var/run/docker.sock的绑定挂载添加到您的docker run command
  • 实际上没有任何方法可以从容器中识别 Docker 卷挂载(不暴露对 Docker api 的访问权限)。
  • 您可以“作弊”并在您的docker run 命令中添加一个环境变量列表--env-file=[] Read in a file of environment variables(来自文档docs.docker.com/reference/commandline/cli/#run),但是您将它提供给您的容器,您的容器没有发现它
  • 为什么? Docker 的全部意义在于存储卷、网络端口和容器链接是从容器化应用程序中抽象出来的。这就是使 Docker 容器具有可移植性的原因。
  • 没有完美的抽象,有时你只需要做一些自定义的事情。在这种情况下,我想修复所有共享卷的权限,因为这个问题仍然存在:Make uid & gid configurable 并且这个想法来自Hamy community wiki 我的代码:github.com/elgalu/docker-selenium/blob/…

标签: docker mount inspect


【解决方案1】:

(编辑 - 这可能不再适用于 Mac)如果您的 Docker 主机是 OS X,则安装的卷将为 osxfs(或 fuse.osxfs)类型。你可以运行一个

mount | grep osxfs | awk '{print $3}'

并获取所有已安装卷的列表。

如果您的 Docker 主机是 Linux(至少 Ubuntu 14+,也许还有其他),卷似乎都在 /dev 上,但不在容器的 /dev 文件系统中的设备上。这些卷将与/etc/resolv.conf/etc/hostname/etc/hosts 并列。如果你做一个mount | grep ^/dev 启动,然后过滤掉ls /dev/* 中的任何文件,然后过滤掉上面列出的三个文件,你应该留下主机卷。

mount | grep ^/dev/ | grep -v /etc | awk '{print $3}'

我的猜测是,具体情况可能因 Linux 不同而异。不理想,但至少可以弄清楚。

【讨论】:

  • 适用于我的 Ubuntu 主机和来宾。这是我需要的。谢谢!
  • 在发布答案时这可能是正确的,但从那以后情况似乎发生了变化:在 macOS 10.14 Mojave 上运行 Docker 并且一个示例容器内的所有挂载都不是@987654330 类型@:mount | sed -E -e 's|.*type ([^ ]+).*|\1|g' | sort | uniq | xargs 打印 cgroup devpts ext4 mqueue overlay proc sysfs tmpfs
  • @ssc 我没有任何方法可以验证,所以我会接受你的话。
【解决方案2】:

假设您想检查 从基于 linux 的容器中安装了哪些卷,您可以在 /etc/mtab 中查找以“/dev”开头的条目,删除 /etc 条目

$ grep "^/dev" /etc/mtab | grep -v " \/etc/"

/dev/nvme0n1p1 /var/www/site1 ext4 rw,relatime,discard,data=ordered 0 0
/dev/nvme0n1p1 /var/www/site2 ext4 rw,relatime,discard,data=ordered 0 0

【讨论】:

    【解决方案3】:

    您可以从您拥有的许多 cmets 中了解到,容器最初只不过是资源的受限、保留部分,与您的计算机的其余部分完全隔离开来。它不知道自己是 Docker,并且在容器内一切都表现得好像它是一台单独的机器。我猜有点像矩阵;)

    您可以访问主机的内核及其资源,但又一次被限制为仅被过滤掉的集合。这是通过 Unix/Linux 内核附带的令人敬畏的“cgroups”功能完成的。

    现在好消息:您可以通过多种方式向 Docker 提供信息,但您必须自己提供和构建这些信息。

    最简单最有效的方法是将位于主机上/var/run/docker.sock 的 Unix 套接字挂载到容器内部的同一位置。这样,当您在容器中使用 Docker 客户端时,您就是直接与主机上的 docker 引擎对话。

    然而,权力越大,责任越大。这是一个不错的设置,但不是很安全。一旦有人设法进入您的 docker,它就可以通过这种方式访问​​您的主机系统。

    更好的方法是通过环境设置提供挂载列表,或者坚持一些虚构的约定来预测挂载。

    (你是否意识到有一个用于挂载的参数,为你的 Docker 内部的挂载提供一个别名?)

    【讨论】:

      【解决方案4】:

      docker exec 命令可能就是你要找的。​​p>

      这将允许您在现有容器中运行任意命令。

      例如:

      docker exec -it <mycontainer> bash
      

      当然,您运行的任何命令都必须存在于容器文件系统中。

      #docker  cp  >>>> Copy files/folders between a container and the local filesystem
      docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
      docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
      

      复制整个文件夹:

      docker cp ./src/build b081dbbb679b:/usr/share/nginx/html
      

      注意——这将复制容器的…/nginx/html/目录中的构建目录以仅复制文件夹中存在的文件:

      docker cp ./src/build/ b081dbbb679b:/usr/share/nginx/html
      

      注意 - 这将复制容器的 …./nginx/html/ directory 中的构建目录的内容

      Docker 存储选项:

      卷存储在由 Docker 管理的主机文件系统的一部分(Linux 上的 /var/lib/docker/volumes/)。非 Docker 进程不应修改文件系统的这一部分。卷是在 Docker 中持久化数据的最佳方式。

      创建卷时,它会存储在 Docker 主机上的目录中。当您将卷挂载到容器中时,此目录就是挂载到容器中的目录。这类似于绑定挂载的工作方式,只是卷由 Docker 管理并且与主机的核心功能隔离。

      一个给定的卷可以同时挂载到多个容器中。当没有正在运行的容器使用卷时,卷仍然可供 Docker 使用,并且不会自动删除。您可以使用 docker volume prune 删除未使用的卷。

      当您挂载一个卷时,它可能是命名的或匿名的。匿名卷在首次挂载到容器时没有明确的名称,因此 Docker 为它们提供了一个随机名称,该名称保证在给定的 Docker 主机中是唯一的。除了名称之外,命名卷和匿名卷的行为方式相同。

      卷还支持使用卷驱动程序,它允许您将数据存储在远程主机或云提供商上,以及其他可能性。

      绑定挂载可以存储在主机系统的任何位置。它们甚至可能是重要的系统文件或目录。 Docker 主机或 Docker 容器上的非 Docker 进程可以随时修改它们。 从 Docker 早期就可用。与卷相比,绑定挂载的功能有限。当您使用绑定挂载时,主机上的文件或目录会挂载到容器中。文件或目录由其在主机上的完整路径引用。该文件或目录不需要已经存在于 Docker 主机上。如果它尚不存在,则按需创建。绑定挂载非常高效,但它们依赖于具有特定目录结构的主机文件系统。如果您正在开发新的 Docker 应用程序,请考虑改用命名卷。您不能使用 Docker CLI 命令直接管理绑定挂载。

      使用绑定挂载的一个副作用是,无论好坏,您都可以通过容器中运行的进程更改主机文件系统,包括创建、修改或删除重要的系统文件或目录。这是一种强大的能力,可能会产生安全隐患,包括影响主机系统上的非 Docker 进程。

      tmpfs 挂载仅存储在主机系统的内存中,永远不会写入主机系统的文件系统。

      tmpfs 挂载不会持久保存在磁盘上,无论是在 Docker 主机上还是在容器内。它可以在容器的生命周期内被容器使用,用于存储非持久状态或敏感信息。例如,在内部,swarm 服务使用 tmpfs 挂载将秘密挂载到服务的容器中。

      如果你需要指定卷驱动选项,你必须使用--mount。 -v 或 --volume:由三个字段组成,以冒号字符 (:) 分隔。字段必须按正确的顺序排列,每个字段的含义不是很明显。 o 在命名卷的情况下,第一个字段是卷的名称,并且在给定的主机上是唯一的。对于匿名卷,省略第一个字段。 o 第二个字段是文件或目录将在容器中挂载的路径。 o 第三个字段是可选的,是以逗号分隔的选项列表,例如 ro。这些选项将在下面讨论。 • --mount:由多个键值对组成,以逗号分隔,每个都包含一个= 元组。 --mount 语法比 -v 或 --volume 更冗长,但键的顺序并不重要,标志的值更容易理解。 o 挂载类型,可以是 bind、volume 或 tmpfs。本主题讨论卷,因此类型始终为卷。 o 坐骑的来源。对于命名卷,这是卷的名称。对于匿名卷,此字段被省略。可以指定为 source 或 src。 o 目标将文件或目录安装在容器中的路径作为其值。可以指定为目的地、dst 或目标。 o readonly 选项(如果存在)会导致绑定挂载以只读方式挂载到容器中。 o 可以多次指定的volume-opt 选项采用由选项名称及其值组成的键值对。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-14
        • 2017-07-21
        • 2021-01-13
        • 1970-01-01
        • 2017-04-15
        • 2021-09-17
        • 2019-12-10
        相关资源
        最近更新 更多