Systemd: gerenciando serviços no Linux
1. Introdução ao Systemd no contexto DevOps
Systemd é o sistema de init e gerenciador de serviços padrão na maioria das distribuições Linux modernas. Ele substituiu o antigo SysVinit, oferecendo paralelismo na inicialização, dependências declarativas e monitoramento ativo de processos. Para profissionais DevOps, dominar Systemd é essencial porque:
- Serviços críticos como Docker Engine, containerd e kubelet são gerenciados por ele
- Permite criar serviços customizados para aplicações que rodam em contêineres
- Oferece controle granular sobre dependências e ordem de inicialização
- Substitui scripts de inicialização frágeis por arquivos de configuração declarativos
Diferente do SysVinit, que usava scripts shell sequenciais, Systemd usa arquivos de unidade (unit files) que descrevem serviços, sockets, dispositivos e timers de forma padronizada. Essa abordagem é fundamental para ambientes de contêineres, onde múltiplos serviços precisam iniciar na ordem correta.
2. Comandos essenciais para gerenciamento de serviços
O comando systemctl é a principal ferramenta para interagir com Systemd. Veja os comandos mais usados no dia a dia DevOps:
# Verificar status de um serviço
systemctl status docker.service
# Iniciar/parar/reiniciar um serviço
systemctl start docker.service
systemctl stop docker.service
systemctl restart docker.service
# Habilitar/desabilitar inicialização automática
systemctl enable docker.service
systemctl disable docker.service
# Listar todas as unidades ativas
systemctl list-units --type=service
# Listar dependências de um serviço
systemctl list-dependencies docker.service
# Verificar se um serviço está ativo
systemctl is-active docker.service
Em ambientes produtivos, enable e disable são cruciais para garantir que serviços essenciais como Docker e kubelet iniciem automaticamente após uma reinicialização do servidor.
3. Criando e editando unit files (serviços customizados)
Um arquivo .service possui três seções principais. Veja um exemplo prático para uma aplicação Node.js:
[Unit]
Description=API de Microsserviço Node.js
Documentation=https://docs.exemplo.com/api
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/minha-api
ExecStart=/usr/bin/node /opt/minha-api/server.js
Restart=always
RestartSec=10
Environment=NODE_ENV=production
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Principais diretivas:
- Restart=always: reinicia automaticamente se o processo falhar
- RestartSec: tempo de espera antes de reiniciar
- After: define ordem de inicialização
- Requires: dependência obrigatória
Para ativar o serviço:
sudo systemctl daemon-reload
sudo systemctl enable minha-api.service
sudo systemctl start minha-api.service
4. Gerenciamento de dependências e ordem de inicialização
Controlar a sequência de inicialização é vital em ambientes com múltiplos contêineres. As principais diretivas são:
[Unit]
Description=App com dependência de banco
After=docker.service postgres.service
Requires=docker.service
Wants=redis.service
BindsTo=postgres.service
PartOf=minha-aplicacao.target
After: define que este serviço inicia após os listadosRequires: se o serviço falhar, este também falhaWants: dependência opcional (não quebra se falhar)BindsTo: serviço fortemente acoplado (se parar, este para junto)PartOf: agrupa serviços em um target comum
Exemplo prático: serviço que só inicia após o Docker Engine estar pronto:
[Unit]
Description=Worker de processamento
After=docker.service
Requires=docker.service
[Service]
ExecStartPre=/usr/bin/docker pull minha-imagem:latest
ExecStart=/usr/bin/docker run --rm minha-imagem:latest
ExecStopPost=/usr/bin/docker system prune -f
5. Logs e monitoramento com journald
Systemd integra logging via journald, acessível com journalctl. Comandos essenciais para DevOps:
# Ver logs de um serviço específico
journalctl -u docker.service
# Últimos 50 logs com atualização contínua
journalctl -u kubelet.service -n 50 -f
# Logs das últimas 2 horas
journalctl -u containerd.service --since "2 hours ago"
# Logs por prioridade (0=emerg, 3=err, 6=info)
journalctl -u docker.service -p err
# Exportar logs para análise
journalctl -u kubelet.service --output=json > kubelet-logs.json
Para integrar com sistemas externos como Fluentd (usado em clusters Kubernetes), configure o rsyslog:
# /etc/rsyslog.d/journal-forward.conf
module(load="imjournal")
*.* action(type="omfwd" target="fluentd-host" port="514" protocol="tcp")
6. Timers do Systemd (substituto do cron para DevOps)
Timers oferecem mais controle que o cron tradicional. Exemplo: limpeza automática de imagens Docker:
# /etc/systemd/system/docker-cleanup.service
[Unit]
Description=Limpeza de imagens Docker não utilizadas
[Service]
Type=oneshot
ExecStart=/usr/bin/docker image prune -af
# /etc/systemd/system/docker-cleanup.timer
[Unit]
Description=Timer para limpeza de imagens Docker
[Timer]
OnCalendar=daily
OnBootSec=10min
RandomizedDelaySec=30min
Persistent=true
[Install]
WantedBy=timers.target
Ativando o timer:
sudo systemctl daemon-reload
sudo systemctl enable docker-cleanup.timer
sudo systemctl start docker-cleanup.timer
Diretivas de tempo:
- OnCalendar: agendamento estilo cron (daily, weekly, Mon..Fri 02:00:00)
- OnUnitActiveSec: executa X tempo após última ativação
- OnBootSec: executa X tempo após boot
7. Systemd e Docker: integração prática
Serviços Systemd podem gerenciar contêineres Docker diretamente. Exemplo de serviço que mantém um contêiner sempre rodando:
[Unit]
Description=Contêiner Nginx gerenciado por Systemd
After=docker.service
Requires=docker.service
[Service]
ExecStartPre=-/usr/bin/docker rm -f nginx-app
ExecStart=/usr/bin/docker run --name nginx-app -p 8080:80 nginx:latest
ExecStop=/usr/bin/docker stop nginx-app
ExecStopPost=/usr/bin/docker rm -f nginx-app
Restart=always
RestartSec=5
TimeoutStartSec=60
[Install]
WantedBy=multi-user.target
Para controle de recursos:
[Service]
CPUQuota=50%
MemoryMax=256M
MemoryHigh=200M
O ExecStartPre com - ignora erros (útil se o contêiner não existir ainda).
8. Boas práticas para ambientes Kubernetes
Em clusters Kubernetes, Systemd gerencia os componentes críticos:
# Verificar status do kubelet
systemctl status kubelet.service
# Verificar dependências do kubelet
systemctl list-dependencies kubelet.service
# Logs de falha do containerd
journalctl -u containerd.service -p err --since "1 hour ago"
Configuração típica para workers:
[Unit]
Description=Kubernetes Kubelet
Documentation=https://kubernetes.io/docs/
After=containerd.service
Wants=containerd.service
Requires=network.target
[Service]
ExecStart=/usr/bin/kubelet \
--container-runtime=remote \
--container-runtime-endpoint=unix:///run/containerd/containerd.sock
Restart=always
RestartSec=10
CPUQuota=80%
[Install]
WantedBy=multi-user.target
Troubleshooting rápido:
# Diagnóstico de falha no kubelet
systemctl status kubelet.service
journalctl -u kubelet.service -n 100 --no-pager
# Verificar se containerd está rodando
systemctl is-active containerd.service
# Ver dependências não atendidas
systemctl list-dependencies kubelet.service --reverse
Systemd é a espinha dorsal da inicialização e gerenciamento de serviços no Linux moderno. Para profissionais DevOps, dominar seus comandos, unit files e integração com Docker/Kubernetes é indispensável para manter ambientes estáveis, diagnosticáveis e automatizados.
Referências
- Documentação oficial do Systemd — Referência completa sobre unit files, diretivas e configuração de serviços.
- Red Hat - Gerenciamento de serviços com systemd — Guia prático da Red Hat sobre systemctl, targets e troubleshooting.
- DigitalOcean - Systemd Timers vs Cron — Tutorial detalhado sobre criação de timers para automação de tarefas.
- Kubernetes - Configurando kubelet com systemd — Documentação oficial sobre integração do kubelet com systemd em clusters.
- Docker - Configuração de daemon com systemd — Guia oficial para configurar o Docker Engine como serviço systemd, incluindo variáveis de ambiente e recursos.
- Arch Linux Wiki - Systemd — Wiki com exemplos avançados de unit files, timers e integração com contêineres.