GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo ejecutar pods como servicios systemd con Podman

Podman es bien conocido por su perfecta integración en los sistemas Linux modernos, y el soporte de systemd es una piedra angular en estos esfuerzos. Linux comúnmente usa el sistema systemd init para administrar servicios locales como servidores web, motores de contenedores, demonios de red y todas sus interdependencias. Extender estas prácticas de administración de sistemas Linux más tradicionales con el mundo moderno de los contenedores es una evolución natural.

Hay dos casos de uso comunes para combinar systemd y contenedores:

  • Ejecutar systemd dentro de un contenedor
  • Uso de systemd para ejecutar aplicaciones en contenedores

El primer escenario es ejecutar systemd dentro de un contenedor. Como explica Dan Walsh, ejecutar systemd dentro de un contenedor es tan simple como cuando se usa Podman. Podman configura automáticamente varios montajes en el contenedor y systemd está listo para funcionar. Si bien es una función de Podman comparativamente pequeña, fue un gran salto para ejecutar cargas de trabajo en contenedores cuando se introdujo.

Históricamente, otras herramientas de contenedor no han sido compatibles con systemd. Los usuarios enfrentaron el desafío de escribir secuencias de comandos de inicio personalizadas, que son propensas a errores y una carga de soporte para los proveedores de software. Con Podman, todos estos problemas desaparecen. Los usuarios pueden usar systemd para instalar y ejecutar sus aplicaciones en contenedores, como en cualquier otro lugar, y los proveedores de software no enfrentarán los desafíos de lidiar con scripts de inicio personalizados escritos por sus usuarios.

El segundo escenario es usar systemd para ejecutar y administrar aplicaciones en contenedores. Eso significa que systemd inicia una aplicación en contenedores y administra todo su ciclo de vida. Podman simplifica esto con el podman generate systemd comando, que genera un archivo de unidad systemd para un contenedor o pod específico. Podman v1.7 y versiones posteriores admiten la generación de tales unidades. Con el tiempo, nuestro equipo ha mejorado esta función y ha generado archivos unitarios systemd que pueden ejecutarse en otras máquinas, de forma similar al uso de un archivo YAML de Kubernetes o Compose. Además, la estrecha integración con systemd sentó las bases para actualizaciones automáticas y reversiones simples, compatibles desde Podman v3.4.

Si bien hay muchos blogs y artículos anteriores sobre la generación de unidades systemd para contenedores, no hay ninguno para generar estas unidades para pods. Pero antes de entrar en estos detalles, quiero repasar qué es un pod.

[ ¿Empezando con los contenedores? Consulta este curso gratuito. Implementación de aplicaciones en contenedores:una descripción técnica general. ]

¿Qué es una cápsula?

Hay varias partes diferentes en un pod, y creo que Brent Baude lo explica mejor con la gran figura a continuación:

Lo primero que hay que notar es que un pod consta de uno o más contenedores. El grupo comparte grupos de control (cgroups) y espacios de nombres específicos como el PID, la red y el espacio de nombres IPC. Los cgroups compartidos aseguran que todos los contenedores tengan las mismas restricciones de recursos. Los espacios de nombres compartidos permiten que los contenedores se comuniquen entre sí más fácilmente (por ejemplo, a través de host local o comunicación entre procesos).

También puede ver un contenedor de infraestructura especial. Su objetivo principal es mantener abiertos recursos específicos asociados con el pod, como puertos, espacios de nombres o cgroups. El contenedor de infraestructura es el contenedor de nivel superior del pod, se crea antes que otros contenedores y se destruye en último lugar. El contenedor de infraestructura se utiliza al generar unidades systemd para un pod, así que tenga en cuenta que este contenedor se ejecuta durante toda la vida útil del pod. También implica que no puede generar unidades systemd para pods sin un contenedor de infraestructura (como --infra=false ).

Por último, pero no menos importante, verá múltiples conmon procesos en ejecución, uno por contenedor. "Común" es la abreviatura de monitor de contenedor, que resume su funcionalidad principal. También se encarga de reenviar registros y realizar acciones de limpieza una vez que el contenedor ha salido. El conmon El proceso comienza antes que el contenedor e instruye el tiempo de ejecución del contenedor subyacente (como runc o crun ) para crear e iniciar el contenedor. También sale con el código de salida del contenedor, lo que permite usarlo como proceso principal del servicio systemd.

Generando unidades systemd para un pod

Podman genera exactamente una unidad de sistema para un contenedor. Una vez instalado, use systemctl para iniciar, detener e inspeccionar el servicio. El PID principal de cada unidad es el proceso común del contenedor. De esta forma, systemd puede leer el código de salida del contenedor y actuar de acuerdo con la política de reinicio configurada. Para obtener más detalles sobre las unidades, consulte Ejecución de contenedores con Podman y servicios compartibles de systemd y Podman de systemd mejorado con Podman 2.0.

La generación de unidades para un pod es muy similar a iniciar un contenedor. Cada contenedor en el pod tiene una unidad systemd dedicada, y cada unidad depende de la unidad systemd principal del pod. De esta manera, puedes continuar usando systemctl para iniciar, detener e inspeccionar el servicio principal del pod; systemd se encargará de (re)iniciar y detener los servicios de los contenedores junto con el servicio principal.

Este ejemplo crea un pod con dos contenedores, genera archivos de unidad para el pod y luego instala los archivos para el usuario actual:

$ podman pod create --name=my-pod
635bcc5bb5aa0a45af4c2f5a508ebd6a02b93e69324197a06d02a12873b6d1f7

$ podman create --pod=my-pod --name=container-a -t centos top
c04be9c4ac1c93473499571f3c2ad74deb3e0c14f4f00e89c7be3643368daf0e

