Данный podman установлен в системе Linux и системном модуле с именем baz.service:
# /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
И начался баз.сервис:
# systemctl daemon-reload
# systemctl start baz.service
Затем, когда я проверяю состояние модуля, я не вижу sh
или sleep
процесс в cgroup /system.slice/baz.service
# 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
# ...
Я ожидал увидеть sh
и sleep
детей в моем статусе baz.service, потому что слышал, как люди из redhat говорят, что podman использует традиционную модель fork-exec.
Если podman сделал fork и exec, то не будут ли my sh
и sleep
process дочерними по отношению к podman и были бы в той же группе, что и исходный процесс podman?
Я ожидал, что смогу использовать systemd и podman, чтобы иметь возможность управлять моими контейнерами без перехода детей к другому родителю и выхода из моего модуля baz.service ssystemd.
Глядя на выходе ps
я вижу , что sh
и sleep
на самом деле дети другого процесса , который называется conmon
. Я не уверен, откуда появился conmon или как он был запущен, но systemd не захватил его.
# 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 отличается от модели сервера-докера?
- Чем отличается приман подмана от контейнера докера?
Возможно, они оба являются средами выполнения контейнеров, и dockerd
демон - это то, от чего люди хотят избавиться.
Так что, возможно, докер это как:
- Dockerd Daemon
- докер кли
- контейнерная среда выполнения
И Подман это как:
- подман кли
- время выполнения контейнера conmon
Так что, возможно, podman использует традиционную модель fork exec, но это не podman cli, который разветвляется и exec, это процесс conmon.
Я чувствую себя смущенным.
источник
Ответы:
Основная идея
podman
заключается в том, чтобы уйти от централизованной архитектуры с помощью сверхмощного наблюдателя (напримерdockerd
), где централизованный демон является единственной точкой отказа. Об этом даже есть хэштег - " #nobigfatdaemons ".Как избежать централизованного управления контейнерами? Вы удаляете одного главного демона (снова
dockerd
) и запускаете контейнеры независимо (в конце дня контейнеры - это просто процессы, поэтому вам не нужен демон для их порождения).Тем не менее, вам все еще нужен способ
stdout
иstderr
контейнер;wait(2)
указать PID контейнера 1;Для этой цели каждый контейнер podman по-прежнему контролируется небольшим демоном, называемым
conmon
(из «контейнера-монитора»). Разница с демоном Docker заключается в том, что этот демон настолько мал, насколько это возможно (проверьте размер исходного кода ), и он создается для каждого контейнера. Еслиconmon
для одного контейнера происходит сбой, остальная часть системы остается неизменной.Далее, как контейнер порождается?
Учитывая, что пользователь может захотеть запустить контейнер в фоновом режиме, как в Docker,
podman run
процесс дважды разветвляется и только потом выполняетconmon
:Промежуточный процесс между
podman run
иconmon
(т. Е. Прямым родителемconmon
- в приведенном выше примере это PID 8484) завершится иconmon
будет переименованinit
, таким образом становясь демоном самоуправления. После этогоconmon
также отключается среда выполнения (напримерrunc
) и, наконец, среда выполнения выполняет точку входа контейнера (например/bin/sh
).Когда контейнер работает,
podman run
он больше не требуется и может выйти, но в вашем случае он остается в сети, потому что вы не просили его отсоединиться от контейнера.Далее,
podman
использует cgroups для ограничения контейнеров. Это означает, что он создает новые cgroups для новых контейнеров и перемещает туда процессы . По правилам cgroups, процесс может быть членом только одной cgroup одновременно, и добавление процесса в некоторую cgroup удаляет его из другой cgroup (где это было ранее) в пределах той же иерархии. Таким образом, при запуске контейнера, окончательное расположение контрольных групп выглядят следующим образом :podman run
остатки на контрольных группы изbaz.service
, созданныхsystemd
, тоconmon
процесс помещается в своих контрольных группах, а также контейнерные процессы помещаются в их собственных контрольных группах:Примечание: PID 13075 выше на самом деле
sleep 1
процесс, порожденный после смерти PID 13043.Надеюсь это поможет.
источник
stdout
/stderr
streams - опять же,podman
владеет контейнером и захватывает потоки контейнерного процесса.systemd
владеет сервисом и захватывают потоки основного процесса сервиса (в вашем случае, наsystemd
самом деле захватываетstdout
/stderr
оpodman run
процессе). Это работает именно так, как и должно работать, потому чтоconmon
захватывает потоки контейнера,podman run
присоединяется к нимconmon
,systemd
захватывает потокиpodman run
, поэтому, наконец, все журналы из контейнера захватываютсяsystemd
и вы видите их вsystemctl status baz.service
.