Reinicios watchdog en Ubuntu 24.04: detecta colgamientos silenciosos antes de que te cuesten disponibilidad (caso nº18)

¿Te fue útil?

Nada pone a prueba una rotación de guardias como un servidor que “se reinicia solo” sin apagado limpio, sin volcado de memoria y con logs que se cortan a medias. El servicio vuelve, los paneles se ponen verdes y todos fingen que fue un caso aislado—hasta que vuelve a ocurrir durante la demostración del CEO.

Ubuntu 24.04 es perfectamente capaz de decirte qué pasó. El truco es saber dónde encaja el watchdog en la cadena, qué significa realmente un “colgamiento silencioso” y cómo capturar pruebas antes de que el reinicio borre la escena del crimen.

Qué hacen realmente los watchdogs (y qué no hacen)

Un watchdog es un temporizador con una tarea: si el sistema deja de avanzar, reinícialo (o al menos grita fuerte). En Linux verás varias capas:

  • Hardware watchdog (BMC/iDRAC/iLO, o un temporizador del chipset). Si el kernel no lo “mima”, el hardware reinicia la máquina. Este es el que sigue funcionando cuando el kernel está totalmente bloqueado.
  • Watchdogs del kernel (soft lockup, hard lockup/NMI watchdog). Detectan CPUs atascadas en espacio kernel, regiones con interrupciones deshabilitadas o estados no programables.
  • Watchdogs en espacio de usuario (systemd watchdog, heartbeats de aplicaciones). Detectan servicios que están “vivos pero muertos”, por ejemplo un daemon atrapado en un bucle infinito pero que aún conserva su PID.

Los watchdogs no son “detectores de fallos”. Son detectores de “hemos perdido el control”. Un panic deja migas de pan (trazas de pila, volcados). Un colgamiento es un apagón. Los watchdogs existen porque, en producción, una falla limpia es un lujo.

Aquí viene la parte dolorosa: el mismo reinicio que te encanta porque restaura el servicio también destruye tu mejor evidencia. Si tu estrategia es “espera a que vuelva a ocurrir y entonces haz SSH”, estás haciendo arqueología con un soplador de hojas.

Recomendación práctica: ejecuta un watchdog en producción, pero trátalo como un disparador que activa la captura de datos. Configura la captura primero. Luego deja que reinicie.

Dos términos que verás con frecuencia

  • Soft lockup: la CPU está atascada ejecutando código del kernel demasiado tiempo sin hacer scheduling. El kernel aún puede ejecutarse lo suficiente para quejarse.
  • Hard lockup: la CPU no responde a las interrupciones (o parece muerta). La detección suele apoyarse en NMIs o fuentes de temporización separadas.

Una cita, porque es cierta

Werner Vogels (idea parafraseada): “Construyes para la falla—porque la falla no es opcional, es parte de operar a escala.”

Además, para que conste: un “colgamiento silencioso” no es silencioso. Simplemente habla en el lugar equivocado—como el ring buffer del kernel que nunca persististe, sobre una cola de disco que ahora mismo está congelada.

Datos interesantes y contexto histórico

Los watchdogs llevan existiendo el tiempo suficiente como para tener historial. Algunos puntos de contexto que ayudan cuando estás leyendo logs a las 03:00:

  1. Los temporizadores watchdog existen desde antes de Linux. Los controladores industriales los usaban porque un lazo de control atascado puede ser un problema de seguridad, no solo un asunto de SLA.
  2. La detección de soft lockup en Linux llegó a medida que los kernels se volvieron más preemptivos. A medida que evolucionaron el scheduler y la preempción, “CPU atascada” se volvió medible y accionable.
  3. El trabajo del NMI watchdog cambió con el tiempo. Antes era una herramienta común para “¿está viva la CPU?”; los kernels modernos a menudo usan la infraestructura de perf events como parte de esa ruta de detección.
  4. La detección de tareas colgadas se agregó porque “simplemente espera I/O” aún puede matar un sistema. Una tarea bloqueada en estado D puede detener subsistemas críticos incluso si las CPUs parecen bien.
  5. Los watchdogs hardware se trasladaron a los BMC. Muchos servidores pueden reiniciarte incluso si el SO desaparece, lo cual es estupendo hasta que la configuración del BMC se convierte en un dominio de fallo aparte.
  6. systemd popularizó los watchdogs de servicio. No fue el primero, pero convirtió en algo habitual la idea de “el proceso debe enviarme pings” en las distribuciones Linux.
  7. Los entornos virtualizados complican el tiempo. Los umbrales del watchdog pueden dispararse bajo contención extrema en el host porque tu guest deja de recibir tiempo de CPU.
  8. Los colgamientos de almacenamiento se hicieron más visibles con NVMe. Es rápido—hasta que firmware/driver tienen casos límite que atascan colas, y entonces todo lo que toca el disco parece culpable.
  9. Algunos “reinicios aleatorios” son deliberados. Un reinicio por hardware watchdog es indistinguible de un fallo de alimentación a menos que recolectes los logs fuera de banda correctos.

