インストールする

インストールする

私は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
    

おすすめ記事