`systemctl`: gestión y diagnóstico de servicios en systemd

systemctl es la herramienta de línea de comandos que te permite hablar con el demonio systemd (PID 1). No es un envoltorio cosmético: cada subcomando que ejecutas se traduce en una llamada D-Bus al proceso init, que responde con estado, ejecuta cambios o persiste configuración en disco. Entender esta distinción —que systemctl es un cliente y systemd el servidor— explica por qué ciertos cambios requieren pasos explícitos como daemon-reload: el cliente no sabe automáticamente que los archivos en disco cambiaron, hay que decírselo.

El diseño de systemctl separa intencionalmente dos ejes ortogonales: el estado en tiempo de ejecución (activo/inactivo ahora mismo) y el estado persistente en el arranque (habilitado/deshabilitado para futuros boots). Mezclarlos mentalmente es la fuente de la mayoría de errores de configuración: un servicio puede estar corriendo ahora y no arrancar en el próximo boot, o estar habilitado y estar caído en este momento. Cada eje se gestiona con verbos distintos.

Úsalo siempre que necesites arrancar, detener, inspeccionar o configurar unidades de systemd —servicios, timers, sockets, mounts—. Si estás escribiendo un script de automatización o de despliegue, los subcomandos is-active e is-enabled te devuelven exit codes limpios (0 = sí, distinto de 0 = no) sin texto que parsear, lo que los hace ideales para condicionales de shell.

Lo que se rompe si no conoces bien esta herramienta es predecible: reinicias un servicio cuando solo necesitabas recargar su configuración (interrumpiendo conexiones activas), olvidas daemon-reload tras editar un unit file y te quedas preguntando por qué systemd ignora tus cambios, o habilitas un servicio sin arrancarlo esperando que ya esté activo.

# Escenario: instalar nginx, ajustar su configuración y dejarlo
# correctamente gestionado en producción.

# 1. Instalar nginx (crea el unit file en /lib/systemd/system/nginx.service)
apt install -y nginx

# 2. Habilitar E arrancar en un solo paso.
#    --now equivale a: enable + start en una sola llamada.
systemctl enable --now nginx

# Verificar estado completo: muestra si está activo, enabled,
# el PID, uso de memoria, y los últimos logs del journal.
systemctl status nginx

# 3. Editar la configuración de nginx y recargar SIN cortar conexiones.
#    reload le manda SIGHUP al proceso; nginx recarga sus workers.
#    Solo funciona si el servicio implementa recarga — no todos lo hacen.
nano /etc/nginx/sites-available/default
nginx -t                  # validar antes de aplicar
systemctl reload nginx

# 4. Si cambiaste el unit file mismo (no la config de la aplicación),
#    systemd necesita releer el disco antes de cualquier otra operación.
#    Sin este paso, systemd opera con la definición anterior en memoria.
nano /lib/systemd/system/nginx.service   # hipotético — en producción usa override
systemctl daemon-reload
systemctl restart nginx   # stop + start completo; corta conexiones activas

# 5. Crear un override drop-in sin tocar el unit file original.
#    Abre $EDITOR con una plantilla en /etc/systemd/system/nginx.service.d/override.conf
#    Al guardar, el archivo queda en disco pero aún no está activo.
systemctl edit nginx
systemctl daemon-reload   # siempre después de editar unit files o drop-ins
systemctl restart nginx

# 6. Checks programáticos — útiles en scripts de despliegue.
#    Exit code 0 = condición verdadera; cualquier otro valor = falsa.
systemctl is-active nginx   && echo "nginx está corriendo"
systemctl is-enabled nginx  && echo "nginx arranca en el boot"

# 7. Ver todos los servicios cargados y su estado actual.
systemctl list-units --type=service

# 8. Si necesitas sacarlo del arranque sin detenerlo ahora:
systemctl disable nginx

# Y si quieres pararlo y deshabilitarlo de una vez:
systemctl disable --now nginx

Qué está pasando en cada paso

El paso 2 con enable --now es el más importante de aprender. enable por sí solo crea un symlink en el target de arranque correspondiente —típicamente /etc/systemd/system/multi-user.target.wants/nginx.service— pero no toca el proceso en ejecución. --now añade el start implícito. Sin --now, tras un apt install el servicio normalmente ya está corriendo (el paquete Debian lo arranca en el postinst), pero no está habilitado para el siguiente boot. Con --now consolidas ambas cosas.

reload en el paso 3 merece atención especial. nginx implementa recarga limpia: cuando recibe SIGHUP, el proceso maestro valida la nueva configuración, lanza workers nuevos y espera a que los viejos terminen sus conexiones activas antes de matarlos. restart no hace eso —mata el proceso y lo vuelve a crear—, lo que genera un hueco de disponibilidad aunque sea de milisegundos. En un balanceador de carga eso puede pasar desapercibido; en un servicio que gestiona estado en memoria, puede ser catastrófico. La regla: si el servicio soporta reload, úsalo.

El daemon-reload del paso 4 es un error clásico omitir. systemd mantiene en memoria las definiciones de las unidades que ya ha procesado. Si editas /lib/systemd/system/nginx.service o creas un drop-in en /etc/systemd/system/nginx.service.d/, systemd no detecta ese cambio automáticamente —no hay inotify watch sobre esos directorios en este contexto—. daemon-reload fuerza la relectura. Hasta que no lo ejecutas, cualquier restart o start posterior usa la definición antigua.

El paso 5 con systemctl edit es la forma correcta de personalizar un unit file en Debian. Los archivos en /lib/systemd/system/ son propiedad del paquete y el próximo apt upgrade puede sobreescribirlos. systemctl edit crea automáticamente /etc/systemd/system/nginx.service.d/override.conf con una plantilla vacía. Solo escribes las directivas que quieres sobreescribir —por ejemplo LimitNOFILE=65536 o Environment=NGINX_ENVVAR=valor—; el resto hereda del unit original. Después del daemon-reload, systemd fusiona el drop-in sobre la definición base.

Los checks del paso 6 son los que separan los scripts que funcionan de los que funcionan a veces. Parsear la salida de systemctl status en un script es frágil: el formato puede cambiar entre versiones, el texto varía con el locale, y capturar la salida completa es innecesariamente costoso. is-active y is-enabled devuelven un exit code limpio y además imprimen el estado en una palabra (active, inactive, enabled, disabled) por si quieres usarlo con $(...). En un health check de un script de despliegue, el patrón es simplemente systemctl is-active nginx || systemctl start nginx.

list-units --type=service en el paso 7 muestra por defecto solo las unidades cargadas —las que systemd tiene en memoria, ya sea porque están activas, porque fallaron, o porque fueron activadas en esta sesión—. Si quieres ver todas las definidas en disco, incluyendo las deshabilitadas que nunca se han cargado, añade --all. Añade --state=failed para ver solo las que tienen problemas, que es el primer lugar donde mirar en un sistema con comportamiento extraño al arranque.

66

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Scroll al inicio