Evite la eliminación del alcance del usuario de systemd al apagar

Evite la eliminación del alcance del usuario de systemd al apagar

Creo una máquina Debian Bookworm para que sirva como administrador de contenedores LXC. Utilizo contenedores LXC sin privilegios iniciados con el comando lxc-unpriv-start que crea un alcance de usuario systemd. Creo un servicio que inicia mis contenedores al iniciar el servidor y lanza un apagado limpio al detener el servicio. Cada contenedor puede tardar 2 o 3 minutos en cerrarse. Si detengo el servicio principal manualmente, todo funciona bien. El problema surge cuando apago el servidor porque mi servicio espera correctamente a que finalicen los contenedores, pero mientras tanto, systemd-logind elimina todas las sesiones de usuario y también mata brutalmente a mi contenedor.

Simulo la situación creando un shell de solo suspensión y lo ejecuto con

/usr/bin/systemd-run --user --scope -p "Delegate=yes" wait.sh &

y muere al apagarse. ¿Cómo puedo evitar esta muerte?

Respuesta1

Linger debería resolver ese problema.

Dehttps://www.freedesktop.org/software/systemd/man/loginctl.html

Activar/desactivar el usuario persistente para uno o más usuarios. Si está habilitado para un usuario específico, se genera un administrador de usuarios para el usuario en el arranque y se mantiene después de cerrar sesión. Esto permite a los usuarios que no han iniciado sesión ejecutar servicios de larga duración. Toma uno o más nombres de usuario o UID numéricos como argumento. Si no se especifica ningún argumento, habilita/deshabilita la permanencia para el usuario de la sesión de la persona que llama.

loginctl enable-linger <username>

Habilitar la permanencia en la sesión del usuario permitirá que sus contenedores continúen ejecutándose incluso después de cerrar sesión o durante el apagado del sistema. Esto debería evitar que systemd-logind finalice por la fuerza la sesión del usuario y los contenedores asociados, dándoles la oportunidad de cerrarse correctamente.

Respuesta2

Suponiendo que el comando de detención del contenedor se "bloquea" (es decir, sale después de que el contenedor se ha detenido), probablemente pueda ejecutar el comando de inicio del contenedor con un servicio de usuario systemd en lugar de hacerlo directamente desde un shell. Supongamos que necesita iniciar varios contenedores, puede escribir una plantilla de servicio en $HOME/.config/systemd/user/. El nombre de archivo de una plantilla de servicio debe aparecer @antes .service(por ejemplo [email protected], ).

Aquí tienes un ejemplo:

[Unit]
PartOf=%i.scope
After=%i.scope

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-run --user --scope -u %i sh -c 'sleep 1d &'
ExecStop=/usr/bin/sleep 1m

Como puede ver, el nombre del alcance debe ser "conocido" en lugar de uno generado.

Con la plantilla, ahora puede iniciar el contenedor con, por ejemplo systemctl --user start test@container-a, . Ahora debería ver que el alcance correspondiente permanece hasta que su servicio "agente" se haya detenido (es decir, el ExecStop=comando haya salido).

Es posible que deba ejecutar systemctl --user daemon-reloadcada vez que haya realizado cambios en los archivos de servicio (plantilla).

PD: Obviamente, si necesita pasar argumentos adicionales específicos del contenedor (que no son la misma cadena que el nombre del alcance) al comando de inicio/detención del contenedor, probablemente tenga que escribir varios archivos de servicio en lugar de usar una plantilla.

información relacionada