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
を試しましたが、それでも同じエラーが発生します。
私は、initプロセス(pid 1)から見えるマウントが厳密に必要ではなく、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-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
_