如何获取docker容器内主机的挂载信息

如何获取docker容器内主机的挂载信息

我需要连接到 docker 容器内主机的所有磁盘的安装点。挂载信息在文件中可用/proc/1/mounts,但我无法在所有操作系统上访问该文件。

当我在 Ubuntu 上运行以下命令时,它工作正常。

docker run -it -v /proc/1/mounts:/tmp/mounts ubuntu:16.04

但在启用了 SELinux 的 CentOS 上,我无法挂载/proc/1/mounts文件。就会permission denied报错。

我也尝试过/etc/mtab,但由于它是 的符号链接/proc/self/mounts,因此内容将在 docker 容器内发生变化。

除了 之外,是否还有其他方法来获取主机的挂载信息/proc/1/mounts,或者应该使用特定的 SELinux 标签?

我尝试使用docker run -it --privileged -v /proc/1/mounts:/tmp/mounts ubuntu:16.04,但它仍然给出相同的错误。

答案1

我假设您并不严格要求 init 进程 (pid 1) 可见的安装并且 docker 守护进程可见的安装就足够了。通常,它们应该具有相同的挂载命名空间。

CentOS docker 软件包的答案

(使用 CentOS 存储库中的 docker 1.13.1)

我可以用 重现你的问题/proc/1/mounts。但是,使用 docker 守护进程的挂载文件可以:

$ docker run -it -v /proc/$(pidof dockerd-current)/mounts:/tmp/mounts ubuntu:16.04

在docker容器中,/tmp/mounts然后列出主机的挂载。

Docker 社区版的答案

(使用外部 docker-ce 18.09.5 包如此处所述

除了上面解释的问题之外,该docker-ce包还存在服务的 SE Linux 上下文问题containerd

# ps xZ | grep containerd
system_u:system_r:unconfined_service_t:s0 5695 ? Ssl   0:00 /usr/bin/containerd
...

我们希望containerd 用 typecontainer_runtime_t而不是来标记unconfined_service_t。为此,/usr/bin/containerd必须更新标签(一般参考):

# ls -Z /usr/bin/dockerd-ce 
-rwxr-xr-x. root root system_u:object_r:container_runtime_exec_t:s0 /usr/bin/dockerd-ce
# ls -Z /usr/bin/containerd
-rwxr-xr-x. root root system_u:object_r:bin_t:s0       /usr/bin/containerd
# semanage fcontext -a -t container_runtime_exec_t /usr/bin/containerd
# restorecon /usr/bin/containerd
# ls -Z /usr/bin/containerd
-rwxr-xr-x. root root system_u:object_r:container_runtime_exec_t:s0 /usr/bin/containerd

接下来,重新启动containerd守护进程:

# systemctl daemon-reload
# systemctl restart containerd
# ps xZ | grep containerd
system_u:system_r:container_runtime_t:s0 6557 ? Ssl   0:00 /usr/bin/containerd

现在,可以使用与上面相同的技术来启动 docker 容器(使用dockerd代替dockerd-current):

$ docker run -it -v /proc/$(pidof dockerd)/mounts:/tmp/mounts ubuntu:16.04

背景资料

我在 CentOS Linux 版本 7.6.1810 上对此进行了测试。

您可以验证 init 和 docker 守护进程是否具有相同的挂载命名空间(即它们的 /proc/[pid]/mounts 将显示相同的挂载):

# readlink /proc/1/ns/mnt /proc/$(pidof dockerd-current)/ns/mnt
mnt:[4026531840]
mnt:[4026531840]

我还验证了 SE Linux 已启用:

# getenforce
Enforcing

当使用 CentOS 软件包运行命令时,docker我收到以下错误消息:

$ docker run -it -v /proc/1/mounts:/tmp/mounts ubuntu:16.04
/usr/bin/docker-current: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "container init exited prematurely".

此外,在 中/var/log/audit/audit.log,我看到以下 AVC 违规:

type=AVC msg=audit(1555530383.707:214): avc:  denied  { mounton } for  pid=5691 comm="runc:[2:INIT]" path="/var/lib/docker/overlay2/8944062749f8ad19c3ff600e1d5286315227378174b95a952e7b0530927f4dcd/merged/tmp/mounts" dev="proc" ino=45422 scontext=system_u:system_r:container_runtime_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=file permissive=0

这告诉我们,SE Linux 规则不允许类型为“container_runtime_t”的源上下文对“init_t”类型的目标上下文执行“mounton”操作。您可以验证这是 的上下文/proc/1/mounts,而 的上下文/proc/$(pidof dockerd-current)/mounts匹配:

# ls -Z /proc/1/mounts /proc/$(pidof dockerd-current)/mounts
-r--r--r--. root root system_u:system_r:init_t:s0      /proc/1/mounts
-r--r--r--. root root system_u:system_r:container_runtime_t:s0 /proc/5476/mounts

相关内容