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 Community Editionの回答

(外部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 型を使用したいと思います。これを行うには、ラベルを更新する必要があります(container_runtime_tunconfined_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ルールがタイプ'init_t'のターゲットコンテキストを'マウント'するためにタイプ'container_runtime_t'のソースコンテキストを許可しないことを示します。これがコンテキスト/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

おすすめ記事