私はコンテナ化のメカニズムを研究しています。 マニュアルページ ユーザー名前空間の状態: "各プロセスは正確に1つのユーザー名前空間のメンバーです。"
私もフォローしようとしています この記事 作成者は次のように述べています: "ユーザー名前空間では、ユーザー名前空間1のプロセスのUIDをUIDユーザー名前空間2 "の同じプロセス
上記の2つのステートメントは矛盾しているようです。同じプロセスを複数のユーザー名前空間の一部にすることはできますか?プロセス、UID、およびユーザー名前空間の間の関係は何ですか?いくつかのグラフィカルな説明をいただければ幸いです。
明らかな矛盾は、記事内のユーザー名前空間階層の省略に起因します。マンページの引用:
ユーザーの名前空間はネストできます。つまり、各ユーザー名前空間(初期(「ルート」)名前空間を除く)には親ユーザー名前空間があり、0個以上の子ユーザー名前空間を持つことができます。親ユーザー名前空間は、
unshare(2)
またはclone(2)
の呼び出しを介してユーザー名前空間を作成するプロセスのユーザー名前空間です。CLONE_NEWUSER
フラグ。
この記事では、プロセスDはユーザー名前空間2の一部であり、ユーザー名前空間1内にネストされています。単一のプロセスは単一のユーザー名前空間に属していますが、そのユーザー名前空間は、ルート名前空間までの連続する親内にネストされています。 。
プロセスは、複数のユーザー名前空間から表示できます。特に、すべてのプロセスは、最上位のユーザー名前空間から(または、必要に応じて、すべてのユーザー名前空間の外部から)表示されます。プロセスにアタッチされたユーザーIDは、クエリ元のユーザー名前空間、各ユーザー名前空間で使用されているuid/gidマップに応じて値が変化します。これが、この記事が作成しようとしているポイントです。
これは、たとえばbash
を実行しているルートレスコンテナを起動することで確認できます。コンテナ内のps
が表示されます
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.3 0.0 12024 3196 pts/0 Ss 13:49 0:00 /bin/bash
ただし、samebash
プロセスは次のように表示されます
skitt 23345 0.0 0.0 12024 3208 pts/0 Ss+ 15:49 0:00 /bin/bash
コンテナの外。 /proc/.../uid_map
は、使用中のuidマップを示しています。
$ cat /proc/23345/uid_map
0 1000 1
1 624288 65536
これは、0から0insideのuidの「範囲」が、クエリを実行したユーザー名前空間の1000にマップされ、1から65536の範囲がマップされることを意味します。から624288–689823。
多くの頭痛の種の後、私はいくつかの答えがあると思います。すべてのプロセスは確かに正確に1つのユーザー名前空間( ここで確認 )、 記事の画像)の一部です それを正確に描写します。 initとは別に、プロセスは他のプロセスによって作成されます。プロセスが子プロセスを作成するとき、子を新しいユーザー名前空間に割り当てるオプションがあります。これは、親プロセスのユーザー名前空間の「子名前空間」とも呼ばれます。
いわゆるUID(ユーザーID)とGID(グループID)マッピングにより、プロセスのUIDとGIDをにすることができます。 )appear別の名前空間から調べると異なります。プロセスは、たとえば、他の名前空間のプロセスがアクセスするシステム上のファイルを変更する可能性があり、名前空間の外部からそれらのファイルの意味のあるUIDまたはGIDを確認する必要があるため、マッピングは重要です。
マッピングUID(GIDでも同じ)は、新しい名前空間を作成しているプロセスのUIDを取得し、それを/proc/<Process_ID>/uid_map
と照合して、新しい名前空間の新しいプロセスにマップされたUIDを割り当てることで機能します。新しいユーザー名前空間の作成時にマッピングが指定されていない場合、新しい名前空間のプロセスUIDは/proc/sys/kernel/overflowuid
の値を取ります。このようなマッピングを定義する方法の詳細については、 このLWN記事 。