O Guia Definitivo de systemd para Administradores de Sistemas Modernos

Por que systemd é a espinha dorsal da infraestrutura Linux atual

Para administradores e engenheiros DevOps, systemd é mais do que um init: é um conjunto coerente de ferramentas para inicialização, orquestração de serviços, logging e políticas de segurança no espaço usuário. Neste guia técnico vamos a fundo em arquivos de unidade, timers, isolamento, políticas de segurança e automação (IaC). Exemplos práticos, snippets CLI e templates de configuração permitem integração direta em pipelines de provisionamento.

Arquitetura de unidades: tipos, targets e dependências

Systemd organiza o runtime em unidades (units). Principais tipos: service, socket, target, mount, automount, timer, path, scope e slice. Targets agrupam unidades para fases de boot e níveis lógicos (equivalente moderno aos runlevels).

Dependências e ordem são declaradas com campos como Wants, Requires, After, Before, Conflicts e PartOf. Exemplo mínimo de unidade:

[Unit]
Description=app-api service
After=network.target

[Service]
Type=simple
User=app
ExecStart=/usr/local/bin/app --config /etc/app/config.yml
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Para ativar e controlar:

sudo systemctl daemon-reload
sudo systemctl enable --now app-api.service
sudo systemctl status app-api.service

Templating e instância de unidades: patterns @

Unidades templadas permitem múltiplas instâncias com o mesmo arquivo. Exemplo: criar /etc/systemd/system/[email protected]:

[Unit]
Description=worker instance %i
After=network.target

[Service]
Type=simple
User=worker
ExecStart=/usr/local/bin/worker --id %i
Restart=always

[Install]
WantedBy=multi-user.target

Instanciar e gerenciar:

sudo systemctl enable --now [email protected]
sudo systemctl start [email protected]
sudo systemctl status 'worker@*.service'

Overrides e drop-ins: versão controlada por IaC

Evite editar arquivos em /lib/systemd/system diretamente. Use drop-ins em /etc/systemd/system/<unit>.service.d/override.conf para sobrescrever settings. Exemplo de drop-in para ajustar limites de recursos e nome de grupo:

[Service]
User=app
Group=app
LimitNOFILE=65536

Com Ansible é trivial gerenciar drop-ins idempoticamente:

- name: Deploy systemd drop-in for app
  copy:
    dest: /etc/systemd/system/app-api.service.d/override.conf
    content: |
      [Service]
      LimitNOFILE=65536
  notify:
    - systemd daemon-reload

- name: Start app
  systemd:
    name: app-api.service
    enabled: yes
    state: started

handlers:
  - name: systemd daemon-reload
    command: systemctl daemon-reload

Timers systemd como substituto programático do cron

Timers oferecem precisão, dependência e melhor observabilidade. Exemplo: job que roda diariamente às 02:30 e aguarda um serviço:

# /etc/systemd/system/db-backup.service
[Unit]
Description=Database backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-db --output /var/backups/db.sql

# /etc/systemd/system/db-backup.timer
[Unit]
Description=Daily DB backup timer

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target

Ative com:

sudo systemctl enable --now db-backup.timer
sudo systemctl list-timers --all

Logging e investigação: journalctl e persistência

O journal unifica logs binários com campos estruturados. Comandos essenciais:

# logs recentes do serviço
sudo journalctl -u app-api.service --no-pager

# seguir em tempo real
sudo journalctl -u app-api.service -f

# filtrar por prioridade
sudo journalctl -p err -u app-api.service

# logs entre timestamps
sudo journalctl --since "2026-01-01 00:00:00" --until "2026-01-01 01:00:00"

Habilitar journal persistente em /etc/systemd/journald.conf (Storage=persistent) e controlar rotação com SystemMaxUse. Para enviar logs a sistemas centralizados, use journald-remote/journal-gatewayd ou rode um agente (Vector, Fluentd) que leia /var/log/journal.

Isolamento forte: opções de segurança do unit file

Systemd expõe many sandboxing flags. Combine para reduzir blast radius de processos: PrivateTmp, ProtectSystem, ProtectHome, NoNewPrivileges, CapabilityBoundingSet, SystemCallFilter.

