インストールする

インストールする

私はLinuxコンテナの内部の仕組みを理解しようとしています。私が学んだことの1つは、特別なフラグを渡してシェルをコンテナ化できることです。フラグの1つはPID用です。

psただし、これはまだホストとコンテナのすべてのプロセスを表示するため、コマンドに望ましい効果はありません。これはpsディレクトリからの読み込みによるものです。/proc

コンテナで実行されているプロセスのみを表示する方法の1つpsは、偽のルートファイルシステム(オペレーティングシステムのディレクトリ/ユーティリティのみを含む)としてルートを指定し、ホストディレクトリを/proc偽のfsのprocディレクトリにマウントすることです。

私はこれが実際になぜ動作するのか理解していません。/procディレクトリを別のマウントポイントにマウントすると、コンテナ化されたかのように動作するのはなぜですか?

Dockerのようなコンテナが正しく機能するために偽のルートファイルシステムが必要なのはなぜですか?

私は何を逃したことがありませんか?

私が説明する技術はこの動画DockerConで。

メソッドが完了する正確な時刻へのリンクを設定しました。

答え1

そのunshareコマンドについて話していると仮定すると、解決策は--mount-procマウントネームスペースを共有解除し、/proc新しいpidネームスペースを参照する新しいネームスペースをマウントするオプションを使用することです。pid_namespaces(7)マニュアルページを参照してください。

/proc および PID 名前空間

/ procファイルシステム(/ proc / [pid]ディレクトリにあります)は、/ procファイルシステムが別の名前空間のプロセスで表示されていても、マウントを実行しているプロセスのPID名前空間に表示されるプロセスにのみ表示されます。

新しいPID名前空間を作成した後、子がルートディレクトリを変更し、/ procに新しいprocfsインスタンスをマウントすると、ps(1)などのツールが正しく機能できるようにするのが便利です。

clone(2) または unshare(2) のフラグ引数に CLONE_NEWNS を含む新しいマウント名前空間を同時に作成する場合、ルートディレクトリを変更する必要はありません。新しいprocfsインスタンスは/ procに直接マウントできます。

シェルから/ procをマウントするコマンドは次のとおりです。

$ mount -t proc proc /proc

/proc/self パスで readlink(2) を呼び出すと、procfs によってマウントされた PID 名前空間 (つまり、procfs をマウントするプロセスの PID 名前空間) に呼び出し元のプロセス ID が生成されます。これは、プロセスが別の名前空間からそのPIDを取得しようとするときに自己検査目的に役立ちます。

$ sudo unshare -p   -f ps -o pid,ppid,pidns,mntns,comm
  PID  PPID      PIDNS      MNTNS COMMAND
27462 24107 4026531836 4026531840 sudo
27463 27462 4026531836 4026531840 unshare
27464 27463 4026532863 4026531840 ps
$ sudo unshare -p --mount-proc  -f ps -o pid,ppid,pidns,mntns,comm
  PID  PPID      PIDNS      MNTNS COMMAND
    1     0 4026532864 4026532863 ps

unsharedockerなどの名前空間にアクセスするためのラッパーとシステムコール用の低レベルユーティリティですnsenterunshare(2)setns(2)

strace何が起こっているのかを彼らに伝えることができます。第二に:

  1. mntとpidの名前空間共有を解放します。

    5281  unshare(CLONE_NEWNS|CLONE_NEWPID) = 0
    
  2. 子供をフォークする(なぜなら-f

    5281  clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6b0af4a7d0) = 5282
    

    受け継がれた子供共有されていません名前空間

  3. マウントが親名前空間と子名前空間の両方に伝播しないように、新しい mnt 名前空間でマウント伝播を無効にします。

    5282  mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0
    5282  mount("none", "/proc", NULL, MS_REC|MS_PRIVATE, NULL) = 0
    
  4. 内部に新しいpid名前空間の新しいprocをマウントします/proc(なぜならpsそれが見つかると予想される場所であり、私たちがmnt名前空間を作成した理由だからです)。別のオプションは、いくつかのバインドマウントとを使用することです chroot。 fsはpid名前空間をproc親mnt名前空間にマウントすることもできますが、そうすると大きな問題が発生する可能性があります。

    5282  mount("proc", "/proc", "proc", MS_NOSUID|MS_NODEV|MS_NOEXEC, NULL) = 0
    
  5. psこの名前空間で実行

    5282  execve("/bin/ps", ["ps", "-o", "pid,ppid,pidns,mntns,comm"], 0x7fff5a325dd8 /* 73 vars */) = 0
    

答え2

ただ映像を見ました。彼女はprocタイプを/ procとしてマウントし、できるだけ多く表示しました(他のプロセス名前空間にありました)。ホストを表示できますが、/procプロセスの名前空間にリークがあります。

状況が混ざっています。さまざまな名前空間があります。ビデオには、ホスト名の名前空間(彼女はあまり注意を払わなかった)、プロセスの名前空間、およびファイルシステムの名前空間(chroot経由)が表示されます。ファイルシステムとプロセスの名前空間を混在させています。それはおそらくファイルpsシステム(/proc)を使用していますが、プロセス名前空間を使用したいからです。 procはプロセス名前空間を使用するため、新しいprocが作成されると新しい名前空間になります。

インストールする

インストールは再インストールではありません(再インストールオプションはありません)。

複数のプロセスを持つことができますか?試してみてください。はい、しかし他の場所では、psはそれを使用します/proc。チートのために静的ファイルに置き換えることもできます。ただし、ファイル、ディレクトリ、または特殊ファイル(chrootを実行しない限り)はps1つしか存在できません。/proc

カーネルがすべてのprocsを書くかどうか

いいえ、カーネルは同時に2つの場所に書き込まれません(書き込む内容はありません(ディスクスペースではありません))。 procから読み取ると、カーネルは適切なデータを生成します(使用する名前空間によって異なります)。 re in)一度に1つしか読み取ることができないので、一度に1つだけを作成でき、必要なだけ読み取ることができます(1ファイルのみ)。

Linuxのどの名前空間がどのファイルシステムに対応するかについての文書はありますか?

lsこれは、名前空間がどの名前空間にあるのかを尋ねるのと同じです。そうではありませんが、名前空間の影響を受けます。したがって、procは現在のプロセス名前空間内のプロセスについてのみ知ることができます。 procの他の部分は、異なる名前空間タイプの影響を受ける可能性があります(その機能によって異なります)。

関連情報