Systemd в контейнере

Материал из ALT Linux Wiki

Запуск systemd с помощью podman

Для запуска systemd в контейнере можно использовать podman (в том числе rootless). podman умеет определять, что в контейнере запускается systemd. По умолчанию, контейнер запускается в режиме systemd, если команда, запущенная в контейнере, одна из

  • systemd
  • /usr/sbin/init
  • /sbin/init
  • /usr/local/sbin/init

Запущенный в режиме systemd контейнер имеет следующие особенности:

podman монтирует tmpfs файловые системы в следущие каталоги:

  • /run
  • /run/lock
  • /tmp
  • /sys/fs/cgroup/systemd (в случае cgroup v1)
  • /var/lib/journal

Кроме того

  • podman устанавливает сигнал для завершения по умолчанию в SIGRTMIN+3.
  • podman не монтирует виртуальные консоли (/dev/tty\d+) когда запущен с опцией --privileged.
  • В системах с cgroup v2, /sys/fs/cgroup монтируется с возможностью записи.

Это позволяет systemd запускаться в изолированном контейнере без особых модификаций.

Подробнее в man:podman-run(1)

Примечание:

В SELinux системах systemd пытается писать в файловую систему cgroup, что по умолчанию запрещено. Необходимо установить опцию container_manage_cgroup.

# setsebool -P container_manage_cgroup true


$ podman run -d --name systemd registry.altlinux.org/p10/systemd

В минимальной конфигурации запускаются systemd и systemd-journald.

$ podman top systemd
USER  PID  PPID    %CPU    ELAPSED         TTY    TIME    COMMAND
root  1    0       0.000   3m4.700369115s  ?      0s      /sbin/init
root  17   1       0.000   3m4.700425s     ?      0s      /lib/systemd/systemd-journald

Запуск сервисов на примере nginx

Создадим простой Dockerfile

FROM registry.altlinux.org/p10/systemd:latest

RUN apt-get update && apt-get install -y nginx && \
    rm -f /var/cache/apt/archives/*.rpm \
          /var/cache/apt/*.bin \
          /var/lib/apt/lists/*.*

RUN mkdir -p /var/www/html && \
    echo "<html><body><h1>nginx works</h1></body></html>" > /var/www/html/index.html

RUN cat <<EOF > /etc/nginx/sites-available.d/site.conf
server {
    listen 80;
    root /var/www/html;
}
EOF

RUN ln -s /etc/nginx/sites-available.d/site.conf /etc/nginx/sites-enabled.d/site.conf

RUN systemctl enable nginx.service

EXPOSE 80

CMD ["/sbin/init"]

Создадим образ

$ podman build -t test/systemd-nginx .

Запустим

$ podman run -d --name systemd-nginx -p 8080:80 test/systemd-nginx:latest

Сервер должен быть доступен по адресу http://localhost:8080/. Проверить можно с помощью curl или в веб-браузере.

$ curl http://localhost:8080/
<html><body><h1>nginx works</h1></body></html>
$ podman exec systemd-nginx pstree -p
systemd(1)-+-nginx(22)-+-nginx(23)
           |           |-nginx(24)
           |           |-nginx(25)
           |           |-nginx(26)
           |           |-nginx(27)
           |           |-nginx(28)
           |           |-nginx(29)
           |           |-nginx(30)
           |           |-nginx(31)
           |           `-nginx(32)
           `-systemd-journal(17)
$ podman top systemd-nginx
USER    PID  PPID  %CPU   ELAPSED          TTY  TIME  COMMAND
root    1    0     0.000  8m0.393810545s   ?    0s    /sbin/init
root    17   1     0.000  7m59.393869929s  ?    0s    /lib/systemd/systemd-journald
root    22   1     0.000  7m59.394027789s  ?    0s    nginx: master process /usr/sbin/nginx -g daemon off;
_nginx  23   22    0.000  7m59.394096358s  ?    0s    nginx: worker process
_nginx  24   22    0.000  7m59.394138682s  ?    0s    nginx: worker process
_nginx  25   22    0.000  7m59.39417755s   ?    0s    nginx: worker process
_nginx  26   22    0.000  7m59.394217778s  ?    0s    nginx: worker process
_nginx  27   22    0.000  7m59.394338805s  ?    0s    nginx: worker process
_nginx  28   22    0.000  7m59.394410942s  ?    0s    nginx: worker process
_nginx  29   22    0.000  7m59.394466699s  ?    0s    nginx: worker process
_nginx  30   22    0.000  7m59.394504949s  ?    0s    nginx: worker process
_nginx  31   22    0.000  7m59.394543313s  ?    0s    nginx: worker process
_nginx  32   22    0.000  7m59.394581473s  ?    0s    nginx: worker process

Остановить контейнер можно командой

$ podman stop systemd-nginx

Ссылки

Как запускать systemd в контейнере

Документация podman-run