Guía de diagnóstico rápido (primero/segundo/tercero)

Si estás en modo incidente, no tienes tiempo para una teoría grandiosa. Necesitas localizar el cuello de botella rápido: bloqueo de CPU, bloqueo de I/O, presión de memoria, reinicio por hardware o inanición por virtualización.

Primero: prueba si fue un reinicio por watchdog vs un reinicio normal

  • Revisa los logs del arranque anterior en busca de mensajes de watchdog/lockup.
  • Busca marcadores de apagado limpio (generalmente están ausentes).
  • Consulta los logs fuera de banda/BMC si los tienes (incluso una pérdida de alimentación parece un reinicio).

Segundo: decide si el sistema se colgó por CPU o por I/O

  • Busca soft lockup, hard LOCKUP o advertencias del NMI watchdog (ruta de CPU).
  • Busca blocked for more than, hung_task, timeouts NVMe, resets SCSI, errores ext4/XFS I/O (ruta de I/O).
  • Correlaciona con los síntomas de la aplicación: timeouts vs falta total de respuesta.

Tercero: captura evidencia para la próxima vez

  • Habilita journald persistente y preserva el ring buffer del kernel si es posible.
  • Configura kdump para capturar un vmcore en caso de panic (y configura el watchdog para provocar panic en lugar de reiniciar si es apropiado).
  • Configura triggers sysrq y logging remoto para que tengas un rastro incluso cuando los discos locales se aten.

Punto de decisión: si no puedes capturar evidencia, no estás depurando—estás adivinando. Y adivinar es caro.

De los síntomas a la evidencia: las señales que importan

“Se reinició” es un resultado, no un diagnóstico. Los reinicios por watchdog suelen ser consecuencia de una de estas causas:

  • Bloqueo de CPU: kernel atascado con interrupciones deshabilitadas, o en spin sobre un lock. El watchdog lo detecta.
  • Bloqueo de I/O o espiral de timeouts de dispositivo: colas de almacenamiento atascadas; tareas se acumulan en estado D; el sistema se vuelve no responsive; el watchdog termina disparándose.
  • Presión de memoria y tormentas de reclaim: no es un “colgamiento”, pero lo parece. Si kswapd y similares quedan en reclaim patológico o en espera de I/O, la máquina “se congela”.
  • Fallas de firmware/hardware: errores corregidos hasta que ya no; tormentas PCIe AER; resets de controladora NVMe; eventos ECC; a veces el watchdog hardware simplemente corta la corriente.
  • Contención en el host VM: el guest deja de ser planificado; el watchdog dispara dentro del guest; el host aparece inocente en los logs (como siempre).

Ubuntu 24.04 incluye un kernel moderno y una pila systemd actualizada, lo cual es una buena noticia: tienes mecanismos para ver qué ocurre. La mala noticia: los valores por defecto favorecen “seguir funcionando” sobre “dejar un informe forense perfecto”. Tendrás que hacer concesiones deliberadas.

Tareas prácticas (comandos, salidas, decisiones)

Estas no son “ejecuta esto para sentirte ocupado”. Cada una da una señal específica, y debes tomar una decisión basada en ella.

Task 1: Confirmar que el reinicio no fue limpio (arranque previo)

cr0x@server:~$ journalctl -b -1 -p warning..alert --no-pager | tail -n 40
Aug 12 03:14:22 server kernel: watchdog: BUG: soft lockup - CPU#7 stuck for 26s! [kworker/7:1:1234]
Aug 12 03:14:22 server kernel: Modules linked in: nvme tcp_bbr ...
Aug 12 03:14:30 server kernel: NMI watchdog: Watchdog detected hard LOCKUP on cpu 7
Aug 12 03:14:31 server systemd[1]: Starting Reboot...
Aug 12 03:14:31 server kernel: watchdog: Initiating system reboot

Qué significa: soft lockup escalando a hard lockup, y luego un reinicio disparado por el watchdog.

Decisión: trátalo como un colgamiento de kernel/hardware/driver, no como un reinicio de aplicación. Pasa inmediatamente a recopilar evidencia del kernel y del dispositivo.

Task 2: Ver si el sistema registró un apagado normal

cr0x@server:~$ last -x | head -n 8
reboot   system boot  6.8.0-41-generic Mon Aug 12 03:15   still running
crash    system crash 6.8.0-41-generic Mon Aug 12 03:14 - 03:15  (00:01)
reboot   system boot  6.8.0-41-generic Sun Aug 11 18:02 - 03:15  (09:13)
shutdown system down  6.8.0-41-generic Sun Aug 11 18:01 - 18:02  (00:01)

Qué significa: aparece un marcador de crash en lugar de una secuencia de apagado limpia.

Decisión: prioriza logs del kernel y evidencia fuera de banda; no pierdas tiempo auditando reinicios de unidades systemd.

Task 3: Identificar dispositivos y drivers watchdog activos

cr0x@server:~$ ls -l /dev/watchdog /dev/watchdog0 2>/dev/null || echo "no /dev/watchdog node"
crw------- 1 root root 10, 130 Aug 12 08:40 /dev/watchdog
crw------- 1 root root 10, 130 Aug 12 08:40 /dev/watchdog0

