Como usar o systemd-nspawn para containers leves no Linux
1. Introdução ao systemd-nspawn e seus fundamentos
O systemd-nspawn é uma ferramenta nativa do ecossistema systemd que permite criar e gerenciar containers leves no Linux. Diferente de soluções como Docker e Podman, que focam em containers de aplicação, o systemd-nspawn opera no conceito de container de sistema — ou seja, ele simula um ambiente completo de sistema operacional dentro de um namespace isolado, permitindo rodar um init system (como o próprio systemd) e múltiplos serviços simultaneamente.
As principais diferenças entre systemd-nspawn e outras ferramentas incluem:
- Simplicidade: não requer daemon centralizado, repositórios de imagens ou camadas de abstração complexas
- Integração nativa com systemd: utiliza journald, cgroups e units do systemd para gerenciamento
- Leveza: consome menos recursos que máquinas virtuais e não exige overhead de runtime como o Docker
- Segurança: suporte nativo a namespaces de usuário, seccomp e restrições de capabilities
Pré-requisitos básicos incluem um kernel Linux com suporte a namespaces (PID, network, mount, UTS, IPC, user) e cgroups v2 (habilitados por padrão na maioria das distribuições modernas).
2. Instalação e configuração inicial do ambiente
A instalação do systemd-nspawn varia conforme a distribuição:
# Ubuntu/Debian
sudo apt install systemd-container
# Fedora
sudo dnf install systemd-container
# Arch Linux
sudo pacman -S systemd
Após a instalação, verifique se os módulos do kernel necessários estão ativos:
# Verificar namespaces disponíveis
ls /proc/self/ns/
# Verificar cgroups v2
mount | grep cgroup
O diretório padrão para armazenar containers é /var/lib/machines. Você pode alterar isso editando /etc/systemd/nspawn/ ou usando caminhos personalizados com machinectl.
3. Criação e gerenciamento de containers com systemd-nspawn
Para criar um container, utilize o debootstrap (no Debian/Ubuntu) ou ferramentas equivalentes:
# Criar um container Debian mínimo
sudo debootstrap --include=systemd,systemd-sysv,dbus bookworm /var/lib/machines/meu-container http://deb.debian.org/debian
Gerenciamento básico com machinectl:
# Iniciar o container
sudo machinectl start meu-container
# Acessar o shell
sudo machinectl login meu-container
# Executar comando diretamente
sudo machinectl shell meu-container /bin/bash
# Listar containers ativos
machinectl list
# Parar o container
sudo machinectl poweroff meu-container
Para criar containers a partir de outras distribuições:
# Fedora
sudo dnf --releasever=38 --installroot=/var/lib/machines/fedora-container install systemd passwd dnf
# OpenSUSE
sudo zypper --root=/var/lib/machines/opensuse-container install systemd patterns-base-minimal
4. Configuração de rede e volumes compartilhados
O systemd-nspawn oferece múltiplos modos de rede:
# Rede em modo host (container compartilha a rede do host)
sudo systemd-nspawn -D /var/lib/machines/meu-container --network-host
# Rede com bridge virtual (veth)
sudo systemd-nspawn -D /var/lib/machines/meu-container --network-veth
# Rede isolada (sem acesso externo)
sudo systemd-nspawn -D /var/lib/machines/meu-container --network-none
Para compartilhar diretórios entre host e container (bind mounts):
# Montar diretório /dados do host em /mnt/dados no container
sudo systemd-nspawn -D /var/lib/machines/meu-container \
--bind=/dados:/mnt/dados \
--network-veth
Para expor portas do container para a rede externa, combine bind mounts com configuração de roteamento no host:
# Criar bridge e configurar NAT
sudo ip link add br0 type bridge
sudo ip addr add 10.0.0.1/24 dev br0
sudo ip link set br0 up
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
5. Gerenciamento de recursos e isolamento avançado
Limitação de recursos com cgroups via opções do systemd-nspawn:
# Limitar CPU (50% de um core)
sudo systemd-nspawn -D /var/lib/machines/meu-container \
--cpu-quota=50%
# Limitar memória (512 MB)
sudo systemd-nspawn -D /var/lib/machines/meu-container \
--memory-high=512M --memory-max=768M
# Limitar I/O de disco (10 MB/s leitura, 20 MB/s escrita)
sudo systemd-nspawn -D /var/lib/machines/meu-container \
--read-write --property="IOReadBandwidthMax=/dev/sda 10M" \
--property="IOWriteBandwidthMax=/dev/sda 20M"
Isolamento de segurança com namespaces de usuário:
# Mapear usuário root do container para UID 100000 no host
sudo systemd-nspawn -D /var/lib/machines/meu-container \
--private-users=100000:65536 \
--private-users-chown
Sistema de arquivos read-only e tmpfs:
# Montar /var como tmpfs e /usr como read-only
sudo systemd-nspawn -D /var/lib/machines/meu-container \
--read-only \
--tmpfs=/var:size=512M
6. Integração com systemd e boot de containers
Para iniciar containers automaticamente como serviços systemd:
# Criar arquivo de configuração do container
sudo mkdir -p /etc/systemd/nspawn
sudo tee /etc/systemd/nspawn/meu-container.nspawn <<EOF
[Exec]
Boot=yes
PrivateUsers=100000:65536
[Network]
VirtualEthernet=yes
EOF
# Habilitar o serviço
sudo systemctl enable systemd-nspawn@meu-container.service
sudo systemctl start systemd-nspawn@meu-container.service
Para containers com suporte completo ao systemd (init):
# Iniciar com boot completo
sudo systemd-nspawn -b -D /var/lib/machines/meu-container
Logs do container ficam disponíveis via journald:
# Ver logs do container
journalctl -u systemd-nspawn@meu-container.service
# Ver logs dentro do container
sudo machinectl shell meu-container /bin/journalctl
7. Casos de uso práticos e boas práticas
Rodando serviços legados: isole aplicações antigas que exigem bibliotecas específicas em containers dedicados:
# Container para aplicação PHP 5.6
sudo debootstrap --include=php5.6,apache2 stretch /var/lib/machines/legado-php
sudo machinectl start legado-php
sudo machinectl shell legado-php /etc/init.d/apache2 start
Ambientes de desenvolvimento reproduzíveis: crie containers com ferramentas específicas para cada projeto:
# Container para desenvolvimento Python 3.11
sudo debootstrap bookworm /var/lib/machines/dev-python
sudo machinectl shell dev-python /bin/bash -c "apt install python3.11 python3-pip"
Backup e migração: containers systemd-nspawn são portáteis:
# Backup do container
sudo tar -czf meu-container-backup.tar.gz -C /var/lib/machines meu-container
# Migrar para outro host
scp meu-container-backup.tar.gz usuario@outro-host:/tmp/
ssh usuario@outro-host "sudo tar -xzf /tmp/meu-container-backup.tar.gz -C /var/lib/machines"
8. Troubleshooting e limitações comuns
Problemas de DNS: configure manualmente o resolv.conf:
# Dentro do container
echo "nameserver 8.8.8.8" > /etc/resolv.conf
echo "nameserver 1.1.1.1" >> /etc/resolv.conf
Erros de permissão: verifique mapeamento de UIDs:
# Verificar UIDs mapeados
sudo cat /proc/$(machinectl show meu-container -p Leader)/uid_map
Limitações conhecidas:
- Não suporta orquestração nativa (como Kubernetes)
- Gerenciamento de rede manual comparado ao Docker
- Sem registro centralizado de imagens (como Docker Hub)
- Performance de I/O inferior a máquinas virtuais em alguns cenários
Referências
- Documentação oficial do systemd-nspawn — Página de manual completa com todas as opções e flags disponíveis
- Arch Linux Wiki: systemd-nspawn — Guia prático e detalhado com exemplos de configuração avançada
- Debian Wiki: systemd-nspawn — Tutorial oficial do Debian sobre criação e gerenciamento de containers
- Fedora Magazine: Getting started with systemd-nspawn — Artigo introdutório com exemplos práticos para iniciantes
- Linux Journal: systemd-nspawn Containers — Artigo técnico aprofundado sobre casos de uso e boas práticas
- FreeDesktop.org: systemd-nspawn Container Interface — Documentação do machinectl para gerenciamento de containers
- DigitalOcean: How to Use systemd-nspawn — Tutorial passo a passo com configuração de rede e volumes