Uma tradução do artigo foi preparada especificamente para os alunos do curso Linux Administrator .
Lidamos com a capacidade do systemd de executar contêineres para restaurar o sistema de arquivos raiz de um sistema danificado.
Enquanto existirem sistemas GNU / Linux, os administradores de sistema precisarão se recuperar de danos ao sistema de arquivos raiz, alterações acidentais na configuração ou outras situações que impeçam o carregamento do sistema em um estado "normal".Normalmente, as distribuições Linux oferecem uma ou mais opções de menu no momento da inicialização (por exemplo, no menu GRUB) que podem ser usadas para reparar um sistema danificado; geralmente eles inicializam o sistema no modo de usuário único com o desligamento da maioria dos serviços do sistema. Na pior das hipóteses, o usuário pode alterar a linha de comando do kernel no carregador de inicialização para usar o shell padrão como o processo init (PID 1). Esse método é o mais complexo e cheio de dificuldades que podem levar à perda de tempo e frustração, enquanto o sistema precisa ser restaurado.
Mais importante ainda, todos esses métodos pressupõem que o sistema danificado possui algum tipo de console físico, mas isso não pode mais ser utilizado na era da computação em nuvem. Sem um console físico, existem apenas algumas opções (se ainda estiverem disponíveis) para influenciar o processo de inicialização dessa maneira. Mesmo máquinas físicas podem se tornar pequenos dispositivos internos que não possuem um console fácil de usar, e encontrar os cabos e adaptadores de porta serial certos e configurar um emulador de terminal; tudo para usar o console em uma porta serial em caso de emergência costuma ser bastante complicado.
Quando outro sistema está disponível (da mesma arquitetura e configuração geralmente semelhante), uma maneira geral de simplificar o processo de recuperação é remover os dispositivos de armazenamento do sistema danificado e conectá-los ao sistema de trabalho como dispositivos secundários. Em sistemas físicos, isso geralmente é simples, e a maioria das plataformas de computação em nuvem também suporta isso, porque elas permitem montar o volume raiz da instância danificada em outra instância.
Após o sistema de arquivos raiz ser conectado a outro sistema, o problema de corrupção do sistema de arquivos é resolvido usando o
fsck e outras ferramentas. A solução de problemas de erros de configuração, pacotes corrompidos ou outros problemas pode ser mais difícil porque eles exigem que você monte o sistema de arquivos e localize e modifique os arquivos ou bancos de dados de configuração corretos.
Usando systemd
Antes do advento do
systemd, a maneira de corrigir as configurações na prática era editar arquivos de configuração usando um editor de texto. Encontrar os arquivos necessários e entender seu conteúdo é uma tarefa separada que está além do escopo deste artigo.
Quando o sistema GNU / Linux usa
systemd , muitas mudanças na configuração são feitas melhor usando as ferramentas que ele fornece - por exemplo, ativar ou desativar serviços requer a criação ou exclusão de links simbólicos em vários lugares. A ferramenta
systemctl é usada para fazer essas alterações, mas seu uso requer que a instância
systemd funcione e escute as solicitações (via D-Bus). Quando o sistema de arquivos raiz é montado como um sistema de arquivos adicional em outro computador, uma instância funcional do systemd não pode ser usada para fazer essas alterações.
O início manual do sistema do sistema de destino também é impraticável, pois foi projetado como um processo PID 1 para controlar todos os outros processos, que podem entrar em conflito com uma instância já em execução no sistema usado para correção.
Felizmente, o
systemd tem a capacidade de executar contêineres - sistemas GNU / Linux totalmente encapsulados com seu próprio PID 1 e ambiente, que usa várias funcionalidades de namespace oferecidas pelo kernel Linux. Ao contrário de ferramentas como Docker e Rocket, o
systemd não requer uma imagem de contêiner para executá-lo; ele pode executá-lo com privilégios de root em qualquer lugar do sistema de arquivos existente. Isso é feito usando a
ferramenta systemd-nspawn , que criará os espaços para nome do sistema necessários e iniciará o processo inicial no contêiner e fornecerá o console. Diferente do
chroot , que altera apenas a raiz visível do sistema de arquivos, esse tipo de contêiner terá um espaço para nome do sistema de arquivos separado, sistemas de arquivos adequados montados em
/ dev ,
/ run e
/ proc , além de um espaço para nome do processo e IPC separados. Visite o
principal recurso systemd-nspawn para saber mais sobre seus recursos.
Um exemplo para demonstrar como isso funciona
Neste exemplo, um dispositivo de armazenamento que contém o sistema de arquivos raiz do sistema danificado é conectado a um sistema em execução, onde aparece como
/ dev / vdc . O nome do dispositivo variará dependendo do número de dispositivos de armazenamento existentes, do tipo de dispositivo e do método usado para conectá-lo ao sistema. O sistema de arquivos raiz pode usar o dispositivo de armazenamento inteiro ou residir em uma partição dentro do dispositivo; como a configuração mais comum (simples) coloca o sistema de arquivos raiz na primeira partição do dispositivo,
/ dev / vdc1 será usado neste exemplo.
Substitua o nome do dispositivo nos comandos abaixo pelo nome correto do dispositivo do seu sistema .
Um sistema de arquivos raiz danificado também pode ser mais complexo que um sistema de arquivos separado em um dispositivo; pode ser um volume no LVM ou em um conjunto de dispositivos combinados em uma matriz RAID. Nesses casos, você deve concluir as etapas necessárias para criar e ativar um dispositivo lógico que contém o sistema de arquivos antes que ele esteja disponível para montagem. Novamente, essas etapas estão além do escopo deste artigo.
Preparações necessárias
Primeiro, verifique se a ferramenta systemd-nspawn está instalada - a maioria das distribuições GNU / Linux não a instala por padrão. Ele é fornecido pelo pacote systemd-container na maioria das distribuições; portanto, use o gerenciador de pacotes da sua distribuição para instalá-lo. As instruções neste exemplo foram testadas usando o Debian 9, mas devem funcionar de maneira semelhante em qualquer distribuição moderna do GNU / Linux.
O uso dos comandos abaixo quase certamente exigirá privilégios de root; portanto, você deverá fazer login como root, usar o sudo para obter um shell com privilégios de root ou adicionar o prefixo sudo a cada comando.
Verifique e monte o sistema de arquivos
Primeiro use fsck para verificar as estruturas e o conteúdo do sistema de arquivos de destino:
$ fsck /dev/vdc1
Se ele encontrar algum problema com o sistema de arquivos, responda as perguntas adequadamente para corrigi-las. Se o sistema de arquivos estiver seriamente danificado, ele não poderá ser reparado; nesse caso, você precisará procurar outras maneiras de extrair seu conteúdo.
Agora crie um diretório temporário e monte o sistema de arquivos de destino nele:
$ mkdir /tmp/target-rescue $ mount /dev/vdc1 /tmp/target-rescue
Quando o sistema de arquivos estiver montado, execute o contêiner como o sistema de arquivos raiz:
$ systemd-nspawn --directory /tmp/target-rescue --boot -- --unit rescue.target
Argumentos da linha de comando para iniciar o contêiner:
- --directory / tmp / target-rescue fornece o caminho para o sistema de arquivos raiz do contêiner.
- --boot procura um programa de inicialização adequado no sistema de arquivos raiz do contêiner e o inicia passando parâmetros da linha de comando para ele. Neste exemplo, o sistema de destino também usa systemd como o PID 1 do processo, portanto, o restante dos parâmetros é para ele. Se o sistema de destino que você estiver restaurando usar alguma outra ferramenta como o PID 1 do processo, será necessário definir as configurações adequadamente.
- - Separa os parâmetros para systemd-nspawn daqueles destinados ao PID 1 do processo de contêiner.
- --unit rescue.target informa ao systemd no contêiner o nome do destino que ele deve tentar atingir durante o processo de inicialização. Para simplificar as operações de recuperação no sistema de destino, inicialize-o no modo "recuperação", em vez do modo multiusuário normal.
Se tudo correr bem, você verá uma saída parecida com esta:
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):
Nesta saída, você pode ver que o
systemd inicia como o processo init no contêiner e determina que ele seja executado dentro do contêiner para que ele possa personalizar seu comportamento. Para trazer o contêiner para a condição de trabalho, vários arquivos de unidade são iniciados e, em seguida, a senha raiz do sistema de destino é solicitada. Você pode inserir a senha root aqui se desejar solicitar um shell com privilégios de root ou pressionar
Ctrl + D para continuar o processo de inicialização, que exibirá o prompt de login do console habitual.
Ao fazer as alterações necessárias no sistema de destino, pressione
Ctrl +] três vezes seguidas; Isso encerrará o contêiner e retornará ao shell original. A partir daí, você pode executar a limpeza desmontando o sistema de arquivos do sistema de destino e excluindo o diretório temporário:
$ umount /tmp/target-rescue $ rmdir /tmp/target-rescue
Isso é tudo! Agora você pode remover os dispositivos de armazenamento do sistema de destino e devolvê-los.
A idéia de usar
systemd-nspawn dessa maneira, especialmente
a opção --boot , surgiu de uma
pergunta publicada no StackExchange. Agradecemos a Shibumi e kirbyfan64sos pelas respostas úteis a esta pergunta!Mais recursos Linux