Qué significa: existe un dispositivo de caracteres watchdog; algo puede activarlo.

Decisión: confirma quién lo está usando (systemd, daemon watchdog, agente del proveedor). Un espacio de usuario mal configurado puede causar reinicios sorpresa.

Task 4: Comprobar si systemd alimenta un watchdog hardware

cr0x@server:~$ systemctl show -p RuntimeWatchdogUSec -p RebootWatchdogUSec -p WatchdogDevice systemd-logind
RuntimeWatchdogUSec=0
RebootWatchdogUSec=0
WatchdogDevice=

Qué significa: estos valores no son el watchdog global de systemd; son por unidad. No los interpretes mal.

Decisión: revisa la configuración global de systemd a continuación; la salida por unidad puede inducir a error.

Task 5: Ver ajustes watchdog global de systemd

cr0x@server:~$ grep -E '^(RuntimeWatchdogSec|RebootWatchdogSec|ShutdownWatchdogSec|WatchdogDevice)=' /etc/systemd/system.conf
RuntimeWatchdogSec=30s
RebootWatchdogSec=10min
ShutdownWatchdogSec=2min

Qué significa: systemd está configurado para armar un watchdog durante el runtime y durante transiciones de reinicio/apagado.

Decisión: valida el dispositivo/driver del watchdog y asegúrate de que tus timeouts sean razonables para tus peores pausas de I/O (más adelante hay más sobre esto).

Task 6: Identificar la configuración de detección de lockup del kernel

cr0x@server:~$ sysctl kernel.watchdog kernel.softlockup_panic kernel.hardlockup_panic kernel.watchdog_thresh
kernel.watchdog = 1
kernel.softlockup_panic = 0
kernel.hardlockup_panic = 0
kernel.watchdog_thresh = 10

Qué significa: la detección watchdog está activada; advierte pero no entra en panic por defecto. El umbral es 10 segundos (valor común).

Decisión: en producción, considera provocar panic en lockup (con kdump configurado) para obtener un vmcore. Reiniciar sin evidencia es como terminar “monitorizando” en lugar de arreglar.

Task 7: Inspeccionar dmesg del arranque anterior (si se preservó)

cr0x@server:~$ journalctl -k -b -1 --no-pager | egrep -i 'watchdog|lockup|hung|blocked for more than|nvme|reset|I/O error' | tail -n 60
Aug 12 03:13:58 server kernel: nvme nvme0: I/O 123 QID 4 timeout, aborting
Aug 12 03:14:02 server kernel: nvme nvme0: Abort status: 0x371
Aug 12 03:14:06 server kernel: INFO: task jbd2/nvme0n1p2-8:512 blocked for more than 120 seconds.
Aug 12 03:14:06 server kernel:       Tainted: G           O       6.8.0-41-generic #41-Ubuntu
Aug 12 03:14:22 server kernel: watchdog: BUG: soft lockup - CPU#7 stuck for 26s! [kworker/7:1:1234]
Aug 12 03:14:31 server kernel: watchdog: Initiating system reboot

Qué significa: timeouts NVMe precedieron a un hilo de journaling atascado, luego advertencia de lockup de CPU. Es el clásico “almacenamiento volvió miserable al kernel”.

Decisión: trata la ruta de almacenamiento (firmware, driver, errores PCIe, colas) como sospechosa principal. No pierdas días culpando al pool de hilos de tu app.

Task 8: Verificar persistencia de journald (para no perder el rastro)

cr0x@server:~$ grep -E '^\s*Storage=' /etc/systemd/journald.conf
Storage=auto
cr0x@server:~$ ls -ld /var/log/journal || echo "no persistent journal directory"
ls: cannot access '/var/log/journal': No such file or directory
no persistent journal directory

Qué significa: los logs pueden ser volátiles. Tras un reinicio, tus mejores pistas pueden haberse ido.

Decisión: habilita journald persistente en servidores donde te importe el post-mortem. Sí, usa disco. Y el tiempo de inactividad también.

Task 9: Habilitar almacenamiento persistente de journald (de forma segura)

cr0x@server:~$ sudo mkdir -p /var/log/journal
cr0x@server:~$ sudo systemd-tmpfiles --create --prefix /var/log/journal
cr0x@server:~$ sudo systemctl restart systemd-journald
cr0x@server:~$ journalctl --disk-usage
Archived and active journals take up 1.1G in the file system.

Qué significa: journald ahora persiste logs. La próxima vez tienes una oportunidad.

Decisión: ajusta límites de retención adecuados a tus discos y necesidades de respuesta a incidentes.

Task 10: Revisar la política de “hung task” del kernel y decidir si quieres panics

cr0x@server:~$ sysctl kernel.hung_task_timeout_secs kernel.hung_task_panic kernel.hung_task_warnings
kernel.hung_task_timeout_secs = 120
kernel.hung_task_panic = 0
kernel.hung_task_warnings = 1

Qué significa: el kernel advertirá sobre tareas bloqueadas 120 segundos, pero no provocará panic.

