Cómo usar systemd-nspawn para restaurar un sistema Linux

Se preparó una traducción del artículo específicamente para estudiantes del curso de Administrador de Linux .





Nos ocupamos de la capacidad de systemd para ejecutar contenedores para restaurar el sistema de archivos raíz de un sistema dañado.

Mientras existan sistemas GNU / Linux, los administradores del sistema deberán recuperarse de daños en el sistema de archivos raíz, cambios accidentales de configuración u otras situaciones que impidan que el sistema se cargue en un estado "normal".

Típicamente, las distribuciones de Linux ofrecen una o más opciones de menú en el momento del arranque (por ejemplo, en el menú GRUB) que se pueden usar para reparar un sistema dañado; a menudo inician el sistema en modo de usuario único con el apagado de la mayoría de los servicios del sistema. En el peor de los casos, el usuario puede cambiar la línea de comando del núcleo en el gestor de arranque para usar el shell estándar como el proceso de inicio (PID 1). Este método es el más complejo y está lleno de dificultades que pueden conducir a la pérdida de tiempo y la frustración, mientras que el sistema necesita ser restaurado.

Lo más importante es que todos estos métodos suponen que el sistema dañado tiene algún tipo de consola física, pero esto ya no se puede confiar en la era de la computación en la nube. Sin una consola física, solo hay unas pocas opciones (si todavía están disponibles) para influir en el proceso de arranque de esta manera. Incluso las máquinas físicas pueden convertirse en pequeños dispositivos integrados que no tienen una consola fácil de usar, y encontrar los cables y adaptadores de puerto serie correctos y configurar un emulador de terminal, todo para usar la consola en un puerto serie en una emergencia a menudo es bastante complicado.

Cuando hay otro sistema disponible (de la misma arquitectura y configuración generalmente similar), una forma general de simplificar el proceso de recuperación es eliminar los dispositivos de almacenamiento del sistema dañado y conectarlos al sistema de trabajo como dispositivos secundarios. En los sistemas físicos, esto suele ser sencillo, y la mayoría de las plataformas de computación en la nube también pueden admitir esto, ya que le permiten montar el volumen raíz de la instancia dañada en otra instancia.

Después de que el sistema de archivos raíz está conectado a otro sistema, el problema de corrupción del sistema de archivos se resuelve usando fsck y otras herramientas. La resolución de errores de configuración, los paquetes dañados u otros problemas pueden ser más difíciles porque requieren que monte el sistema de archivos y encuentre y modifique los archivos de configuración o bases de datos correctos.

Usando systemd


Antes de la llegada de systemd, la forma de arreglar las configuraciones en la práctica era editar archivos de configuración usando un editor de texto. Encontrar los archivos necesarios y comprender su contenido es una tarea separada que está más allá del alcance de este artículo.

Cuando el sistema GNU / Linux usa systemd , muchos cambios de configuración se realizan mejor utilizando las herramientas que proporciona; por ejemplo, habilitar o deshabilitar servicios requiere crear o eliminar enlaces simbólicos en varios lugares. La herramienta systemctl se utiliza para realizar estos cambios, pero su uso requiere que la instancia systemd funcione y escuche las solicitudes (a través de D-Bus). Cuando el sistema de archivos raíz se monta como un sistema de archivos adicional en otra computadora, una instancia funcional de systemd no se puede usar para realizar estos cambios.

El inicio manual del sistema del sistema de destino tampoco es práctico, ya que está diseñado como un proceso PID 1 para controlar todos los demás procesos, lo que puede entrar en conflicto con una instancia que ya se está ejecutando en el sistema utilizado para la corrección.

Afortunadamente, systemd tiene la capacidad de ejecutar contenedores: sistemas GNU / Linux totalmente encapsulados con su propio PID 1 y entorno, que utiliza varias funciones de espacio de nombres que ofrece el kernel de Linux. A diferencia de herramientas como Docker y Rocket, systemd no requiere una imagen de contenedor para ejecutar el contenedor; puede ejecutarlo con privilegios de root en cualquier parte del sistema de archivos existente. Esto se hace usando la herramienta systemd-nspawn , que creará los espacios de nombres del sistema necesarios e iniciará el proceso inicial en el contenedor y luego proporcionará la consola. A diferencia de chroot , que solo cambia la raíz visible del sistema de archivos, este tipo de contenedor tendrá un espacio de nombres de sistema de archivos separado, sistemas de archivos adecuados montados en / dev , / run y / proc , así como un espacio de nombres de proceso e IPC separados. Visite el recurso principal systemd-nspawn para obtener más información sobre sus características.

Un ejemplo para demostrar cómo funciona esto


En este ejemplo, un dispositivo de almacenamiento que contiene el sistema de archivos raíz del sistema dañado está conectado a un sistema en ejecución, donde aparece como / dev / vdc . El nombre del dispositivo variará según la cantidad de dispositivos de almacenamiento existentes, el tipo de dispositivo y el método utilizado para conectarlo al sistema. El sistema de archivos raíz puede usar todo el dispositivo de almacenamiento o residir en una partición dentro del dispositivo; Dado que la configuración más común (simple) coloca el sistema de archivos raíz en la primera partición del dispositivo, / dev / vdc1 se utilizará en este ejemplo. Asegúrese de reemplazar el nombre del dispositivo en los comandos a continuación con el nombre correcto del dispositivo de su sistema .

Un sistema de archivos raíz dañado también puede ser más complejo que un sistema de archivos separado en un dispositivo; puede ser un volumen en LVM o en un conjunto de dispositivos combinados en una matriz RAID. En estos casos, debe completar los pasos necesarios para crear y activar un dispositivo lógico que contenga el sistema de archivos antes de que esté disponible para el montaje. Una vez más, estos pasos están más allá del alcance de este artículo.

