web-dev-qa-db-ja.com

dockerコンテナー内の名前空間内にプライベート/ procをマウントするにはどうすればよいですか?

Dockerコンテナー内に名前空間を作成する必要があります。そして、その一環として、内部の名前空間に/proc privateをマウントする必要があります。これを実現するには、特定の権限でコンテナを実行する必要があることを理解していますが、最小限のセットを有効にすることをお勧めします。

これは機能します:

$ Sudo docker run --privileged --security-opt=seccomp=unconfined \
 -it Fedora:rawhide /usr/bin/unshare -Ufmp -r \
 /bin/sh -c 'mount -t proc proc /proc'

これはしません:

$ Sudo docker run --cap-add=sys_admin --security-opt=seccomp=unconfined \
  -it Fedora:rawhide /usr/bin/unshare -Ufmp -r \
   /bin/sh -c 'mount -t proc proc /proc'
mount: /proc: cannot mount proc read-only.

したがって、seccompフィルターをオフにしてCAP_SYS_ADMINを追加するだけでは十分ではありません。何で十分ですか

更新:Selinuxが問題の一部です。 selinuxの強制をグローバルにオフにすると機能します。ただし、--security-opt label:disableを使用して特定のコンテナの強制をオフにすることもできます。これは オンラインDockerマニュアルのセキュリティ構成セクション に記載されています。

Sudo docker run --cap-add=sys_admin --security-opt label:disable \
 -it Fedora:rawhide /usr/bin/unshare -fmp /bin/sh -c \
 'mount --make-private / ; mount -t proc proc /proc'

ただし、-Uフラグと-rフラグをunshareに追加すると、失敗します。そしてもちろん、--privilegedをdocker runコマンドに追加しても、-Uフラグと-rフラグがあっても問題なく機能します。

私は現在、カーネルトレース機能を使用して、正確に何がEPERMを与えているのかを理解しようとしています。取得するのは非常に役に立たない不特定のエラーです。

6
Omnifarious

このコマンドは機能します:

Sudo docker run --cap-add=sys_admin --security-opt label:disable -it Fedora:rawhide /bin/sh -c 'for dir in $(awk '"'"'/\/proc\// { print $5; }'"'"' /proc/1/mountinfo ); do umount "$dir"; done; /usr/bin/unshare -Ufmp -r /bin/sh -c '"'"'mount --make-private / ; mount -t proc proc /proc ; ls /proc'"'"

引用が非常に重要であるため、複数行に分割しませんでした。基本的に、子ユーザーの名前空間でunshareを実行して/procをマウントする前に、/procにあるすべてのものをマウント解除します。

Dockerは、/proc内の多数のディレクトリとファイルを、空のtmpfsディレクトリとnullファイルである独自のディレクトリでマウントします。 /procのさまざまなファイルは、システム全体に適用できる値を表します。実際、/proc/kcoreを使用すると、ルートである場合にコンテナ内のカーネルメモリを読み取ることができます。これは、多くの人がコンテナが軽量であると信じたいからですVMまたは何か、多くの人を驚かせるでしょう。

カーネル(バージョン4.14以降)fs/namespace.c:mnt_already_visibleは、すでにマウントされているファイルシステムをマウントしているかどうかを確認し、そのファイルシステムに子ファイルシステムとしてマウントされているものがあり、それらのマウントにMNT_LOCKEDフラグがある場合、失敗します。 MNT_LOCKEDフラグがユーザーネームスペースを作成するときはいつでも、すべてのマウントに適用されているようです(これはカーネルのどこにあるか調べていません)。ユーザー名前空間)と非表示のものを再び表示します。

私が投稿したコマンドは、/proc/1/mountinfoの内容にawkスクリプトを使用して、Dockerがマウントした/procのサブディレクトリとファイルをすべて取り出し、それらすべてをアンマウントします。これにより、/procファイルシステムがネストされたユーザー名前空間に再びマウント可能になります。

3
Omnifarious