Decisión: si los colgamientos están matando el uptime, considera provocar panic (con kdump) tras deadlocks confirmados para capturar el estado. Es un tradeoff: un panic es disruptivo, pero también lo es un reinicio watchdog sin evidencia.

Task 11: Verificar que kdump esté instalado y armado

cr0x@server:~$ systemctl status kdump-tools --no-pager
● kdump-tools.service - Kernel crash dump capture service
     Loaded: loaded (/lib/systemd/system/kdump-tools.service; enabled; preset: enabled)
     Active: active (exited) since Mon 2025-08-12 08:41:12 UTC; 3h ago
       Docs: man:kdump-tools(8)

Qué significa: kdump está habilitado. No es prueba de que funcionará, pero es un inicio.

Decisión: valida la reserva crashkernel y haz una prueba de crash controlada en una ventana de mantenimiento.

Task 12: Comprobar la reserva crashkernel (sin ella kdump suele fallar)

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0-41-generic root=UUID=... ro crashkernel=512M-:192M quiet splash

Qué significa: crashkernel está reservado. El tamaño importa; si es demasiado pequeño los volcados fallan bajo carga.

Decisión: asegúrate de que es adecuado para tu RAM y kernel; ajústalo si los vmcores se truncan o faltan.

Task 13: Forzar una prueba de crash controlada (solo en ventana de mantenimiento)

cr0x@server:~$ sudo sysctl -w kernel.sysrq=1
kernel.sysrq = 1
cr0x@server:~$ echo c | sudo tee /proc/sysrq-trigger
c

Qué significa: el kernel entra en panic inmediatamente. Si kdump está correcto, obtendrás un vmcore al reiniciar.

Decisión: si no obtienes un volcado, arregla kdump ahora—no después del próximo colgamiento en producción.

Task 14: Tras el reinicio, confirmar que existe un volcado

cr0x@server:~$ ls -lh /var/crash | tail -n 5
drwxr-xr-x 2 root root 4.0K Aug 12 09:02 202508120902
cr0x@server:~$ ls -lh /var/crash/202508120902 | egrep 'vmcore|dmesg'
-rw-r----- 1 root root 2.8G Aug 12 09:03 vmcore
-rw-r----- 1 root root  92K Aug 12 09:03 dmesg.0

Qué significa: puedes capturar evidencia. Eso cambia completamente el juego.

Decisión: considera cambiar el manejo de lockup/hung-task de “solo advertir” a “panic” para clases de colgamientos que no puedas depurar de otro modo.

Task 15: Revisar errores PCIe AER que suelen preceder wedges de dispositivo

cr0x@server:~$ journalctl -k -b -1 --no-pager | egrep -i 'AER|pcie|nvme.*reset|link down|fatal error' | tail -n 40
Aug 12 03:13:40 server kernel: pcieport 0000:3b:00.0: AER: Corrected error received: 0000:3b:00.0
Aug 12 03:13:40 server kernel: pcieport 0000:3b:00.0: AER: [ 0] RxErr
Aug 12 03:13:58 server kernel: nvme nvme0: controller is down; will reset: CSTS=0x3

Qué significa: el bus se está quejando y la controladora NVMe se reseteó después. Eso no es “un bug de la app”.

Decisión: involucra a los responsables de hardware/firmware: BIOS, firmware de NIC/HBA/NVMe, topología PCIe, ajustes de gestión de energía.

Task 16: Revisar presión y bloqueos I/O (baseline post-incidente)

cr0x@server:~$ cat /proc/pressure/io
some avg10=0.00 avg60=0.05 avg300=0.12 total=11234567
full avg10=0.00 avg60=0.01 avg300=0.03 total=1234567

Qué significa: PSI muestra con qué frecuencia las tareas están bloqueadas por I/O. Tras un evento de colgamiento, quieres comparar con la línea base; los picos se correlacionan con “todo parece congelado”.

Decisión: si PSI está elevado durante periodos normales, probablemente tienes contención crónica de almacenamiento; los lockups pueden ser la cola extrema.

Task 17: Confirmar salud NVMe y logs de errores (si NVMe está implicado)

cr0x@server:~$ sudo nvme list
Node             SN                   Model                                   Namespace Usage                      Format           FW Rev
/dev/nvme0n1     S6XXXXXXXXXXXX       ACME NVMe Datacenter 3.2TB              1         1.20  TB / 3.20  TB        512   B +  0 B   1.2.3
cr0x@server:~$ sudo nvme smart-log /dev/nvme0
critical_warning                    : 0x00
media_errors                        : 0
num_err_log_entries                 : 14
cr0x@server:~$ sudo nvme error-log /dev/nvme0 | head
Entry[ 0]
error_count     : 14
sqid            : 4
cmdid           : 0x001a
status_field    : 0x4004
parm_err_loc    : 0x0000

Qué significa: la controladora ha registrado errores. No necesariamente fatales, pero es una pista que coincide con timeouts.

Decisión: planifica actualizaciones de firmware y consulta avisos del proveedor. Si puedes correlacionar entradas de error con las marcas de tiempo del colgamiento, tienes un caso sólido.