Preparaciones necesarias


Primero, asegúrese de que la herramienta systemd-nspawn esté instalada; la mayoría de las distribuciones de GNU / Linux no la instalan de manera predeterminada. Es proporcionado por el paquete systemd-container en la mayoría de las distribuciones, así que use el administrador de paquetes de su distribución para instalarlo. Las instrucciones en este ejemplo se probaron con Debian 9, pero deberían funcionar de manera similar en cualquier distribución moderna de GNU / Linux.

El uso de los comandos a continuación seguramente requerirá privilegios de root, por lo que deberá iniciar sesión como root, usar sudo para obtener un shell con privilegios de root o agregar el prefijo sudo a cada comando.

Verifique y monte el sistema de archivos


Primero use fsck para verificar las estructuras y el contenido del sistema de archivos de destino:

$ fsck /dev/vdc1 

Si encuentra algún problema con el sistema de archivos, responda las preguntas en consecuencia para solucionarlos. Si el sistema de archivos está gravemente dañado, no se puede reparar, en cuyo caso tendrá que buscar otras formas de extraer su contenido.

Ahora cree un directorio temporal y monte el sistema de archivos de destino en él:

 $ mkdir /tmp/target-rescue $ mount /dev/vdc1 /tmp/target-rescue 

Cuando el sistema de archivos esté montado, ejecute el contenedor con él como el sistema de archivos raíz:

 $ systemd-nspawn --directory /tmp/target-rescue --boot -- --unit rescue.target 

Argumentos de línea de comando para iniciar el contenedor:

  • --directory / tmp / target-rescue proporciona la ruta al sistema de archivos raíz del contenedor.
  • --boot busca un programa de inicialización adecuado en el sistema de archivos raíz del contenedor y lo inicia, pasándole parámetros desde la línea de comandos. En este ejemplo, el sistema de destino también usa systemd como el PID 1 del proceso, por lo que el resto de los parámetros son para él. Si el sistema de destino que está restaurando utiliza alguna otra herramienta como el PID 1 del proceso, debe configurar los ajustes en consecuencia.
  • - Separa los parámetros para systemd-nspawn de los destinados al PID 1 del proceso del contenedor.
  • --unit rescue.target le dice a systemd en el contenedor el nombre del objetivo que debe intentar lograr durante el proceso de arranque. Para simplificar las operaciones de recuperación en el sistema de destino, inicie en modo "recuperación", en lugar de en modo multiusuario normal.

Si todo va bien, debería ver una salida que se parece a esto:

 Spawning container target-rescue on /tmp/target-rescue. Press ^] three times within 1s to kill container. systemd 232 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN) Detected virtualization systemd-nspawn. Detected architecture arm. Welcome to Debian GNU/Linux 9 (Stretch)! Set hostname to <test>. Failed to install release agent, ignoring: No such file or directory [ OK ] Reached target Swap. [ OK ] Listening on Journal Socket (/dev/log). [ OK ] Started Dispatch Password Requests to Console Directory Watch. [ OK ] Reached target Encrypted Volumes. [ OK ] Created slice System Slice. Mounting POSIX Message Queue File System... [ OK ] Listening on Journal Socket. Starting Set the console keyboard layout... Starting Restore / save the current clock... Starting Journal Service... Starting Remount Root and Kernel File Systems... [ OK ] Mounted POSIX Message Queue File System. [ OK ] Started Journal Service. [ OK ] Started Remount Root and Kernel File Systems. Starting Flush Journal to Persistent Storage... [ OK ] Started Restore / save the current clock. [ OK ] Started Flush Journal to Persistent Storage. [ OK ] Started Set the console keyboard layout. [ OK ] Reached target Local File Systems (Pre). [ OK ] Reached target Local File Systems. Starting Create Volatile Files and Directories... [ OK ] Started Create Volatile Files and Directories. [ OK ] Reached target System Time Synchronized. Starting Update UTMP about System Boot/Shutdown... [ OK ] Started Update UTMP about System Boot/Shutdown. [ OK ] Reached target System Initialization. [ OK ] Started Rescue Shell. [ OK ] Reached target Rescue Mode. Starting Update UTMP about System Runlevel Changes... [ OK ] Started Update UTMP about System Runlevel Changes. You are in rescue mode. After logging in, type "journalctl -xb" to view system logs, "systemctl reboot" to reboot, "systemctl default" or ^D to boot into default mode. Give root password for maintenance (or press Control-D to continue): 

En esta salida, puede ver que systemd se inicia como un proceso de inicio en el contenedor y determina que se ejecuta dentro del contenedor para que pueda ajustar su comportamiento en consecuencia. Para que el contenedor funcione correctamente, se lanzan varios archivos de unidad y luego se solicita la contraseña raíz del sistema de destino. Puede ingresar la contraseña de root aquí si desea solicitar un shell con privilegios de root, o puede presionar Ctrl + D para continuar el proceso de inicio, que mostrará el indicador de inicio de sesión habitual de la consola.

Cuando realice los cambios necesarios en el sistema de destino, presione Ctrl +] tres veces seguidas; Esto cerrará el contenedor y lo regresará al shell original. Desde allí, puede realizar la limpieza desmontando el sistema de archivos del sistema de destino y eliminando el directorio temporal:

 $ umount /tmp/target-rescue $ rmdir /tmp/target-rescue 

Eso es todo! Ahora puede eliminar los dispositivos de almacenamiento del sistema de destino y devolverlos.

La idea de usar systemd-nspawn de esta manera, especialmente la opción --boot , surgió de una pregunta publicada en StackExchange. ¡Gracias a Shibumi y kirbyfan64sos por las útiles respuestas a esta pregunta!

Más recursos de Linux


Source: https://habr.com/ru/post/470497/


All Articles