Alvos do Systemd Explicados: Gerenciando Estados de Inicialização e Níveis de Execução Efetivamente

Entenda alvos do systemd, equivalentes de níveis de execução, estados de inicialização padrão, isolamento, modos de resgate e gráfico.

Alvos do Systemd Explicados: Gerenciando Estados de Inicialização e Níveis de Execução Efetivamente

Os alvos do systemd são estados nomeados do sistema. Um alvo pode representar uma inicialização normal de servidor, uma área de trabalho gráfica, um shell de resgate, um desligamento ou um grupo personalizado de serviços que você deseja iniciar juntos. Se você veio de sistemas Linux mais antigos, os alvos são a substituição do systemd para as partes dos níveis de execução que as pessoas realmente usavam, mas são mais flexíveis porque são construídos a partir de dependências em vez de apenas números.

Você geralmente encontra alvos quando um servidor inicializa no modo errado, um gerenciador de exibição de desktop não inicia ou um guia de recuperação diz para você entrar em rescue.target. Conhecer alguns comandos torna essas situações muito menos misteriosas.

A Evolução dos Níveis de Execução para Alvos do Systemd

Historicamente, os sistemas Linux usavam um conceito chamado níveis de execução para definir o estado operacional do sistema durante a inicialização e execução. Um nível de execução era um identificador numérico (0-6) que ditava quais serviços eram iniciados ou parados. Por exemplo, o nível de execução 3 normalmente significava um modo de texto multiusuário, enquanto o nível de execução 5 indicava um ambiente multiusuário gráfico. Este sistema, embora funcional, tinha limitações:

  • Rigidez: Os níveis de execução eram frequentemente definidos de forma fixa ou específica da distribuição, tornando difícil personalizar o conjunto exato de serviços ativos para um determinado estado.
  • Dependências Implícitas: As dependências entre serviços eram frequentemente gerenciadas indiretamente por meio de atribuições de níveis de execução, levando a potenciais conflitos ou serviços perdidos.
  • Falta de Granularidade: O sistema numérico carecia de clareza descritiva, dificultando a compreensão do estado pretendido do sistema.

Os alvos do systemd abordam essas limitações fornecendo uma abordagem mais explícita, orientada por dependências e descritiva. Em vez de números abstratos, os alvos têm nomes significativos (por exemplo, multi-user.target, graphical.target) que indicam claramente o estado pretendido do sistema. As dependências são explicitamente definidas nos arquivos de unidade, garantindo que todos os componentes necessários sejam iniciados na ordem correta.

O mapeamento aproximado se parece com isso em muitos sistemas systemd:

Nível de execução tradicional Equivalente comum no systemd Significado
0 poweroff.target Desligar e desenergizar
1 rescue.target Modo de resgate de usuário único
3 multi-user.target Modo de texto/servidor multiusuário
5 graphical.target Modo multiusuário mais login gráfico
6 reboot.target Reinicializar

Trate isso como um auxílio de tradução, não como uma lei. O comportamento dos níveis de execução variava entre as distribuições, e os alvos do systemd podem expressar relacionamentos que os níveis de execução antigos não conseguiam.

Entendendo os Alvos do Systemd

Um alvo do systemd é em si um tipo de unidade. Quando uma unidade de alvo é ativada, o systemd tenta ativar todas as unidades listadas como dependências dentro do arquivo de unidade desse alvo. Isso cria um efeito em cascata, garantindo que todos os serviços, dispositivos e outros componentes necessários sejam colocados online para atingir o estado desejado do sistema.

Características Principais dos Alvos do Systemd:

  • Gerenciamento de Dependências: Os alvos definem quais outras unidades precisam estar ativas para que o alvo seja considerado alcançado. Este é o núcleo de seu poder.
  • Pontos de Sincronização: Eles atuam como pontos de sincronização durante o processo de inicialização. O sistema não prosseguirá para o próximo estágio até que o alvo atual esteja totalmente inicializado.
  • Nomenclatura Descritiva: Os alvos são nomeados descritivamente, facilitando a compreensão do estado pretendido do sistema (por exemplo, rescue.target, poweroff.target).

Os alvos geralmente não executam código de longa duração por si mesmos. Eles agrupam outras unidades. Você pode inspecionar esse agrupamento com:

systemctl list-dependencies multi-user.target
systemctl list-dependencies graphical.target

Esta é uma boa maneira de responder: "Por que este serviço inicia na inicialização?" Se a unidade aparecer na árvore de dependências para o alvo padrão, ela está sendo puxada em algum lugar.

Alvos Comuns do Systemd

O systemd vem com um conjunto de alvos predefinidos projetados para cobrir estados comuns do sistema. Entender estes é fundamental para gerenciar seu sistema.

multi-user.target