$ podman create --pod=my-pod --name=container-b -t centos top
b42314b2deff99f5877e76058ac315b97cfb8dc40ed02f9b1b87f21a0cf2fbff

$ cd $HOME/.config/systemd/user

$ podman generate systemd --new --files --name my-pod
/home/vrothberg/.config/systemd/user/pod-my-pod.service
/home/vrothberg/.config/systemd/user/container-container-b.service
/home/vrothberg/.config/systemd/user/container-container-a.service

Como era de esperar, Podman generó tres .service archivos, uno para cada contenedor más el de nivel superior para el pod. Consulte el apéndice al final del artículo para ver el contenido completo de los archivos de la unidad. Las unidades generadas para los dos contenedores parecen unidades de contenedor estándar más las siguientes dependencias systemd:

  • BindsTo=pod-my-pod.service :La unidad contenedora está "vinculada" a la unidad del pod. Si la unidad del módulo se detiene, esta unidad también se detendrá.
  • After=pod-my-pod.service :La unidad del contenedor comienza después de la unidad del pod.

Las dependencias del servicio principal del pod también garantizan que si una unidad contenedora no se inicia correctamente, la unidad principal del pod principal también fallará.

Eso es todo lo que necesita saber sobre la generación de unidades systemd para pods con Podman. Una vez que haya recargado systemd a través de systemctl --user daemon-reload , inicie y detenga el pod.service a voluntad. Echa un vistazo:

# Reload the daemon
$ systemctl --user daemon-reload

# Start the pod service and make sure the service is running
$ systemctl --user start pod-my-pod.service

$ systemctl --user is-active pod-my-pod.service
active

# Make sure the pod and its containers are running
$ podman pod ps
POD ID    	NAME    	STATUS  	CREATED    	INFRA ID  	# OF CONTAINERS
6dd1090d4ca6  my-pod  	Running 	2 minutes ago  85f760a5cfe5  3
user $ podman container ps
CONTAINER ID  IMAGE                                	COMMAND 	CREATED    	STATUS        	PORTS   	NAMES
85f760a5cfe5  localhost/podman-pause:4.0.2-1646319369          	5 minutes ago  Up 5 minutes ago          	6dd1090d4ca6-infra
44a7e60b9563  quay.io/centos/centos:latest         	top     	5 minutes ago  Up 5 minutes ago          	container-b
31f24bdff747  quay.io/centos/centos:latest         	top     	5 minutes ago  Up 5 minutes ago          	container-a

Genial, todo funciona como se esperaba. Puedes usar systemctl para iniciar los servicios, y Podman enumera los pods y sus contenedores correctamente. En aras de la coherencia, eche un vistazo final a cómo detener el servicio de pod.

# Stop the pod service
$ systemctl --user stop pod-my-pod.service

# Make sure the pod and its containers are removed
$ podman pod ps -q

$ podman container ps -q

# Make sure the services are inactive
$ systemctl --user is-active pod-my-pod.service container-container-a.service container-container-b.service
inactive
inactive
inactive

El mensaje final es que Podman genera unidades systemd para pods tal como lo hace para contenedores. Las dependencias entre estas unidades se establecen de manera que solo necesita interactuar con la unidad principal del pod, y systemd se encarga de iniciar y detener las unidades de los contenedores.

Apéndice

Podman genera los siguientes archivos de unidad para un pod y los dos contenedores relacionados.

pod-my-pod.servicio

Description=Podman pod-my-pod.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=
Requires=container-container-a.service container-container-b.service
Before=container-container-a.service container-container-b.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/pod-my-pod.pid %t/pod-my-pod.pod-id
ExecStartPre=/usr/bin/podman pod create --infra-conmon-pidfile %t/pod-my-pod.pid --pod-id-file %t/pod-my-pod.pod-id --name=my-pod --replace
ExecStart=/usr/bin/podman pod start --pod-id-file %t/pod-my-pod.pod-id
ExecStop=/usr/bin/podman pod stop --ignore --pod-id-file %t/pod-my-pod.pod-id -t 10
ExecStopPost=/usr/bin/podman pod rm --ignore -f --pod-id-file %t/pod-my-pod.pod-id
PIDFile=%t/pod-my-pod.pid
Type=forking

[Install]
WantedBy=default.target

contenedor-contenedor-un.servicio

[Unit]
Description=Podman container-container-a.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
BindsTo=pod-my-pod.service
After=pod-my-pod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-my-pod.pod-id --sdnotify=conmon -d --replace --name=container-a -t centos top
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target

contenedor-contenedor-b.servicio

[Unit]
Description=Podman container-container-b.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
BindsTo=pod-my-pod.service
After=pod-my-pod.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --pod-id-file %t/pod-my-pod.pod-id --sdnotify=conmon -d --replace --name=container-b -t centos top
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all

[Install]
WantedBy=default.target


Linux
  1. Cómo administrar los servicios de Systemd con Systemctl en Linux

  2. Cómo usar Podman dentro de un contenedor

  3. ¿Cómo ejecutar un comando dentro de un contenedor Systemd en ejecución?

  4. Cómo eliminar los servicios de systemd

  5. ¿Cómo ejecuto un script antes que todo lo demás al apagar con systemd?

Cómo ejecutar Podman en Windows

Ejecute el contenedor Docker de Almalinux o Rocky Linux 8 con Systemd (systemctl)

Cómo ejecutar PHPMyAdmin en un contenedor Docker

Cómo ejecutar Grafana en un contenedor Docker

Cómo ejecutar contenedores Docker

Cómo ejecutar un alias con Sudo en Linux