Task 18: Revisar señales de inanición de CPU (virtualización o vecinos ruidosos)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.8.0-41-generic (server)  08/12/2025  _x86_64_  (16 CPU)

08:52:01 AM  CPU   %usr %nice  %sys %iowait  %irq %soft %steal %idle
08:52:02 AM  all   12.0  0.0    5.0   2.0     0.0  0.5   18.0  62.5
08:52:03 AM  all   10.8  0.0    4.7   1.8     0.0  0.4   21.3  61.0

Qué significa: un %steal alto indica que la VM no está siendo planificada. Los watchdogs dentro de los guests pueden dispararse porque el tiempo efectivamente se detiene.

Decisión: si esto es una VM, trata la contención del host como sospecha de primera clase; ajusta los umbrales del watchdog con cuidado o arregla la capacidad del host.

Task 19: Identificar si ajustes de frecuencia/potencia CPU hacen algo raro

cr0x@server:~$ cat /sys/devices/system/cpu/cpufreq/policy0/scaling_governor 2>/dev/null || echo "cpufreq not exposed"
performance

Qué significa: el governor está en performance (a menudo bien para servidores). Los modos de ahorro de energía pueden interactuar con la latencia y los timeouts de dispositivo en algunas plataformas.

Decisión: si ves lockups correlacionados con C-states profundos o gestión agresiva de energía, coordina cambios en BIOS y parámetros del kernel; no hagas ajustes masivos a ciegas en producción.

Broma #1: Un watchdog que reinicia tu servidor es como un detector de humo que apaga el fuego haciendo detonar el edificio. Eficaz, pero aún así quieres el informe del incidente.

Tres microhistorias corporativas desde el terreno

Microhistoria 1: El incidente causado por una suposición equivocada

Tenían una narrativa clara: “La base de datos se colgó”. Los gráficos mostraban latencia de consultas subiendo y luego un precipicio. Un reinicio por watchdog siguió. Así que el comandante de incidente hizo lo que muchos hacemos bajo presión: asignó tareas al equipo de BD, pidió planes de consulta y apuntó “optimizar índices”.

El equipo de BD se enfadó pero actuó profesional. Recolectaron logs de consultas lentas, compararon líneas base y no encontraron nada espectacular. Mientras tanto, el colgamiento reapareció—otra vez durante un periodo de volumen de consultas “normal”. Tampoco coincidía con despliegues. La única característica estable era el reinicio por watchdog.

Un ingeniero de almacenamiento finalmente hizo una pregunta brusca: “¿Tenemos logs persistentes del kernel?” No los tenían. Journald era volátil. La única pista era una captura de consola truncada que alguien guardó desde un KVM remoto mostrando una línea sobre blocked for more than 120 seconds.

Habilitaron journald persistente y configuraron kdump. En la siguiente ocurrencia, los logs mostraron timeouts NVMe que escalaron a un hilo de journaling atascado en D, luego lockups. La base de datos fue daño colateral: esperaba un fsync que nunca llegó. La historia de “la base de datos se colgó” era reconfortante, pero errónea.

La corrección fue aburrida: actualizaciones de firmware para los NVMe, una actualización de kernel que mejoró el manejo de resets de controladora y una reversión de una configuración BIOS agresiva de gestión de energía PCIe. La BD era inocente, pero tomó una semana probarlo porque el equipo asumió que el componente más ruidoso causó la falla.

Microhistoria 2: La optimización que salió mal

Un equipo de plataforma quería una recuperación más rápida de crashes. Activaron un watchdog hardware con un timeout corto y configuraron systemd para mimarlo. Su lógica: si el kernel se congela, reiniciar rápido reduce el impacto al cliente. No era una idea loca; es un patrón estándar en appliances.

Luego desplegaron una “mejora de rendimiento”: escritura más agresiva de páginas sucias y mayores profundidades de cola I/O en sus nodos más ocupados. Funcionó en benchmarks. En producción, durante una ventana de compactación intensa, un subconjunto de nodos se volvía no responsive el tiempo suficiente para perder pings del watchdog. El watchdog hardware los reiniciaba a mitad de escritura.

Tras el reinicio, los sistemas de archivos reproducían journals, los servicios reiniciaban y la flota parecía “saludable”. Pero empezaron a sonar alarmas sutiles de corrupción de datos—no al instante, sino semanas después—porque algunas invariantes a nivel de aplicación no toleraban ser interrumpidas en ese punto. La optimización no corrompió directamente los discos; corrompió las suposiciones sobre atomicidad y la temporización de escrituras.

El post-mortem fue incisivo: el watchdog redujo el tiempo medio de recuperación pero aumentó el tiempo medio hasta demostrar inocencia. Enmascaró el patrón subyacente de bloqueos I/O y acortó la ventana para capturar evidencia. Habían cambiado “falla lenta visible” por “reinicio rápido invisible”.