Este é um dos alvos mais fundamentais. Ele representa um sistema multiusuário totalmente funcional com rede habilitada, mas sem um gerenciador de login gráfico ou ambiente de desktop. Este é tipicamente o alvo padrão para servidores.

  • Propósito: Fornecer um ambiente estável para executar serviços e permitir que múltiplos usuários façam login via consoles baseados em texto ou SSH.
  • Dependências: Geralmente inclui unidades para rede, serviços do sistema e prompts de login do console.

Para servidores headless, multi-user.target geralmente é o padrão correto. Ele fornece SSH e serviços normais sem gastar recursos em um gerenciador de exibição.

graphical.target

Este alvo representa um sistema multiusuário totalmente funcional com um ambiente de desktop gráfico pronto para interação do usuário. É tipicamente um dependente de multi-user.target e adiciona os componentes necessários para uma sessão gráfica.

  • Propósito: Iniciar um gerenciador de exibição gráfica (como GDM, LightDM, SDDM) e o ambiente de desktop associado.
  • Dependências: Comumente puxa o comportamento de multi-user.target e adiciona unidades para um gerenciador de exibição e componentes de sessão gráfica.

Se uma estação de trabalho inicializar com uma tela preta, mas o SSH ainda funcionar, compare estes:

systemctl get-default
systemctl status display-manager.service
journalctl -u display-manager.service -b

O alvo padrão informa o que o sistema tentou alcançar. Os logs do gerenciador de exibição informam por que a camada gráfica subiu ou não.

rescue.target

Este alvo fornece um ambiente mínimo de usuário único. É usado principalmente para manutenção e recuperação do sistema. Ele ativa o sistema básico e um shell root, mas normalmente não inicia a rede ou serviços multiusuário.

  • Propósito: Fornecer um ambiente seguro para administradores de sistema realizarem tarefas de manutenção sem interferência de outros serviços.
  • Dependências: Conjunto mínimo de componentes essenciais do sistema e um shell root. A rede geralmente não está disponível a menos que você a inicie manualmente.

emergency.target

Este é ainda mais mínimo que rescue.target. Ele ativa o sistema com um único sistema de arquivos somente leitura e um shell root. É destinado a situações de emergência graves onde até mesmo serviços básicos podem ser problemáticos.

  • Propósito: Para recuperação crítica do sistema quando mesmo o rescue.target pode não ser apropriado.
  • Dependências: Apenas os componentes mais essenciais do sistema e um shell root. O sistema de arquivos raiz pode ser montado como somente leitura dependendo da falha e da distribuição.

reboot.target, poweroff.target, halt.target

Estes são alvos especiais usados para desligar ou reiniciar o sistema. Quando o systemd ativa um desses alvos, ele para todos os serviços em execução e então executa a ação especificada (reinicializar, desligar ou parar).

  • Propósito: Desligar ou reiniciar o sistema graciosamente.
  • Dependências: Eles tipicamente dependem de serviços que precisam ser parados antes que o sistema possa ser desligado.

Gerenciando Alvos do Systemd

O systemd fornece várias ferramentas de linha de comando para interagir com alvos. A ferramenta principal é systemctl.

Visualizando Alvos Atuais e Padrão

Para ver qual alvo o sistema está executando atualmente e para qual alvo ele padroniza na inicialização, use:

systemctl status

Este comando fornece uma riqueza de informações, incluindo o alvo ativo. Para consultar especificamente o alvo padrão:

systemctl get-default

Para ver todos os alvos disponíveis:

systemctl list-unit-files --type=target

Para ver unidades de alvo ativas, use:

systemctl list-units --type=target

A diferença é a mesma que com serviços: list-unit-files mostra arquivos de alvo que o systemd conhece, enquanto list-units mostra alvos atualmente carregados ou ativos no sistema em execução.

Alterando o Alvo Padrão

Se você deseja que seu sistema inicialize em um alvo diferente por padrão (por exemplo, de gráfico para multiusuário, ou vice-versa), você pode usar systemctl set-default:

Para definir o padrão como alvo gráfico (comum para sistemas desktop):

sudo systemctl set-default graphical.target

Para definir o padrão como alvo multiusuário (comum para servidores):

sudo systemctl set-default multi-user.target

Importante: Alterar o alvo padrão só terá efeito na próxima reinicialização.

Nos bastidores, isso altera o link simbólico default.target. Você pode inspecioná-lo diretamente se estiver depurando uma imagem de inicialização quebrada:

systemctl get-default
ls -l /etc/systemd/system/default.target

Alternando para um Alvo (Sem Reinicializar)

Você pode alternar o sistema para um alvo diferente imediatamente sem reinicializar. Isso é útil para testar ou alterar temporariamente o estado do sistema. Use o comando systemctl isolate:

Para alternar para o alvo gráfico:

sudo systemctl isolate graphical.target

Para alternar para o alvo multiusuário:

sudo systemctl isolate multi-user.target

Cuidado: systemctl isolate é um comando poderoso. Isolar para um alvo como rescue.target ou emergency.target irá parar a maioria dos serviços em execução. Certifique-se de entender as implicações antes de usá-lo. Você pode perder conectividade de rede ou sua sessão gráfica.

