Почему conmon находится в другой контрольной группе, когда podman запускается с помощью systemd?

Вот так:

find All_RawData/Each_Cell_Raw -name '*.bax.h5' -exec sh -c 'for f do dextract -q "$f" > "${f%.h5}.fastq"; done' find-sh {} +

С некоторыми разрывами строк для облегчения чтения:

find All_RawData/Each_Cell_Raw -name '*.bax.h5' -exec sh -c '
  for f
    do dextract -q "$f" > "${f%.h5}.fastq"
  done' find-sh {} +

Объяснение и обоснование см. вhttps://unix.stackexchange.com/a/321753/135943.

13
10.08.2019, 16:10
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больше не требуется и может закрыться, но в вашем случае он остается в сети, потому что вы не просили его отсоединиться от контейнера.

Затем podmanиспользует контрольные группы для ограничения контейнеров. Это означает, что он создает новые контрольные группы для новых контейнеров и перемещает туда процессы . По правилам cgroups процесс может одновременно быть членом только одной cgroup,и добавление процесса в некоторую контрольную группу удаляет его из другой контрольной группы (, где он был ранее )в той же иерархии. Итак, когда контейнер запущен, окончательная компоновка контрольных групп выглядит следующим образом:podman runостается в контрольных группах baz.service, созданных systemd, процесс conmonразмещается в своих собственных контрольных группах, а процессы в контейнерах помещаются в свои собственные контрольные группы:

$ 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 1процессом, порожденным после смерти PID 13043.

Надеюсь, это поможет.

10
28.04.2021, 23:30

Теги

Похожие вопросы