Lo arreglaron aumentando los timeouts del watchdog, habilitando panic-on-lockup con kdump en un subconjunto de nodos e instrumentando la presión I/O. La lección grande: un watchdog no sustituye la planificación de capacidad y definitivamente no sustituye comprender las latencias cola del almacenamiento.

Microhistoria 3: La práctica aburrida pero correcta que salvó el día

Una firma financiera tenía una costumbre que la gente se burlaba: con cada actualización de kernel y cambio de firmware exigían una “plan de evidencia de fallo” de una página. Listaba dónde van los logs, si kdump está probado y qué logs fuera de banda se retienen. Nadie amaba ese documento. Parecía postureo de cumplimiento.

Entonces una flota de servidores empezó a hacer reinicios watchdog ocasionales bajo carga pico. Los equipos de aplicación estaban listos para culparse mutuamente, como manda la tradición. Pero el plan de evidencia significaba dos cosas ya verdaderas: journald era persistente y kdump había pasado pruebas en el último trimestre.

El primer incidente produjo un vmcore. Las trazas de pila del kernel mostraron un deadlock involucrando una ruta de driver específica bajo alta carga de interrupciones. Lo correlacionaron con una actualización de firmware reciente que cambió el comportamiento de moderación de interrupciones en un dispositivo PCIe que compartía el root complex con la controladora NVMe.

No tuvieron que esperar tres reinicios más “para estar seguros”. Revirtieron el firmware, aislaron el problema de topología PCIe y aplicaron una actualización de kernel con la corrección pertinente tras validar. El impacto en disponibilidad fue real pero contenido.

La práctica aburrida—mantener la captura de evidencia lista—no evitó el colgamiento. Evitó la segunda semana de caos. Esto es lo que parece una buena operación: no heroísmo, sino verdad preposicionada.

Ajustar watchdogs sin sabotearse

Los watchdogs tienen dos modos de fallo:

  • Demasiado sensibles: reinician sistemas sanos pero ocupados (falsos positivos), convirtiendo picos de carga en caídas.
  • Demasiado laxos: nunca disparan, dejándote con agujeros negros de horas hasta que alguien haga un power-cycle.

Ubuntu 24.04 te ofrece palancas en varias capas. Úsalas de forma deliberada.

Umbrales de lockup del kernel: no “arregles” lockups ocultándolos

kernel.watchdog_thresh controla cuánto tiempo antes de advertir sobre soft lockup. Aumentarlo puede reducir ruido en entornos de alta latencia, pero también retrasa la detección de deadlocks reales.

Mi sesgo: no subas umbrales hasta que hayas medido el scheduling de CPU y la presión de I/O. Si ves advertencias de lockup porque tu VM está hambrienta (%steal alto), arregla el host. Si ves advertencias porque los stalls de almacenamiento bloquean hilos críticos, arregla el almacenamiento.

Considera panic-on-lockup para forense (con salvaguardas)

Si no puedes reproducir el problema y es raro pero caro, configura:

  • kernel.softlockup_panic=1 y/o kernel.hardlockup_panic=1
  • Asegura que kdump funciona y que crashkernel está bien dimensionado
  • Prueba primero en un canario

Esto convierte un colgamiento en un volcado de kernel. Los crashes son depurables; los colgamientos silenciosos son vibes.

RuntimeWatchdogSec de systemd: alinéalo con la realidad

El watchdog runtime de systemd suele estar conectado al watchdog hardware. Si systemd no puede ejecutarse (porque el kernel está atascado), no puede mimar el watchdog y el hardware te reinicia. Eso está bien—si el timeout es lo bastante largo para evitar reinicios durante pausas legítimas (como reconstrucciones RAID pesadas o timeouts patológicos de dispositivo).

Regla práctica: fija el timeout del watchdog hardware más largo que la peor pausa de almacenamiento esperada más tiempo suficiente para la estrategia kdump/panic si la usas. Si tu array puede pausar I/O 45 segundos durante un failover de controladora, un watchdog runtime de 30 segundos es una autogenerada caída.

Broma #2: Si pones tu watchdog a 10 segundos en una caja de almacenamiento, no estás haciendo SRE—estás speedruneando la respuesta a incidentes.

Almacenamiento y bloqueos I/O: el colgamiento que parece cómputo

Como ingeniero de almacenamiento, este es el patrón que sigo viendo: aparecen advertencias de lockup de CPU en los logs, así que la culpa recae en CPU o scheduler. Pero el disparador suele ser I/O. Cuando el almacenamiento se bloquea, las tareas se quedan en estado D. Hilos del kernel se acumulan. El reclaim de memoria se enmaraña. Eventualmente una CPU entra en spin en una ruta que detiene el scheduling, y el watchdog dispara. La CPU es la mensajera.

Líneas de log reveladoras que implican almacenamiento

  • nvme ... I/O timeout, aborting
  • task ... blocked for more than ... seconds
  • Buffer I/O error, blk_update_request errors
  • Hilo de journaling del sistema de ficheros bloqueado: jbd2 (ext4) o stalls de log worker (XFS)
  • Resets y abortos SCSI (incluso si “no usas SCSI”—tu HBA sí)

Por qué Ubuntu 24.04 es relevante aquí

