¿Cómo detectar que un sistema de contenedores LXC está listo?

¿Cómo detectar que un sistema de contenedores LXC está listo?

Estoy intentando iniciar un contenedor LXC y luego ejecutar un comando dentro de él. El problema es que incluso si el contenedor está en estado RUNNING, no ha completado todo su arranque. Esto produce problemas con /tmp (y, supongo, con otras inicializaciones).

Esto se puede ilustrar con esta secuencia de llamada que crea un contenedor, lo inicia, espera su estado EN EJECUCIÓN y ejecuta algunos comandos; los comandos crean un archivo /tmp/hello, muestran un directorio, esperan un poco y muestran nuevamente el directorio:

lxc-clone -B overlayfs -s -o vm -n c1 ; lxc-start -n c1 ; lxc-wait -n c1 -s RUNNING ; lxc-attach -n c1 -- su -c "touch /tmp/hello; ls -la /tmp; sleep 5; ls -la /tmp" slave ; lxc-stop -n c1 ; lxc-destroy -n c1

cuya salida es

Created container c1 as snapshot of vm total 16 drwxrwxrwt 1 root root 4096 May 24 09:37 . drwxr-xr-x 1 root nogroup 4096 May 24 09:37 .. drwxrwxrwt 2 root root 4096 May 22 21:19 .ICE-unix drwxrwxrwt 2 root root 4096 May 22 21:19 .X11-unix -rw-rw-r-- 1 slave slave 0 May 24 09:37 hello total 16 drwxrwxrwt 1 root root 4096 May 24 09:37 . drwxr-xr-x 1 root nogroup 4096 May 24 09:37 .. drwxrwxrwt 2 root root 4096 May 24 09:37 .ICE-unix drwxrwxrwt 2 root root 4096 May 24 09:37 .X11-unix

y muestra que el archivo /tmp/hello se elimina mediante algún script de inicialización.

¿Cómo esperar dentro del contenedor hasta que el sistema se inicie por completo? Además, ¿cómo hacerlo desde fuera del contenedor?

Respuesta1

Para un contenedor que se ejecuta en systemd, parece que esto funciona bien:

lxc-attach -n [CONTAINER NAME] -- systemctl isolate multi-user.target

Probablemente podría aplicar la misma lógica para un contenedor basado sysviniten o upstart(ejecutar un comando que se bloquea hasta que se alcanza un nivel de ejecución), pero no podría decirle qué comandos pueden hacer esto en mi cabeza.

Respuesta2

En mi caso, considero que un contenedor LXC está "listo" cuando tiene conectividad de red (por ejemplo, para que comandos como apt updatefuncionen dentro de un script de configuración del contenedor LXC).

En Debian 11 bullseye como host lxc, con un contenedor Debian 11 bullseye lxc, logré aprovechar el siguiente patrón:

lxc-unpriv-start -n "$LXC_CONTAINER"

lxc-wait -n "$LXC_CONTAINER" -s RUNNING
# the lxc-wait RUNNING state is not that useful;
# a container is already considered RUNNING even though the network is not yet up

# the following command blocks until the container's network is up
lxc-unpriv-attach -n "$LXC_CONTAINER" -- systemctl start systemd-networkd-wait-online.service

# when the script reaches this part, the lxc container's network probably is completely up and running

lxc-unpriv-attach -n "$LXC_CONTAINER" -- apt update
# ...

La systemctl start systemd-networkd-wait-online.serviceparte relevante es: systemd-networkd-wait-online.servicees un servicio systemd que se proporciona listo para usar y que solo requiere lanetwork-online.target(o al menos eso tengo entendido).

Por lo tanto, ejecutar systemctl start systemd-networkd-wait-online.servicebloques hasta que la red esté activa.

información relacionada