Linuxの名前空間は、とりわけ、子プロセスをゾンビ化したり、init
にダンプしたりすることなく、制限して子プロセスを安全に処理するために活用できることを知っています。しかし、私は実装の詳細について曖昧です。 mount
やnsenter
などのutil-linux
が提供するツールを使用して、監視、監視し、起動したすべてのプロセスが別のプロセスの直接の名前空間の子孫であることを確認するにはどうすればよいですか?
ここで使用する正しいコマンドはunshare
です。これを行うために必要なオプションはutil-linux 2.23
からのみ利用できることに注意してください。アイデアは、実行中のプログラムに新しい PID名前空間 を作成し、そのすべての子もこの名前空間に作成されるようにすることです。次のようにするだけで、新しいPID名前空間でコマンドを実行できます。
Sudo unshare -fp some_command
シェルを実行するには、コマンドを省略します。これにより、その子と一緒に、親(システム)名前空間内で通常どおりPIDを持つプロセスが作成されます。ただし、新しい名前空間内では、init
プロセスのいくつかの特別な特性とともに、PIDが1
になります。おそらく、監視の観点から最も関連する特性は、その子孫のいずれかが孤立している場合、実際のinit
プロセスではなく、このプロセスに対して親が親になることです。
ほとんどの場合、これを行うだけで十分です。前述のように、名前空間内のプロセスはすべて親名前空間内にPIDを持っているため、通常のコマンドを使用してアクティビティを監視できます。名前空間内のプロセスが孤立した場合でも、トップレベルプログラムのPIDの下にあるプロセスツリーのブランチから外れることがないので、簡単に追跡できます。
しかし、私たちができないことは、それが持っているが考えるPIDに関してプロセスを監視することです。これを行うには、特に新しいネームスペース内でps
コマンドを使用できるようにするには、ネームスペース用に別のprocfs
ファイルシステムをマウントする必要があります。 ps
がprocfs
を受け入れる唯一の場所は/proc
であるため、これは別の問題を引き起こします。 1つの解決策は、chroot
刑務所を作成し、そこに新しいprocfs
をマウントすることです。しかし、これは扱いにくいアプローチです。少なくとも、使用する予定のバイナリを、それらが依存するライブラリと一緒に新しいルートにコピー(または少なくともハードリンク)する必要があるからです。
解決策は、新しいmount名前空間も使用することです。この中で、真のルート/proc
ディレクトリを使用する方法で新しいprocfs
をマウントし、PID名前空間内で使用でき、他のものに干渉しません。このプロセスを非常に単純にするために、unshare
コマンドは--mount-proc
オプションを提供します。
Sudo unshare -fp --mount-proc some_command
結合された名前空間内でps
を実行すると、PIDネームスペースを持つプロセスのみが表示され、PIDが1
である最上位プロセスが表示されます。
nsenter
はどうですか?名前が示すように、nsenter
を使用して、unshare
ですでに作成されている名前空間を入力できます。これは、名前空間内からのみ利用可能な情報を、他の関係のないスクリプトから取得する場合に役立ちます。最も簡単な方法は、名前空間内で実行されているプログラムのPIDにアクセスすることです。明確にするために、これはnsenter
が実行されているネームスペース内のターゲットプログラムのPIDである必要があります(ネームスペースはネストできるため、単一のプロセスで多数のPIDを持つことが可能です)。ターゲットPID /マウント名前空間でシェルを実行するには、次のようにします。
Sudo nsenter -t $PID -m -p
この名前空間が上記のように設定されている場合、ps
はその名前空間内のプロセスのみを一覧表示します。