Ubuntu 24.04 tiende a desplegarse en plataformas más nuevas: NVMe, PCIe Gen4/Gen5, stacks de firmware modernos y más virtualización. Es un gran entorno para rendimiento—y también para casos límite raros donde un dispositivo, driver o topología PCIe hace algo “creativo” bajo presión.

Además: muchos equipos pasaron de SSD SATA (lentos, tolerantes) a NVMe (rápidos, complejos). El modo de fallo cambió de “es lento” a “funciona hasta que de repente no”.

Errores comunes: síntoma → causa raíz → solución

Estos no son fallos morales. Son trampas en las que cae la gente cuando el sistema vuelve y todos quieren seguir adelante.

Error 1: “Reinicio aleatorio” sin logs

Síntoma: el uptime se reinicia, los servicios reinician, no hay errores obvios en los logs del arranque actual.

Causa raíz: los logs estaban en RAM (journald volátil), y el reinicio borró el ring buffer.

Solución: habilita journald persistente y/o logging remoto; confirma que los logs del arranque previo se conservan (journalctl -b -1 debe ser útil).

Error 2: Confundir un reinicio por hardware watchdog con un panic de kernel

Síntoma: el sistema se reinicia abruptamente; la gente asume “el kernel se cayó”.

Causa raíz: el hardware watchdog disparó; no hubo panic, por lo que no hay vmcore y no hay salida final en consola.

Solución: decide si prefieres panic en lockup/hung task (con kdump) en lugar de reinicios a ciegas; ajusta el timeout del watchdog hardware para permitir la captura de evidencia.

Error 3: Tratar advertencias de soft lockup como “solo ruido”

Síntoma: líneas ocasionales BUG: soft lockup, el sistema “parece bien”.

Causa raíz: advertencia temprana de deadlocks de driver, tormentas IRQ o stalls de I/O. El sistema se recupera—hasta que no.

Solución: correlaciona con timeouts de dispositivo y PSI. Si se repite, reproduce bajo carga y captura vmcore usando panic-on-lockup en un canario.

Error 4: Subir umbrales del watchdog para dejar de reiniciar

Síntoma: los reinicios watchdog cesan tras ajustar; más tarde aparecen colgamientos de minutos sin recuperación automática.

Causa raíz: desactivaste la alarma en lugar de arreglar el fuego.

Solución: revierte umbrales; arregla la causa raíz (timeoutes de almacenamiento, %steal del host, bugs de driver). Usa un watchdog hardware más largo pero mantén la detección.

Error 5: Ignorar %steal en VMs

Síntoma: el watchdog del guest dispara “hard lockup” durante eventos de vecinos ruidosos.

Causa raíz: el guest está pausado/hambriento por el hypervisor; los timeouts disparan dentro del guest.

Solución: arregla el scheduling/capacidad del host; haz pinning de vCPUs o ajusta prioridades VM. Si debes, aumenta umbrales en guests—pero considéralo un parche, no la cura.

Error 6: Culpar a la base de datos porque fue la primera en quejarse

Síntoma: picos de latencia y timeouts en la BD antes del reinicio.

Causa raíz: la BD suele ser la primera en bloquearse en fsync; el problema real es almacenamiento o la ruta I/O del kernel.

Solución: inspecciona logs del kernel por errores NVMe/SCSI/sistema de ficheros y tareas colgadas; mide presión I/O y latencias cola en los dispositivos de bloque.

Listas de verificación / plan paso a paso

Paso a paso: prepárate para atrapar el próximo colgamiento

  1. Activa logs persistentes (journald en disco) y establece límites de retención.
  2. Asegúrate de poder leer el arranque previo: verifica que journalctl -b -1 contiene mensajes del kernel.
  3. Habilita y prueba kdump en ventana de mantenimiento usando SysRq crash; confirma que se escribe un vmcore.
  4. Decide tu estrategia:
    • Opción A: reinicio watchdog para recuperación rápida (menos evidencia)
    • Opción B: panic-on-lockup + kdump para evidencia (más evidencia, crash controlado)
  5. Instrumenta la presión I/O (PSI) y obtén una línea base. Si no sabes cómo es lo normal, no puedes señalar lo anormal.
  6. Recolecta logs fuera de banda (BMC SEL, eventos watchdog) cuando sea posible. Si no puedes, al menos alinea con el equipo de hardware sobre cómo recuperarlos.
  7. Cambios canario: aplica actualizaciones de kernel/firmware a un subconjunto; mantén un rollback. El objetivo es cambiar una variable a la vez.

Checklist de incidente: cuando el reinicio ya pasó

  1. Confirma la ventana del arranque previo: journalctl -b -1 y last -x.
  2. Extrae las últimas 200 líneas del kernel del arranque previo; busca lockups, tareas colgadas, resets de dispositivo.
  3. Revisa logs de error de almacenamiento (error-log NVMe, timeouts kernel, errores de sistema de ficheros).
  4. Revisa señales de virtualización: %steal y contención del host si aplica.
  5. Revisa versiones de firmware y kernel por cambios recientes; correlaciónalos con el inicio del incidente.
  6. Apunta una hipótesis y una prueba que la refute. Evita la reunión de “veinte posibles causas”.

