Cambiaste /lib/systemd/system/something.service a las 2 a.m., el servicio “funcionó”, y luego una actualización de paquete deshizo silenciosamente tu arreglo.
Ahora estás frente a un bucle de reinicio, preguntándote qué parte de tu memoria te está engañando.
Ubuntu 24.04 es territorio systemd. La acción correcta casi nunca es “editar el archivo unit del proveedor”. La acción correcta son los overrides: drop-ins,
claros, auditables y reversibles. Obtienes el arreglo sin fragilidad—y dejas de perder contra dpkg.
El modelo mental: qué lee systemd y en qué orden
systemd es un combinador de configuración. No “carga un archivo de servicio”. Construye la configuración final de la unidad desde múltiples capas y luego la ejecuta.
Si lo tratas como un único archivo, seguirás llevándote sorpresas.
De dónde vienen los unit files (Ubuntu 24.04)
En Ubuntu verás comúnmente:
/lib/systemd/system/: unit files del proveedor (instalados por paquetes). No son tuyos./etc/systemd/system/: overrides del administrador y unidades personalizadas. Estos sí son tuyos./run/systemd/system/: unidades en tiempo de ejecución y drop-ins transitorios. Efímeros; duran hasta el reinicio.
La prioridad es efectivamente: /etc gana sobre /run gana sobre /lib (con matices), además de los drop-ins aplicados en orden lexicográfico.
La regla práctica sigue siendo útil: si quieres una solución estable, ponla en /etc.
Drop-ins: el escalpelo limpio
El mecanismo canónico de override es un archivo drop-in:
/etc/systemd/system/<unit>.d/override.conf.
Contiene sólo los deltas que quieres, no una copia completa de la unidad. Eso importa porque es legible, revisable y resistente a la evolución de la unidad del proveedor.
También puedes colocar múltiples drop-ins (p. ej., 10-limits.conf, 20-env.conf). systemd los carga en orden.
Esto facilita responder “quién cambió qué” en lugar de “alguien editó el unit file en su lugar y ahora es un copo de nieve único”.
La diferencia entre editar y sobrescribir (y por qué importa)
Editar el unit file del proveedor es una tentación atractiva. Es rápido, y crea deuda técnica con una sola pulsación.
En el momento en que el paquete se actualice, dpkg:
- sobrescribirá la unidad (si no la marcaste como conffile), o
- mostrará prompts que se “resuelven” durante emergencias, o
- dejará un lío .dpkg-dist/.dpkg-old que nadie recuerda reconciliar.
Los overrides evitan todo eso. El paquete puede hacer lo que quiera. Tu intención sigue aplicándose.
Una cita para mantenerte honesto
“Los bugs sutiles son los que aparecen después de cambios que olvidaste que hiciste.” — idea parafraseada atribuida a ingenieros de operaciones con experiencia
Mantén tus cambios donde puedas verlos. Los overrides son precisamente eso.
Ocho hechos y un poco de historia (por qué existen los overrides)
- systemd debutó en 2010 (Lennart Poettering y Kay Sievers) y reemplazó un zoológico de scripts init por archivos unit declarativos.
- Ubuntu adoptó systemd por defecto en 15.04; para 24.04 ya no es “nuevo”, es la suposición operativa detrás del empaquetado de servicios.
- Los drop-ins fueron diseñados para empaquetado de distribuciones: los proveedores envían valores por defecto seguros; los operadores añaden política de sitio sin bifurcar la unidad.
- Las rutas de búsqueda de unit files son parte de la interfaz; systemd está intencionalmente construido para fusionar configuración desde múltiples ubicaciones, no sólo “leer un archivo”.
systemctl edites el flujo de trabajo recomendado; crea directorios y maneja el editor de forma segura, incluyendo “cambios en seco y luego recarga”.- Sobrescribir
ExecStart=requiere limpiarlo primero; systemd lo trata como una lista, no como una cadena única. Si olvidas la línea de reinicio, ejecutarás dos starts (o ninguno). - Existe una capa de tiempo de ejecución en
/run; herramientas y generators pueden crear unidades transitorias, útil para lógica de arranque pero complicado al depurar. - systemd tiene fuerte introspección:
systemctl cat,systemd-analyze,journalctl -u, ysystemctl showte permiten ver lo que en realidad decidió.
Broma #1: Editar /lib/systemd/system en producción es como “solo probar en prod” — rápido, emocionante y sólo ocasionalmente limitante para la carrera.
Caso #8: un override limpio que sobrevive actualizaciones
Aquí está la situación que veo constantemente en Ubuntu 24.04:
un servicio del proveedor arranca bien la mayoría de los días, pero bajo carga alcanza límites (descriptores de archivo, procesos, bloqueo de memoria), o necesita una variable de entorno adicional,
o el directorio de trabajo es incorrecto, o debería esperar por un montaje. La tentación es editar el unit file donde vive. No lo hagas.
Tu objetivo es: (1) identificar el cambio mínimo, (2) implementarlo en /etc/systemd/system como drop-in, y
(3) demostrar que systemd está ejecutando la configuración fusionada que pretendías.
Patrones típicos de override que son “seguros y aburridos”
- Límites de recursos:
LimitNOFILE=,TasksMax=,MemoryMax=— estables y de baja dramatización. - Orden de arranque:
After=,Requires=,Wants=— evita condiciones de carrera con montajes y redes. - Entorno:
Environment=,EnvironmentFile=— mantiene secretos fuera de los unit files; usa archivos con permisos. - Comportamiento de reinicio:
Restart=on-failure,RestartSec=,StartLimitIntervalSec=— afina, pero no escondas fallos reales. - Cambios en ExecStart: factibles, pero merecen cuidado extra y un plan de rollback.
Cuándo no sobrescribir
Si el servicio está roto porque el binario está mal, el archivo de configuración es incorrecto o falta una dependencia, un override no te salvará.
Los overrides sirven para cambiar cómo systemd ejecuta un programa correcto, no para parchear el propio programa.
Broma #2: Si “arreglas” un segfault con Restart=always, felicitaciones—has inventado un generador muy rápido de logs.
Guion de diagnóstico rápido: encuentra el cuello de botella
Cuando un servicio está poco saludable, puedes pasar 30 minutos leyendo unit files… o puedes pasar 3 minutos mirando la salida correcta.
Este es el orden que uso en producción.
1) Establece el síntoma: estado, código de salida y último error
- Revisa el estado: ¿está
failed,activating, o en ejecución pero degradado? - Revisa el código de salida:
status=203/EXECvsstatus=1/FAILUREvs un kill por OOM son universos distintos. - Revisa las últimas líneas de log: no hagas scroll; pide a journald las últimas 50 líneas con timestamps.
2) Confirma qué está ejecutando realmente systemd
- Imprime la unidad fusionada:
systemctl catmuestra proveedor + drop-ins. - Inspecciona propiedades:
systemctl show -p ExecStart,Environment,LimitNOFILEpara confirmar valores efectivos. - Comprueba si un generator creó algo en /run: si es así, tus cambios persistentes podrían estar siendo superados o complementados.
3) Sólo entonces edita: cambio mínimo, rollback predecible
- Crea un drop-in con
systemctl edit. - Ejecuta
systemd-analyze verifysi cambiaste partes con sintaxis compleja. daemon-reload, luego restart, luego valida.
Tareas prácticas (comandos, significado de salidas, decisiones)
A continuación hay tareas reales que puedes ejecutar en Ubuntu 24.04. Cada una incluye qué significa la salida y qué decisión tomar a continuación.
Usaré nginx.service como ejemplo porque es común, pero el flujo es idéntico para bases de datos, agentes, exporters y demonios personalizados.
Task 1: Encuentra dónde vive el unit file
cr0x@server:~$ systemctl show -p FragmentPath -p DropInPaths nginx.service
FragmentPath=/lib/systemd/system/nginx.service
DropInPaths=/etc/systemd/system/nginx.service.d/override.conf
Significado: FragmentPath es el archivo principal que systemd usa. DropInPaths lista los overrides aplicados.
Decisión: Si tu cambio está en /lib, tienes una granada en la mano. Muévelo a un drop-in en /etc.
Task 2: Lee la unidad fusionada, no sólo el fragmento del proveedor
cr0x@server:~$ systemctl cat nginx.service
# /lib/systemd/system/nginx.service
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target
[Service]
Type=forking
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
PIDFile=/run/nginx.pid
# /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
Significado: Esto es lo que systemd aplicará. Es la verdad. Todo lo demás es comentario.
Decisión: Si la unidad fusionada no muestra tu cambio, estás editando el lugar equivocado o olvidaste daemon-reload.
Task 3: Comprueba el estado en vivo y la última razón de salida
cr0x@server:~$ systemctl status nginx.service --no-pager
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Drop-In: /etc/systemd/system/nginx.service.d
└─override.conf
Active: failed (Result: exit-code) since Mon 2025-12-30 10:12:07 UTC; 15s ago
Docs: man:nginx(8)
Process: 2197 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
CPU: 45ms
Significado: status=1/FAILURE indica que nginx se ejecutó y devolvió fallo (a menudo error de configuración), no un problema de exec.
Decisión: Ve a los logs a continuación; no reescribas ExecStart hasta saber que es necesario.
Task 4: Extrae logs recientes para la unidad, con timestamps
cr0x@server:~$ journalctl -u nginx.service -n 50 --no-pager -o short-iso
2025-12-30T10:12:07+00:00 server nginx[2197]: nginx: [emerg] invalid number of arguments in "worker_connections" directive in /etc/nginx/nginx.conf:12
2025-12-30T10:12:07+00:00 server systemd[1]: nginx.service: Main process exited, code=exited, status=1/FAILURE
2025-12-30T10:12:07+00:00 server systemd[1]: nginx.service: Failed with result 'exit-code'.
Significado: El servicio falló por la configuración de la aplicación. systemd no es el problema hoy.
Decisión: Arregla la configuración de nginx. Los overrides no ayudarán. Si tu cambio pretendía arreglar una ruta de configuración, valida esa hipótesis.
Task 5: Confirma si existe un drop-in y qué contiene
cr0x@server:~$ systemctl edit nginx.service --full
# (editor opens the full unit)
Significado: --full crea una copia completa de la unidad en /etc/systemd/system. Es una herramienta contundente.
Decisión: Prefiere systemctl edit nginx.service (drop-in). Usa --full sólo si debes reemplazar la unidad por completo.
Task 6: Crea un drop-in apropiado (recomendado)
cr0x@server:~$ systemctl edit nginx.service
# (editor opens /etc/systemd/system/nginx.service.d/override.conf)
Añade algo como:
cr0x@server:~$ sudo cat /etc/systemd/system/nginx.service.d/override.conf
[Service]
LimitNOFILE=65536
TasksMax=4096
Significado: No estás bifurcando la unidad. Estás aplicando política por encima.
Decisión: Mantén los overrides pequeños. Si tu override.conf es más largo que el archivo del proveedor, estás escribiendo tu propia unidad—hazte responsable explícitamente.
Task 7: Recarga systemd después de cambiar archivos de unidad
cr0x@server:~$ sudo systemctl daemon-reload
Significado: systemd vuelve a leer las definiciones de unidad. Sin esto, puede mantener versiones antiguas.
Decisión: Si los cambios “no se aplican”, sospecha primero que olvidaste recargar. Segundo sospecha: editaste un archivo que systemd no está usando.
Task 8: Verifica los valores efectivos que systemd aplicará
cr0x@server:~$ systemctl show nginx.service -p LimitNOFILE -p TasksMax -p Environment
LimitNOFILE=65536
TasksMax=4096
Environment=
Significado: Esta es la configuración efectiva después de fusionar todos los fragmentos y drop-ins.
Decisión: Si esperabas un valor y no está aquí, encuentra qué te está sobreescribiendo (orden de drop-ins, unidad completa en /etc, o una unidad transitoria).
Task 9: Sobrescribe ExecStart correctamente (limpia primero)
Este es el que la gente hace mal. En systemd, muchas directivas son de tipo lista. ExecStart= es una de ellas.
Para reemplazarla, debes limpiar la lista existente.
cr0x@server:~$ sudo cat /etc/systemd/system/nginx.service.d/10-execstart.conf
[Service]
ExecStart=
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;' -c /etc/nginx/nginx.conf
Significado: El ExecStart= vacío reinicia la lista; la línea siguiente pasa a ser el único ExecStart.
Decisión: Si no reseteas, podrías acabar con múltiples líneas ExecStart. Mejor caso: el inicio falla. Peor caso: “funciona” hasta que deja de hacerlo.
Task 10: Detecta una tormenta de reinicios y deténla de forma segura
cr0x@server:~$ systemctl show nginx.service -p NRestarts -p Restart -p RestartUSec
NRestarts=27
Restart=on-failure
RestartUSec=100ms
Significado: El servicio está oscilando rápidamente. Esto puede llenar los logs y esconder la primera falla.
Decisión: Detén y enmascara temporalmente mientras depuras (si es seguro), o aumenta RestartSec= vía drop-in para ralentizar el bucle.
Task 11: Comprueba si estás luchando contra una sustitución completa de unidad en /etc
cr0x@server:~$ systemctl show nginx.service -p FragmentPath
FragmentPath=/etc/systemd/system/nginx.service
Significado: Alguien creó una unidad completa en /etc, que sobrescribe completamente la unidad del proveedor.
Decisión: Si no querías poseer toda la unidad, elimina la unidad completa y reemplázala con drop-ins. Esto es una resaca común de “usamos –full una vez”.
Task 12: Identifica problemas de orden/dependencias (montajes, red, etc.)
cr0x@server:~$ systemctl list-dependencies --reverse nginx.service
nginx.service
● multi-user.target
Significado: Las dependencias inversas muestran quién quiere este servicio. Esto es “quién se romperá si nginx está abajo.”
Decisión: Si targets críticos dependen de él, planifica cambios con precaución y usa recargas escalonadas o ventanas de mantenimiento.
Task 13: Verifica la sintaxis de la unidad antes de reiniciar servicios críticos
cr0x@server:~$ systemd-analyze verify /etc/systemd/system/nginx.service.d/10-execstart.conf
Significado: Normalmente la ausencia de salida significa “no se encontraron problemas”. Si hay un error de sintaxis, lo verás antes de hacer el corte en producción.
Decisión: Usa verify cuando toques directivas complicadas (ExecStart, dependencias, sandboxing). Es más barato que una tormenta de pagers.
Task 14: Revertir overrides limpiamente
cr0x@server:~$ sudo systemctl revert nginx.service
Removed "/etc/systemd/system/nginx.service.d/override.conf".
Removed "/etc/systemd/system/nginx.service.d/10-execstart.conf".
Significado: revert elimina los drop-ins y devuelve la unidad al estado del proveedor (o lo que quede).
Decisión: Usa esto cuando tu override empeoró las cosas y necesitas un botón rápido “volver a la línea base conocida”.
Task 15: Confirma qué overrides están aplicados actualmente (con orden de archivos)
cr0x@server:~$ systemctl show nginx.service -p DropInPaths
DropInPaths=/etc/systemd/system/nginx.service.d/10-execstart.conf /etc/systemd/system/nginx.service.d/override.conf
Significado: El orden importa. El orden lexicográfico importa. Tu archivo 90-* vencerá a tu archivo 10-*.
Decisión: Si estás apilando múltiples cambios, nómbralos intencionalmente. No dejes que “override.conf” se convierta en un cajón de trastos.
Task 16: Demuestra que el proceso en ejecución recibió los límites que estableciste
cr0x@server:~$ systemctl show nginx.service -p MainPID
MainPID=2418
cr0x@server:~$ cat /proc/2418/limits | head -n 8
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 4096 4096 processes
Significado: Esto muestra lo que el kernel realmente aplica al proceso.
Decisión: Si los límites en /proc no coinciden, puede que tengas múltiples procesos (master/worker), o el servicio hace fork y aplica límites de forma distinta. Verifica el PID correcto.
Tres microhistorias corporativas desde el terreno
Microhistoria 1: Un incidente causado por una suposición equivocada
Una empresa SaaS mediana tenía una flota de servidores Ubuntu ejecutando un forwarder de logs como servicio systemd.
El forwarder comenzó a fallar tras una actualización de seguridad rutinaria. Los ingenieros vieron que el servicio usaba
un unit file en /lib/systemd/system y asumieron “es estable, no cambiará mucho.”
Meses antes, alguien había “editado temporalmente” la unidad del proveedor en su lugar para añadir una variable de entorno:
Environment=HTTP_PROXY=.... Estaba sin documentar, sin revisión e invisible para la gestión de configuración porque no estaba en /etc.
La actualización de seguridad reemplazó el paquete, y el proxy desapareció. El forwarder no pudo alcanzar el colector y los logs dejaron de fluir.
La alerta que saltó no fue “forwarder de logs caído”. Fue aguas abajo: un dashboard quedó en blanco silenciosamente,
luego un job de exportación de cumplimiento falló porque esperaba logs. La gente persiguió el sistema equivocado durante una hora.
La primera pista estuvo en journald: errores de conexión repetidos después de la hora de la actualización del paquete.
La solución fue aburrida: un drop-in bajo /etc/systemd/system para establecer el proxy, más una nota en el runbook.
La recomendación del postmortem fue más tajante: nunca cambiar unidades del proveedor directamente, e incorporar una comprobación de auditoría de unidades
en la detección de deriva de configuración.
Microhistoria 2: Una optimización que salió mal
Otra compañía ejecutaba un servicio sensible a latencia con ajustes agresivos de reinicio.
Alguien notó que después de un crash, el tiempo de recuperación era demasiado lento para su gusto.
Redujeron RestartSec a 100ms y aumentaron StartLimitBurst “para mantenerlo disponible.”
Redujo el tiempo entre crashes y reinicios. Ese fue el problema.
Un bug latente de configuración empezó a ocasionar fallos ocasionales. En lugar de un crash limpio y un reinicio estable,
el servicio entró en un bucle de caídas rápido. La CPU se disparó, los logs explotaron y otros servicios en la misma máquina
empezaron a perder deadlines por la presión de I/O.
Luego la contrapartida: el rate limiting de journald entró en acción. Los mismos logs necesarios para depurar la falla original se volvieron
incompletos. Mientras tanto, el sistema de monitorización veía “servicio arriba” intermitentemente y no paginó de inmediato.
Todos perdieron tiempo porque los síntomas se extendieron por toda la máquina.
La recuperación fue detener la unidad, revertir el override y luego reintroducir valores sensatos:
Restart=on-failure, RestartSec=2s y un límite de inicio moderado.
La verdadera optimización fue cambiar el chequeo de salud para detectar “reinicios rápidos” como fallo y alertar antes.
Microhistoria 3: Una práctica aburrida pero correcta que salvó el día
Una gran empresa tenía una política: todas las modificaciones systemd debían ser drop-ins, nombradas con un prefijo y un número de ticket,
y cada override debía ser visible en un informe de inventario extraído con systemctl show en cada host.
Sonaba a burocracia hasta que no lo fue.
Un proveedor envió una unidad actualizada para un agente crítico, cambiando las opciones por defecto de sandboxing.
En un subconjunto de servidores, el agente dejó de acceder a un directorio que necesitaba. El incidente pudo haberse convertido en una
búsqueda de “funciona en mi nodo” de varios días porque distintos equipos poseían distintos entornos.
En cambio, el ingeniero on-call sacó el informe de inventario y vio inmediatamente qué servidores tenían un override que tocaba
acceso al sistema de ficheros (p. ej., ReadWritePaths) y cuáles no. La convención de nombres del override lo hizo buscable.
Desplegaron un drop-in de una línea para alinear el comportamiento, reiniciaron el agente con seguridad y siguieron adelante.
La práctica no evitó el cambio del proveedor. Evitó la confusión. En producción, la claridad es una característica.
Errores comunes: síntoma → causa raíz → arreglo
1) “Mi override no se aplica”
Síntoma: Editaste un drop-in, reiniciaste el servicio y nada cambió.
Causa raíz: Olvidaste systemctl daemon-reload, o editaste un archivo en la ruta equivocada, o una unidad completa en /etc suplanta al proveedor + drop-ins.
Arreglo: Ejecuta systemctl show -p FragmentPath -p DropInPaths unit; luego daemon-reload; luego systemctl cat unit para confirmar la configuración fusionada.
2) “Sobrescribí ExecStart y ahora no arranca”
Síntoma: El servicio falla con mensajes extraños, o intenta ejecutar múltiples comandos.
Causa raíz: Añadiste ExecStart=... sin limpiar la lista existente.
Arreglo: En tu drop-in: añade una línea en blanco ExecStart= antes del nuevo ExecStart=.... Recarga y reinicia.
3) “La actualización del paquete revirtió mi arreglo”
Síntoma: El comportamiento del servicio cambia justo después de apt upgrade.
Causa raíz: Editaste /lib/systemd/system/*.service directamente (territorio del proveedor).
Arreglo: Vuelve a aplicar el cambio como un drop-in bajo /etc/systemd/system/<unit>.d/. Considera systemctl revert para limpiar copias accidentales de unidades completas.
4) “Arranca manualmente pero no via systemd”
Síntoma: Ejecutar el binario en una shell funciona; start vía systemd falla.
Causa raíz: Variables de entorno faltantes, directorio de trabajo distinto, o sandboxing más estricto en el contexto de systemd.
Arreglo: Compara systemctl show -p Environment -p WorkingDirectory; añade EnvironmentFile= o WorkingDirectory= en un drop-in; verifica logs.
5) “El servicio oscila y deja la máquina inservible”
Síntoma: CPU alta, logs masivos, “el servicio sigue reiniciándose”.
Causa raíz: Política de reinicio demasiado agresiva (Restart=always, RestartSec minúsculo), o un bucle real de crashes enmascarado por el auto-restart.
Arreglo: Ralentízalo: Restart=on-failure, RestartSec=2s. Detén la unidad, captura logs, arregla la causa raíz y luego reinicia.
6) “Mi override se rompió después de añadir varios drop-ins”
Síntoma: Las configuraciones parecen “cambiar aleatoriamente” según el host.
Causa raíz: El orden de los drop-ins difiere o otro archivo sobreescribe la misma directiva más tarde.
Arreglo: Usa numeración explícita (10-, 20-, 90-). Comprueba DropInPaths. Consolida directivas en conflicto.
7) “No ve un directorio montado en el arranque”
Síntoma: El servicio falla en el arranque, pero funciona tras un reinicio manual.
Causa raíz: Faltan dependencias de orden en la unidad de montaje; el servicio arranca antes de que el sistema de ficheros esté listo.
Arreglo: Añade un drop-in con RequiresMountsFor=/path o los apropiados After=/Requires=. Recarga y prueba el comportamiento al reiniciar.
Listas de verificación / plan paso a paso
Checklist A: Hacer un override seguro (el enfoque por defecto)
- Obtén la verdad actual:
systemctl cat unitysystemctl show -p FragmentPath -p DropInPaths unit. - Decide el cambio más pequeño posible (límites, env, orden, política de reinicio).
- Crea drop-in:
sudo systemctl edit unit. - Añade sólo las directivas que necesitas. Evita copiar el unit del proveedor.
- Valida sintaxis si tocaste cosas complejas:
systemd-analyze verify .... sudo systemctl daemon-reload.- Reinicia y verifica:
sudo systemctl restart unitluegosystemctl status unit. - Prueba la configuración efectiva:
systemctl show -p ... unit. - Prueba el efecto en tiempo de ejecución (límites/env) vía
/proco diagnósticos específicos del servicio.
Checklist B: Debes reemplazar ExecStart (cambio de alto riesgo)
- Captura el ExecStart actual:
systemctl show -p ExecStart unit. - Crea un archivo drop-in dedicado (no lo escondas):
/etc/systemd/system/unit.d/10-execstart.conf. - Resetea la lista primero: incluye una línea en blanco
ExecStart=. - Incluye cualquier
ExecStartPre=,WorkingDirectory=y archivos de entorno necesarios. - Verifica:
systemd-analyze verify. - Recarga y reinicia.
- Tén listo un rollback:
systemctl revert unit(o elimina el drop-in) y reinicia.
Checklist C: Revertir y volver a la línea base
- Detén el servicio si está oscilando:
sudo systemctl stop unit. - Haz snapshot de la unidad fusionada actual:
systemctl cat uniten tus notas de incidente. - Revertir overrides:
sudo systemctl revert unit. - Recarga:
sudo systemctl daemon-reload. - Arranca:
sudo systemctl start unit. - Confirma logs:
journalctl -u unit -n 50.
Preguntas frecuentes
1) ¿Debo alguna vez editar archivos en /lib/systemd/system?
No, no como práctica. Trátalo como firmware del proveedor: legible, no editable. Usa drop-ins en /etc/systemd/system.
Si debes experimentar, hazlo en un host desechable y traduce el resultado a un override.
2) ¿Cuál es la diferencia entre systemctl edit y editar un archivo manualmente?
systemctl edit crea la estructura de directorios correcta, abre el archivo adecuado y se alinea con el modelo de systemd.
Las ediciones manuales están bien si conoces las rutas, pero systemctl edit reduce errores de “ubicación equivocada”.
3) ¿Por qué mi override de ExecStart= no reemplazó al anterior?
Porque ExecStart es de tipo lista. Añade una línea en blanco ExecStart= para limpiar la lista primero, luego añade tu nuevo ExecStart=....
4) ¿Cómo veo la unidad final que usa systemd?
Usa systemctl cat unit para la configuración fusionada y systemctl show -p FragmentPath -p DropInPaths unit para ver fuentes y drop-ins aplicados.
5) ¿Necesito daemon-reload cada vez?
Si cambiaste archivos de unidad o drop-ins, sí. Reiniciar un servicio no implica confiablemente volver a leer la definición de unidad.
daemon-reload es barato; los outages no lo son.
6) ¿Cuál es la forma más limpia de eliminar un override?
sudo systemctl revert unit. Elimina los drop-ins y devuelve a los valores por defecto del proveedor. Luego ejecuta daemon-reload.
7) ¿Puedo usar drop-ins para cambiar dependencias como After= y Requires=?
Sí, y es uno de los mejores usos. Si un servicio depende de un montaje, considera RequiresMountsFor=/path.
Para dependencias de red, ten cuidado: “red arriba” no es lo mismo que “dependencia remota alcanzable”.
8) Mi override funciona en un servidor pero no en otro. ¿Por qué?
Razones más comunes: otro drop-in lo sobreescribe después; hay una unidad completa en /etc en un host; o un generator produjo algo en /run.
Compara systemctl show -p FragmentPath -p DropInPaths entre hosts.
9) ¿Es mejor poner todo en un solo override.conf?
No siempre. Un archivo es fácil hasta que se convierte en un cajón de trastos. Para cambios mayores, separa drop-ins por propósito con numeración:
10-limits.conf, 20-env.conf, 90-hardening.conf. El orden queda explícito.
10) ¿Cómo confirmo que mis cambios de límites aplican realmente al proceso?
Obtén el PID con systemctl show -p MainPID y revisa /proc/<pid>/limits. Eso es lo que el kernel hace cumplir.
Conclusión: próximos pasos que puedes hacer hoy
En Ubuntu 24.04, los overrides de systemd son la forma adulta de arreglar servicios. Sobreviven a las actualizaciones, mantienen tu intención separada de los valores del proveedor,
y hacen la respuesta a incidentes más rápida porque la pregunta “qué cambió” se responde en segundos.
Pasos prácticos siguientes:
- Elige un servicio que hayas “tocado” antes. Ejecuta
systemctl show -p FragmentPath -p DropInPathsy comprueba si hay ediciones en/lib. - Si las hay, migra los cambios a un drop-in bajo
/etc/systemd/system/<unit>.d/. - Estandariza la nomenclatura de drop-ins (numerados, por propósito). Tu yo del futuro es una persona distinta con distinto sueño.
- Enseña a tu equipo dos comandos:
systemctl catysystemctl revert. Uno encuentra la verdad; el otro te compra un rollback.
Haz esto unas cuantas veces y dejarás de tratar a systemd como una caja negra. No es magia. Es sólo muy particular respecto a dónde pones tus ediciones.