[Service]
ExecStart=/usr/local/bin/app
User=app
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
NoNewPrivileges=yes
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
SystemCallFilter=@default @network-io

Teste incrementalmente. Para descobrir falhas de permissões use Journal e strace combinados (strace -f -p <pid>).

Gerenciamento de diretórios temporários: tmpfiles.d e runtime

Crie regras em /etc/tmpfiles.d/ para manter permissões e criar runtime dirs. Exemplo para /var/run/app:

# /etc/tmpfiles.d/app.conf
d /var/run/app 0750 app app -

Integre com unit file adicionando RuntimeDirectory=app, que delega criação com dono correto:

[Service]
RuntimeDirectory=app
RuntimeDirectoryMode=0750

Políticas de falha e limitação: StartLimit e Restart

Evite ciclos de crash-loop com StartLimitBurst, StartLimitIntervalSec e RestartSec. Configurações recomendadas para serviços críticos:

[Unit]
StartLimitBurst=5
StartLimitIntervalSec=60

[Service]
Restart=on-failure
RestartSec=10

Automação completa: Ansible, cloud-init e Dockerfile com systemd

Exemplos de IaC para provisionar unit files e garantir idempotência.

Ansible: deploy unit e enable

- name: Deploy systemd unit
  copy:
    src: files/app-api.service
    dest: /etc/systemd/system/app-api.service
    mode: '0644'
  notify: systemd-reload

- name: Enable service
  systemd:
    name: app-api.service
    enabled: yes
    state: started

cloud-init (user-data) para instâncias na nuvem:

#cloud-config
write_files:
  - path: /etc/systemd/system/app-api.service
    permissions: '0644'
    content: |-
      [Unit]
      Description=app-api service
      After=network.target

      [Service]
      ExecStart=/usr/local/bin/app
      Restart=on-failure

      [Install]
      WantedBy=multi-user.target
runcmd:
  - systemctl daemon-reload
  - systemctl enable --now app-api.service

Rodando systemd em container (quando necessário) — WARNING: requer privilégios e ajustes:

# Dockerfile (exemplo para debug/CI, não produção)
FROM ubuntu:22.04
ENV container docker
RUN apt-get update && apt-get install -y systemd systemd-sysv && 
    systemctl mask dev-mqueue.mount
STOPSIGNAL SIGRTMIN+3
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/sbin/init"]

Executar com Docker: docker run –privileged –tmpfs /run –tmpfs /run/lock -v /sys/fs/cgroup:/sys/fs/cgroup:ro image

Observabilidade e integração com orquestradores

Em ambientes modernos você provavelmente executa workloads em Kubernetes, Nomad ou como containers gerenciados. Para serviços de sistema host-based (sidecars de infra, agentes de logging, proxies), documente o design de integração: qual target aciona dependências, quais sockets são ativados por socket-activation e como os timers substituem cron jobs. Socket activation reduz uso de recursos e acelera boot quando combinado com Targets e on-demand activation.

Checklist prático para implantação segura e automatizada

  • Versionar unit files e drop-ins em Git junto ao código/infra.
  • Gerar e testar unit templates em ambientes de staging com CI (unit tests + systemd-nspawn).
  • Aplicar sandboxing progressivo e inspecionar falhas via journalctl.
  • Preferir timers sobre cron para jobs que dependem de serviços gerenciados por systemd.
  • Automatizar daemon-reload e restart via handlers em Ansible/terraform provisioner.
  • Documentar dependências Between units (Wants/Requires/After) para evitar startup races.

Referências práticas e próximos passos para produção

Implemente um pipeline: unit files em repo –> CI valida syntax/execStart em sandbox (–systemd-run ou systemd-nspawn) –> CD aplica como change set (ansible/terraform/ignition) que cria drop-ins e executa daemon-reload/start. Centralize logs do journal para um agregador (Loki/ELK/Graylog) para correlação e alerting. Teste políticas de segurança com ferramentas como seccomp-bpf e auditd integradas ao journal.

Aplicando os padrões deste guia você transforma systemd em uma camada controlável, auditável e escalável dentro da sua arquitetura — com práticas de Infrastructure as Code para garantir reprodutibilidade e segurança.