Linux

如何獲取docker容器內主機的掛載資訊

  • April 18, 2019

我需要連接到 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,它仍然給出同樣的錯誤。

我假設您並不嚴格要求對 init 程序(pid 1)可見的掛載,並且對 docker 守護程序可見的掛載就足夠了。通常,它們都應該具有相同的掛載命名空間。

CentOS docker 軟體包的答案

(使用 CentOS 儲存庫中的 docker 1.13.1)

我可以重現您的問題/proc/1/mounts。但是,使用 docker 守護程序的 mounts 文件可以:

$ 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包還存在containerd服務的 SE Linux 上下文的問題:

# 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

使用 CentOSdocker軟體包執行命令時,我收到以下錯誤消息:

$ 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

引用自:https://unix.stackexchange.com/questions/512067