web-dev-qa-db-ja.com

Dockerコンテナー内のホストのマウント情報を取得する方法

Dockerコンテナー内のホストに接続されているすべてのディスクのマウントポイントが必要です。マウント情報は/proc/1/mountsファイルにありますが、すべてのOSでそのファイルにアクセスできるわけではありません。

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を試しましたが、それでも同じエラーが発生します。

3
Akhil Mohan

私は、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_パッケージには、containerdサービスのSE Linuxコンテキストに関する問題があります。

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

_container_runtime_t_ではなく_unconfined_service_t_の型でcontainerdをラベル付けしたい。このためには、_/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
_

これで、上記と同じ手法を使用して、ドッカーコンテナーを開始できます(_dockerd-current_の代わりにdockerdを使用)。

_$ 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
_