- Nitro é um sistema init e supervisor de processos ultracompacto que pode ser usado em embarcados, servidores, desktops e contêineres
- Armazena o estado do sistema apenas na RAM, funcionando sem dificuldade mesmo em sistemas de arquivos somente leitura, e oferece um design rápido e eficiente baseado em eventos
- A forma de configuração usa uma estrutura simples de diretórios com scripts, permitindo gerenciar serviços sem arquivos de configuração complexos nem processos de build adicionais
- Suporta serviços parametrizados, reinicialização robusta e logging confiável por serviço, entre outros recursos otimizados para contêineres e ambientes embarcados
- Garante alta flexibilidade e controle com controle remoto via a ferramenta nitroctl e controle de comportamento baseado em sinais
Visão geral
Nitro é um supervisor de processos ultracompacto que também pode ser usado como pid 1 no Linux
As principais áreas de uso são:
- init para máquinas Linux de vários tipos, como embarcados, desktops e servidores
- init do Linux initramfs
- init para ambientes de contêineres como Docker/Podman/LXC/Kubernetes
- daemon de supervisão que funciona sem privilégios em sistemas POSIX
A configuração usa uma estrutura de scripts baseada em diretórios, e o local padrão é /etc/nitro
Requisitos
- suporte a sockets Unix no kernel
tmpfsou um diretório/rungravável
Vantagens em relação a outros sistemas
- Todas as informações de estado ficam apenas na RAM, então funciona em sistemas de arquivos raiz somente leitura sem truques extras
- Operação baseada em eventos, sem polling, para maior eficiência
- Sem alocação dinâmica de memória durante a execução
- Não consome descritores de arquivo indefinidamente
- Requer apenas um binário autocontido (com um binário de controle adicional como opção)
- Não é necessário converter nem compilar arquivos de configuração; um serviço é apenas um diretório simples com scripts
- Suporte a cadeias de reinício de serviços e de logging
- Funciona normalmente mesmo que o relógio do sistema não esteja correto
- Pode ser executado no FreeBSD via
/etc/ttys - Com musl libc, é possível gerar um binário estático ultracompacto
Gerenciamento de serviços
-
Cada diretório de serviço (por padrão dentro de
/etc/nitro) pode conter os seguintes arquivossetup: script (opcional) executado antes do início do serviço; o serviço só pode iniciar se terminar com sucesso (0)run: script de execução do serviço; enquanto não terminar, o serviço é considerado ativo; se não for implementado, é tratado como um serviço one-shotfinish: script (opcional) executado após o término derun, recebendo como argumentos o status de saída e o valor do sinallog: link simbólico apontando para outro diretório de serviço, conectando a saída derunà entrada desse serviço por pipe (permitindo usar cadeias de logging)down: se este arquivo existir, o nitro não sobe esse serviço por padrão- Se o nome do diretório terminar com
@, ele será ignorado e poderá ser usado como serviço parametrizado - O nome do serviço deve ter menos de 64 caracteres e não pode conter
/,,nem quebras de linha
-
O utilitário
chpstdo runit é útil ao escrever scriptsrun
Serviços especiais
LOG: serviço padrão para registrar logs de todos os serviços que não têm linklogSYS:SYS/setupé executado antes de todos os serviços, permitindo implementar inicialização ordenada de serviçosSYS/finish: executado antes de entrar na etapa de desligamento geralSYS/final: executado após o encerramento de todos os processosSYS/fatal: executado no lugar do encerramento em caso de erro fatal (se existir)SYS/reincarnate: executado no lugar de shutdown, podendo ser usado, por exemplo, para reimplementar initramfs
Serviços parametrizados
- Diretórios de serviço terminados em
@são ignorados pelo nitro, mas podem ser especificados diretamente por link simbólico ou pelo comandonitroctl - O parâmetro após
@é passado como primeiro argumento para cada script- Exemplo: se existirem os links simbólicos
agetty@/runeagetty@tty1, entãoagetty@/run tty1será executado - Ao executar
nitroctl up agetty@tty2, é possível rodaragetty@/run tty2(independentemente da existência do diretório)
- Exemplo: se existirem os links simbólicos
Modos de operação
- Todo o ciclo de vida é composto por três etapas: boot, execução de serviços (supervisão) e encerramento
- Boot: se o serviço especial
SYSexistir, ele é executado a partir desetup, e depois todos os serviços non-down são iniciados - Quando um serviço termina, ele é reiniciado; porém, se a reinicialização mais recente tiver ocorrido muito rapidamente, há uma espera de 2 segundos
- É possível enviar um sinal de desligamento com
nitroctl RebootouShutdown- Nesse caso:
SYS/finish→ SIGTERM para todos os serviços (espera máxima de 7 segundos) → SIGKILL →SYS/final→ sequência de encerramento
- Nesse caso:
- Em contêineres ou quando usado como supervisor sem privilégios, apenas os processos são encerrados
- Boot: se o serviço especial
Controle com nitroctl
- A ferramenta de linha de comando nitroctl permite controlar o nitro remotamente
Exemplos de comandos:
- list: mostra lista de serviços, estado, PID, uptime e último status de saída
- up/down/start/stop/restart: controla início, parada e reinício de serviços
- envio de sinais: p(SIGSTOP), c(SIGCONT), h(SIGHUP), a(SIGALRM), i(SIGINT), q(SIGQUIT), 1(SIGUSR1), 2(SIGUSR2), t(SIGTERM), k(SIGKILL)
- pidof: imprime o PID do serviço especificado
- rescan: relê o diretório de serviços e aplica adições/remoções
- Shutdown/Reboot: desliga ou reinicia todo o sistema
Controle por sinais
- Também é possível controlar enviando sinais diretamente ao processo nitro
- SIGHUP: reescaneia serviços (rescan)
- SIGINT: reinicializa
- SIGTERM: encerra (se o nitro não for pid 1)
Nitro como init no Linux
- Nitro é um binário autocontido que pode inicializar diretamente como pid 1 no Linux
- Monta
/deve/runquando necessário, e o restante do comportamento é tratado emSYS/setup - O evento Ctrl-Alt-Del aciona uma reinicialização ordenada
Usando Nitro como init em contêiner Docker
- Nitro pode ser compilado estaticamente e incluído facilmente em um contêiner
/runprecisa existir no contêiner para usar o caminho padrão do socket- Se o socket de controle for montado com bind mount, é possível fazer controle remoto externo com
nitroctl
Nitro no FreeBSD
- É possível fazer o init do FreeBSD supervisionar o nitro adicionando a seguinte linha em
/etc/ttys/etc/nitro "/usr/local/sbin/nitro" "" on
Autor
- Leah Neukirchen leah@vuxu.org
Agradecimentos
- Desenvolvido com base em uma análise detalhada de sistemas existentes de supervisão de processos como daemontools, freedt, runit, perp e s6
Licença
- Licença 0BSD (consulte o arquivo LICENSE para mais detalhes)
Ainda não há comentários.