Podmanがsystemdで起動したときにconmonが他のcgroupにあるのはなぜですか?

Podmanがsystemdで起動したときにconmonが他のcgroupにあるのはなぜですか?

与えられたPodmanは、Linuxシステムとbaz.serviceというsystemdユニットにインストールされています。

# /etc/systemd/system/baz.service
[Service]
ExecStart=/usr/bin/podman run --rm --tty --name baz alpine sh -c 'while true; do date; sleep 1; done'
ExecStop=/usr/bin/podman stop baz

baz.serviceが起動しました:

# systemctl daemon-reload
# systemctl start baz.service

その後、デバイスの状態を確認しても、/system.slice/baz.service cgroupshまたはプロセスは表示されません。sleep

# systemctl status baz
● baz.service
   Loaded: loaded (/etc/systemd/system/baz.service; static; vendor preset: enabl
   Active: active (running) since Sat 2019-08-10 05:50:18 UTC; 14s ago
 Main PID: 16910 (podman)
    Tasks: 9
   Memory: 7.3M
      CPU: 68ms
   CGroup: /system.slice/baz.service
           └─16910 /usr/bin/podman run --rm --tty --name baz alpine sh -c while
# ...

Podmanが従来のフォーク実行モデルを使用しているRedhatの人々から聞いたので、baz.serviceの状態でサブキーを見たいとsh思いました。sleep

Podmanがフォークと実行を実行している場合、私とshプロセスsleepはPodmanの子プロセスではなく、元のPodmanプロセスと同じcgroupにありますか?

私は子供たちが他の親に行き、私のbaz.service ssystemdユニットを脱出しなくてもsystemdとpodmanを使って私のコンテナを管理できるようにしたいです。

出力を見ると、子プロセスが実際に名前が異なるプロセスであることがpsわかります。 conmonがどこから来たのか、どのように始まったのかはわかりませんが、systemdはそれを捉えません。shsleepconmon

# ps -Heo user,pid,ppid,comm
# ...
root     17254     1   podman
root     17331     1   conmon
root     17345 17331     sh
root     17380 17345       sleep

私のbaz.serviceデバイスがconmon - > sh - > sleepチェーンを管理していないことは出力から明らかです。

  • PodmanはDockerクライアントサーバーモデルとどう違うのですか?
  • Podmanのconmonとdockerのコンテナの違いは何ですか?

おそらく両方がコンテナランタイムであり、dockerdデーモンは人々が削除したいものです。

おそらくドッカーは次のようになります。

  • ドッカーデーモン
  • Dockerコマンドライン
  • Containerd コンテナランタイム

フォードマンは次のとおりです。

  • Podmanコマンドラインインタフェース
  • 共通コンテナランタイム

したがって、podmanは従来のフォーク実行モデルを使用しますが、podman cliがフォークと実行を実行するのではなく、一般的なプロセスです。

混乱しています。

ベストアンサー1

これに関する全体的なアイデアは、集中型デーモンが単一の障害点であるpodman非常に強力なスーパーバイザー(たとえば)を持つ集中型アーキテクチャから抜け出すことです。dockerdこれに対するタグもあります。 - "#nobigfatdaemons」。

コンテナの集中管理を回避するには?単一のデフォルトデーモン(もう一度言うがdockerd)を削除し、コンテナを独立して起動します(最終的にコンテナはプロセスにすぎないため、コンテナを作成するためのデーモンは必要ありません)。

しかし、まだ方法が必要です。

  • コンテナからログを収集します。誰かがstdoutコンテナを保管する必要がありますstderr
  • コンテナの終了コードの収集 - 誰かがwait(2)コンテナのPID 1を収集する必要があります。

この目的のために、各Podmanコンテナはconmon(「コンテナモニタ」で)呼び出される小さなデーモンによって引き続き監視されます。 Dockerデーモンとの違いは、このデーモンができるだけ小さいことです(確認ソースコードサイズ)であり、コンテナごとに生成されます。コンテナがクラッシュしても、conmonシステムの残りの部分は影響を受けません。

次に、コンテナはどのように作成されますか?

ユーザーがDockerのようにバックグラウンドでコンテナを実行したいと思うことを考えると、プロセスはpodman run分岐します。二重次に、次を実行しますconmon

$ strace -fe trace=fork,vfork,clone,execve -qq podman run alpine
execve("/usr/bin/podman", ["podman", "run", "alpine"], 0x7ffeceb01518 /* 30 vars */) = 0
...
[pid  8480] clone(child_stack=0x7fac6bffeef0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tid=[8484], tls=0x7fac6bfff700, child_tidptr=0x7fac6bfff9d0) = 8484
...
[pid  8484] clone(child_stack=NULL, flags=CLONE_VM|CLONE_VFORK|SIGCHLD <unfinished ...>
[pid  8491] execve("/usr/bin/conmon", ... <unfinished ...>
[pid  8484] <... clone resumed>)        = 8491

podman run間にある中間プロセスconmon(つまり、直接親プロセスconmon- 上記の例ではPID 8484)が終了し、親がconmon再割り当てされてinit自己管理デーモンになります。その後、conmonランタイムもフォークされ(たとえばrunc)、最後にランタイムはコンテナのエントリポイント(たとえば/bin/sh)を実行します。

コンテナの実行中はpodman run不要になって終了する可能性がありますが、お客様の場合はコンテナから分離を要求していないため、オンラインになります。

次に、podmancgroupを使用してコンテナを制限します。これはそれを意味する新しいコンテナ用の新しいcgroupを作成し、プロセスをここに移動します。。 cgroupの規則によれば、プロセスは一度に1つのcgroupにのみ属することができます。cgroupにプロセスを追加すると、同じ階層(以前に配置されていた)の他のcgroupからそのプロセスが削除されます。したがって、コンテナが起動すると、cgroupの最終レイアウトは次のようになります。podman run生成されたcgroupに残り、プロセスは独自のcgroupに配置され、コンテナ化されたプロセスは独自のcgroupに配置されます。baz.servicesystemdconmon

$ ps axf
<...>
 1660 ?        Ssl    0:01 /usr/bin/podman run --rm --tty --name baz alpine sh -c while true; do date; sleep 1; done
 1741 ?        Ssl    0:00 /usr/bin/conmon -s -c 2f56e37a0c5ca6f4282cc4c0f4c8e5c899e697303f15c5dc38b2f31d56967ed6 <...>
 1753 pts/0    Ss+    0:02  \_ sh -c while true; do date; sleep 1; done
13043 pts/0    S+     0:00      \_ sleep 1
<...>

$ cd /sys/fs/cgroup/memory/machine.slice
$ ls -d1 libpod*
libpod-2f56e37a0c5ca6f4282cc4c0f4c8e5c899e697303f15c5dc38b2f31d56967ed6.scope
libpod-conmon-2f56e37a0c5ca6f4282cc4c0f4c8e5c899e697303f15c5dc38b2f31d56967ed6.scope

$ cat libpod-2f56e37a0c5ca6f4282cc4c0f4c8e5c899e697303f15c5dc38b2f31d56967ed6.scope/cgroup.procs 
1753
13075

$ cat libpod-conmon-2f56e37a0c5ca6f4282cc4c0f4c8e5c899e697303f15c5dc38b2f31d56967ed6.scope/cgroup.procs 
1741

注:上記のPID 13075は、実際にsleep 1PID 13043が死んだ後に作成されたプロセスです。

お役に立てば幸いです。

おすすめ記事