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_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ルールがタイプ'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