Checklist de control de cambios: ajustar parámetros del watchdog

  • No ajustes timeouts antes de confirmar si tratas con lockups de CPU, stalls de I/O o inanición del guest.
  • Si habilitas panic-on-lockup, asegúrate de que kdump funciona y el almacenamiento de volcados es fiable.
  • Mantén timeouts del watchdog cómodamente por encima de las peores pausas conocidas (failover de controladora, lecturas RAID patrol, compactaciones intensas).
  • Documenta la razón. El tú del futuro no recordará por qué RuntimeWatchdogSec=73s pareció buena idea.

Preguntas frecuentes

1) ¿Cuál es la diferencia entre un soft lockup y un hard lockup?

Un soft lockup ocurre cuando una CPU ejecuta código del kernel demasiado tiempo sin scheduling; el kernel puede seguir registrando advertencias. Un hard lockup ocurre cuando la CPU deja de responder a interrupciones; la detección es más difícil y a menudo involucra NMIs o fuentes de temporización.

2) ¿Por qué los reinicios watchdog parecen “aleatorios”?

Porque la condición disparadora suele estar en la cola de una distribución: timeouts de almacenamiento raros, deadlocks de driver raros o contención rara en el host. El reinicio ocurre tras un timeout, no en el momento en que el sistema empezó a fallar.

3) ¿Debería desactivar los watchdogs para dejar de reiniciar?

Sólo si te gustan los colgamientos de varias horas que requieren power-cycles manuales. Mantén los watchdogs. En su lugar, mejora la captura de evidencia (logs persistentes, kdump) y arregla los stalls subyacentes.

4) Si activo panic-on-lockup, ¿no reducirá eso el uptime?

Pueda que sí, a corto plazo, porque convierte “tal vez se recupere” en “se cae”. A cambio obtienes un vmcore y puedes arreglar la causa raíz. Para colgamientos recurrentes en producción, ese tradeoff suele rentabilizarse rápidamente.

5) ¿Puede el almacenamiento realmente causar mensajes de lockup de CPU?

Sí. Los stalls de I/O pueden bloquear hilos críticos del kernel, provocar tormentas de reclaim y crear contención por locks. El watchdog reporta dónde la CPU quedó atascada, no necesariamente qué inició la cascada.

6) ¿Cómo sé si mi VM está siendo hambrienta por el hypervisor?

Mira mpstat y la columna %steal. Un steal alto indica que el guest quiso CPU pero no fue planificado. Eso puede hacer que los timeouts se disparen incluso cuando el guest “está bien”.

7) ¿Por qué no obtuve un volcado de crash?

Porque un reinicio por watchdog no es un panic, y kdump se dispara en panics. Además, kdump falla si crashkernel no está reservado o es insuficiente, o si el destino del volcado no está disponible durante el crash.

8) ¿Cuál es la forma más rápida de encontrar los logs más relevantes tras un reinicio?

Usa journalctl -b -1 -k y filtra por lockups, tareas colgadas y errores de dispositivo. Luego correlaciona timestamps con alertas de aplicación. Si los logs no son persistentes, arregla eso primero.

9) ¿El watchdog de systemd es lo mismo que el watchdog del kernel?

No. El watchdog de systemd alimenta un dispositivo watchdog (a menudo hardware). Los watchdogs del kernel detectan lockups dentro del scheduling/interrupciones del kernel. Pueden interactuar, pero son mecanismos distintos con modos de fallo distintos.

10) ¿Qué hago si la máquina se reinicia tan fuerte que ni siquiera journald alcanza a flush?

Entonces necesitas redundancia: logging remoto, logs fuera de banda y/o una estrategia de panic que escriba un vmcore vía kdump. Si la ruta de disco es lo que se cuelga, los logs locales son inherentemente frágiles.

Conclusión: próximos pasos que realmente reducen el tiempo de inactividad

Si no haces nada más esta semana, haz estas tres cosas:

  1. Haz fiables los logs del arranque previo: journald persistente, retención configurada y confirma que journalctl -b -1 es útil.
  2. Consigue una ruta de volcado de crashes que funcione: habilita y prueba kdump. Un solo vmcore puede ahorrarte meses de especulación.
  3. Elige una postura sobre el comportamiento del watchdog: reinicio rápido para disponibilidad, o panic-on-lockup para evidencia. No te quedes en un estado medio configurado que no te da ni una cosa ni la otra.

Luego ataca las causas raíz con sesgo hacia los sospechosos habituales: timeouts de almacenamiento, errores PCIe, %steal en VMs e interacciones driver/firmware. Los watchdogs no crean el colgamiento. Solo se niegan a dejar que te robe silenciosamente el uptime.

← Anterior
Migración de MariaDB a PostgreSQL: Moverse sin tiempo de inactividad y sin sorpresas
Siguiente →
MySQL vs MariaDB en un VPS de 16GB: cuándo la replicación y el pooling son obligatorios

Deja un comentario