2 puntos por GN⁺ 2025-08-24 | Aún no hay comentarios. | Compartir por WhatsApp
  • Nitro es un sistema init y supervisor de procesos ultraligero que puede aplicarse a entornos embebidos, servidores, escritorios y contenedores
  • Guarda el estado del sistema solo en RAM, por lo que funciona sin problemas incluso en sistemas de archivos de solo lectura, y ofrece un diseño basado en eventos rápido y eficiente
  • Su configuración usa una estructura simple de directorios con scripts, lo que permite administrar servicios sin archivos de configuración complejos ni procesos de compilación adicionales
  • Soporta servicios parametrizados, reinicios robustos y logging confiable por servicio, entre otras funciones optimizadas para contenedores y entornos embebidos
  • Garantiza alta flexibilidad y control con funciones como control remoto mediante la herramienta nitroctl y control de comportamiento basado en señales

Descripción general

Nitro es un supervisor de procesos ultraligero que también puede usarse como pid 1 en Linux

Sus principales casos de uso son los siguientes

  • init para máquinas Linux de distintos usos, como embebidos, escritorios y servidores
  • init de initramfs en Linux
  • init para entornos de contenedores como Docker/Podman/LXC/Kubernetes
  • demonio de supervisión que funciona sin privilegios en sistemas POSIX

La configuración utiliza una estructura de scripts basada en directorios, y la ubicación predeterminada es /etc/nitro

Requisitos

  • Se requiere soporte del kernel para sockets Unix
  • Se requiere tmpfs o un directorio /run con escritura habilitada

Ventajas frente a otros sistemas

  • Toda la información de estado se mantiene solo en RAM, por lo que funciona en sistemas de archivos raíz de solo lectura sin trucos adicionales
  • Proporciona eficiencia con un modo de operación basado en eventos, sin polling
  • No hay asignación dinámica de memoria durante la ejecución
  • Los descriptores de archivo no se consumen indefinidamente
  • Solo se necesita un binario autocontenido (con un binario de control adicional de forma opcional)
  • No hace falta convertir ni compilar archivos de configuración; un servicio es simplemente un directorio con scripts
  • Soporta reinicio de servicios y cadena de logging
  • Funciona correctamente aunque el reloj del sistema no sea preciso
  • Puede ejecutarse en FreeBSD mediante /etc/ttys
  • Con musl libc se puede crear un binario estático ultrapequeño

Gestión de servicios

  • Cada directorio de servicio (por defecto dentro de /etc/nitro) puede incluir los siguientes archivos

    • setup: script (opcional) que se ejecuta antes de iniciar el servicio; el servicio solo puede iniciarse si termina correctamente (0)
    • run: script de ejecución del servicio; mientras no termine, el servicio se considera activo; si no está implementado, se trata como un servicio one-shot
    • finish: script (opcional) que se ejecuta después de que termine run; recibe como argumentos el estado de salida y el valor de la señal
    • log: enlace simbólico que apunta a otro directorio de servicio; conecta por pipe la salida de run con la entrada de ese servicio (útil para cadena de logging)
    • down: si este archivo existe, nitro no levanta ese servicio de manera predeterminada
    • Si el nombre del directorio termina en '@', se ignora y puede usarse como servicio parametrizado
    • El nombre del servicio debe tener menos de 64 caracteres y no puede incluir /, , ni saltos de línea
  • La utilidad chpst de runit resulta útil al escribir scripts run

Servicios especiales

  • LOG: servicio predeterminado para registrar logs de todos los servicios que no tengan enlace log
  • SYS: SYS/setup se ejecuta antes de iniciar todos los servicios y permite implementar un arranque ordenado de servicios
    • SYS/finish: se ejecuta antes de entrar en la fase completa de apagado
    • SYS/final: se ejecuta después de terminar todos los procesos
    • SYS/fatal: se ejecuta en lugar de salir si ocurre un error fatal (si existe)
    • SYS/reincarnate: se ejecuta en lugar de shutdown y puede usarse, por ejemplo, para reimplementar initramfs

Servicios parametrizados

  • Los directorios de servicio que terminan en '@' son ignorados por nitro, pero pueden especificarse directamente mediante enlaces simbólicos o el comando nitroctl
  • El parámetro después de '@' se pasa como primer argumento a cada script
    • Ejemplo: si existen los enlaces simbólicos agetty@/run y agetty@tty1, se ejecuta agetty@/run tty1
    • Al ingresar nitroctl up agetty@tty2, puede ejecutarse agetty@/run tty2 (sin importar si el directorio existe)

Modos de operación

  • El ciclo de vida completo consta de tres etapas: arranque, ejecución de servicios (supervisión) y apagado
    • Arranque: si existe el servicio especial SYS, se ejecuta desde setup, y luego se inician todos los servicios que no estén marcados como down
    • Si un servicio termina, se reinicia; pero si se reinició hace muy poco, espera 2 segundos
    • Es posible enviar la señal de apagado con nitroctl Reboot o Shutdown
      • En ese caso, la secuencia es SYS/finish → SIGTERM a todos los servicios (espera máxima de 7 segundos) → SIGKILL → SYS/final → secuencia de salida
    • En contenedores o en supervisores sin privilegios, solo terminan los procesos

Control con nitroctl

  • La herramienta de línea de comandos nitroctl permite controlar nitro de forma remota

Ejemplos de comandos:

  • list: muestra la lista de servicios, estado, PID, uptime y último estado de salida
  • up/down/start/stop/restart: controla inicio, detención y reinicio de servicios
  • Envío de señales: p(SIGSTOP), c(SIGCONT), h(SIGHUP), a(SIGALRM), i(SIGINT), q(SIGQUIT), 1(SIGUSR1), 2(SIGUSR2), t(SIGTERM), k(SIGKILL)
  • pidof: muestra el PID del servicio especificado
  • rescan: vuelve a leer el directorio de servicios y refleja servicios agregados o eliminados
  • Shutdown/Reboot: apaga o reinicia todo el sistema

Control mediante señales

  • Se puede controlar enviando señales directamente al proceso nitro
    • SIGHUP: reescaneo de servicios (rescan)
    • SIGINT: reinicio
    • SIGTERM: apagado (si nitro no es pid 1)

Nitro como init en Linux

  • Nitro puede arrancar directamente como pid 1 de Linux al ser un binario autocontenido
  • Monta /dev y /run cuando es necesario, y el resto del comportamiento se gestiona en SYS/setup
  • El evento Ctrl-Alt-Del activa un reinicio ordenado

Uso de Nitro como init en contenedores Docker

  • Nitro puede compilarse de forma estática e incluirse fácilmente en un contenedor
  • Debe existir /run dentro del contenedor para poder usar la ruta predeterminada del socket
  • Si el socket de control se monta con bind mount, se puede controlar de forma remota desde fuera con nitroctl

Nitro en FreeBSD

  • Se puede hacer que FreeBSD init supervise nitro agregando la siguiente línea a /etc/ttys
    /etc/nitro "/usr/local/sbin/nitro" "" on
    

Autor

Agradecimientos

  • Desarrollado a partir de un análisis detallado de sistemas de supervisión de procesos existentes como daemontools, freedt, runit, perp y s6

Licencia

  • Licencia 0BSD (consulta el archivo LICENSE para más detalles)

Aún no hay comentarios.

Aún no hay comentarios.