Em um servidor remoto, tenha cuidado especial com isolate rescue.target ou isolate emergency.target. Você pode perder SSH e precisar de acesso ao console através do seu provedor de nuvem, hipervisor ou máquina física. Se você só precisa parar o desktop gráfico em uma estação de trabalho, isolar para multi-user.target é menos drástico do que pular diretamente para o modo de resgate.

Como os Alvos se Relacionam com os Arquivos de Unidade

Os alvos são implementados como arquivos de unidade, tipicamente localizados em /usr/lib/systemd/system/ ou /etc/systemd/system/. Um arquivo de unidade de alvo (por exemplo, graphical.target) especifica dependências em outras unidades, incluindo outros alvos e serviços.

Um arquivo de unidade graphical.target típico pode se parecer com isto (simplificado):

[Unit]
Description=Graphical multi-user system
Documentation=man:systemd.special(7)
# This target is intended to be a prerequisite for the graphical login manager.
# It's the target that the system will boot into if not otherwise specified.
Wants=display-manager.service
Before=shutdown.target

[Install]
Alias=default.target

Aqui:

  • Wants=display-manager.service: Indica que display-manager.service (o gerenciador de login real como GDM ou LightDM) deve ser iniciado se possível. Esta é uma dependência mais fraca que Requires=.
  • Before=shutdown.target: Garante que o ambiente gráfico seja parado antes que o sistema entre no processo de desligamento.
  • Alias=default.target: Isso faz com que graphical.target atue como o padrão se default.target estiver vinculado a ele (o que geralmente é o caso para sistemas desktop).

Criando Alvos Personalizados

Embora menos comum para uso diário, você pode criar seus próprios alvos personalizados para definir estados específicos do sistema com conjuntos únicos de serviços.

Passos para Criar um Alvo Personalizado:

  1. Crie um arquivo de unidade .target: Coloque-o em /etc/systemd/system/ (por exemplo, my-custom.target).
    [Unit]
    Description=My Custom Target
    
    [Install]
    WantedBy=multi-user.target # Or another appropriate target
    
  2. Crie arquivos .service ou outras unidades: Defina os serviços e outras unidades que devem estar ativas para seu alvo personalizado.
  3. Adicione dependências: No arquivo de unidade do seu alvo personalizado, use Requires= ou Wants= para especificar quais unidades devem ou precisam ser iniciadas.
    [Unit]
    Description=My Custom Target
    Wants=service1.service
    Wants=service2.service
    After=service1.service service2.service
    
    [Install]
    WantedBy=multi-user.target
    
  4. Recarregue o systemd:
    
    

sudo systemctl daemon-reload 5. **Habilite/Inicie seu alvo:** bash sudo systemctl start my-custom.target # Or to make it bootable sudo systemctl enable my-custom.target ```

Caso de Uso: Imagine um ambiente de desenvolvimento onde você precisa de servidores de banco de dados e aplicativos específicos em execução. Você poderia criar um dev-env.target que inicia esses serviços.

Alvos personalizados também são úteis para sistemas do tipo appliance. Por exemplo, uma máquina de quiosque pode ter um alvo que inicia rede, um navegador, um watchdog local e um agente de log, mas não o resto de uma sessão de desktop normal. Um servidor de laboratório pode ter alvos separados para uma pilha de teste e uma pilha de demonstração para que os operadores possam iniciar um grupo conhecido de serviços juntos.

Melhores Práticas e Dicas

  • Entenda o Padrão: Conheça o alvo padrão do seu sistema (graphical.target ou multi-user.target), pois ele dita a experiência inicial de inicialização.
  • Use isolate com Cuidado: Esteja atento ao usar systemctl isolate, especialmente em sistemas de produção, pois pode interromper serviços em execução.
  • Verifique as Dependências: Se um serviço não está iniciando, examine as dependências do alvo ao qual está associado usando systemctl list-dependencies <nome_do_alvo>.
  • Servidor vs. Desktop: Em servidores, multi-user.target é quase sempre preferido por segurança e eficiência de recursos. Em desktops, graphical.target é padrão.
  • Manutenção do Sistema: Para tarefas que exigem interferência mínima, rescue.target é útil. Para recuperação crítica, emergency.target está disponível.

Uma Maneira Prática de Pensar Sobre Alvos

Para a maioria do trabalho de administração, você só precisa de um modelo mental curto:

systemctl get-default
systemctl set-default multi-user.target
systemctl isolate graphical.target
systemctl list-dependencies graphical.target

get-default informa para onde a máquina deve inicializar. set-default altera a próxima inicialização. isolate altera o estado atual e pode parar serviços fora desse estado. list-dependencies explica o que um alvo puxa.

Alvos não são apenas níveis de execução renomeados. Eles são grupos de dependência. Depois que você os trata dessa forma, os problemas de inicialização se tornam mais fáceis de raciocinar: encontre o alvo que o sistema tentou alcançar, inspecione os serviços que ele queria, então corrija a unidade ou dependência que falhou.