La era del botón de reinicio: la solución más honesta en informática

¿Te fue útil?

Algunas fallas no provocan un bloqueo; simplemente se pudren. La latencia se eleva poco a poco. Un daemon deja de responder pero nunca “muere”. Una ruta de almacenamiento falla una vez por hora como si aclarara la garganta. Tu monitorización muestra mil pequeños cortes, y el negocio quiere una gran curita.

Entonces alguien lo dice, en voz baja, como una confesión: “¿Deberíamos simplemente reiniciarlo?” La era del botón de reinicio es cuando esa pregunta deja de ser vergonzosa y empieza a ser operacionalmente madura, siempre que sepas qué hace realmente un reinicio, qué oculta y qué debes recopilar antes de pulsarlo.

Por qué los reinicios parecen honestos (y por qué también son una mentira)

Un reinicio es una ruptura limpia en la causalidad. Dejas de intentar negociar con un runtime corrupto y empiezas de nuevo con rutas de inicialización conocidas y buenas: arranque del kernel, inicialización de drivers, arranque de servicios, carga de configuración, calentamiento de cachés. Para una gran categoría de fallos—fugas, deadlocks, I/O atascado, drivers bloqueados—la inicialización es la única ruta de código que se ha probado 10.000 veces.

Esa es la parte honesta. La parte deshonesta es que un reinicio a menudo destruye evidencia. Borra la escena del crimen, tira las trazas de pila y reinicia contadores que te estaban diciendo exactamente lo mal que iba todo.

Así que trata el reinicio como tratarías un analgésico después de una lesión. Úsalo para funcionar, claro. Pero si sigues tomándolo sin diagnóstico, no eres “duro”, simplemente estás volando a ciegas.

Aquí está la verdad operacional: el reinicio es una mitigación válida. Gana tiempo. Reduce el radio de impacto. Recupera a tus clientes. Pero si es tu única jugada, acabarás con un sistema que “necesita” reinicios como una fábrica victoriana necesitaba trabajo infantil: funciona, pero no es un plan.

Broma #1: Un reboot es la disculpa más sincera que puede ofrecer una computadora: no puede explicar lo que pasó, pero promete mejorar.

Cuando un reinicio es la decisión correcta

  • Se está incumpliendo el SLO y tienes una reversión o procedimiento de reinicio conocido y fiable.
  • El estado ya es sospechoso (errores de sistema de archivos, advertencias del kernel, reinicios de NIC, señales de corrupción del asignador).
  • No puedes reproducirlo bajo observación y necesitas una línea base estable para recopilar mejores datos la próxima vez.
  • Contención del radio de impacto: aislar un nodo, drenar la carga, reiniciar, volver a unir.

Cuando un reinicio es mala práctica

  • No has capturado la forense básica (logs, dmesg, principales culpables) y estás a punto de borrarlos.
  • Reiniciar provocará una reconstrucción (RAID, ZFS resilver, recuperación de base de datos) que aumenta el riesgo.
  • El problema es claramente externo (dependencia upstream caída, partición de red, certificado expirado). Reiniciar no cambia nada.
  • Usas el reinicio para evitar admitir que no tienes observabilidad.

Hay una idea parafraseada de Werner Vogels (CTO de Amazon) que debería estar en la pared de todos los equipos de ops: construyes para la falla, porque todo falla eventualmente. La era del botón de reinicio es lo que sucede cuando aceptas esa afirmación literalmente y la operacionalizas: las fallas pasarán; la pregunta es si tus reinicios son controlados e informativos, o caóticos y olvidadizos.

Hechos e historia: cómo llegamos hasta aquí

Los reinicios no son un fallo moral; son una consecuencia de la complejidad. Algunos puntos concretos que explican por qué reiniciar se ha mantenido relevante durante décadas:

  1. Los microordenadores tempranos normalizaron los reinicios duros. Muchos sistemas domésticos alentaban el ciclo de energía como recuperación rutinaria porque el estado persistente y el journaling no eran la base.
  2. El “salto de tres dedos” se convirtió en memoria muscular cultural. Los reinicios por teclado en los primeros PCs convirtieron el “reset” en una solución de usuario, no en una solución de ingeniería.
  3. Los temporizadores watchdog existieron mucho antes de la nube. Los sistemas embebidos usaban watchdogs hardware para reiniciar automáticamente cuando el software dejaba de dar latidos.
  4. Los sistemas de archivos con journaling redujeron—pero no eliminaron—el dolor del reinicio. Hicieron la recuperación tras un crash más rápida y segura, lo que paradójicamente hizo que los reinicios fuesen más aceptables en producción.
  5. La virtualización hizo el reinicio más barato. Cuando un “servidor” es una VM, reiniciarlo se siente menos dramático que mover un carro físico por un pasillo de un datacenter.
  6. Los contenedores normalizaron las re-inicializaciones otra vez. Reiniciar un pod es un evento planificado; los frameworks de orquestación tratan los procesos como desechables.
  7. Los sistemas modernos dependen de cachés por todas partes. Cachés DNS, page cache, pools de conexiones, cachés JIT, tablas de enrutamiento. Los reinicios los vacían—a veces mejorando las cosas, otras veces provocando una estampida.
  8. Las actualizaciones de firmware y microcódigo difuminaron la línea entre “arreglo de software” y “reinicio requerido”. Un parche de seguridad puede requerir un reinicio porque cambió el handshake entre kernel y hardware.
  9. Las pilas de almacenamiento se volvieron multi-capa. RAID/firmware HBA, multipath, sistema de archivos, gestor de volúmenes, cifrado, aplicación. Un reinicio puede arreglar una capa atascada, pero debes identificar cuál.

Fíjate en el patrón: los reinicios se hicieron más fáciles, y “más fácil” cambió la cultura. El peligro es que lo fácil se convierta en predeterminado, y lo predeterminado en doctrina.

Lo que realmente cambia un reinicio: capas, cachés, estado y tiempo

1) Memoria de procesos y estado del asignador

La mayoría de las historias de “reiniciar lo arregló” en realidad son “un espacio de direcciones nuevo lo arregló”. Fugas de memoria, fragmentación, contención del asignador, hilos desbocados, fugas de descriptores de archivo—reiniciar los borra todos, al precio de no demostrar cuál fue el responsable.

2) Estado del kernel y de los drivers

Los bugs del kernel son raros hasta que no lo son. Un reinicio restablece estructuras del kernel: tablas de páginas, colas del scheduler, estado TCP, máquinas de estado de drivers de dispositivo. Si un driver quedó colgado—común con NICs, HBAs, GPUs y algunos dispositivos virtuales—un reinicio es una forma burda pero efectiva de forzar la re-inicialización.

3) Cachés de almacenamiento y colas de I/O

El almacenamiento tiene dos tipos de estado: estado de datos (en disco) y estado operativo (en vuelo). Un reinicio borra el estado operativo: I/O pendientes, profundidades de cola, decisiones de multipath, control de congestión. Eso puede “arreglar” una espiral de latencia, pero también puede desencadenar una reconstrucción, rescan o failover del controlador en el peor momento posible.

4) Sesiones de red y afinidad de balanceadores

Los reinicios cortan conexiones TCP, reinician tablas conntrack y fuerzan a los clientes a reconectar. En un sistema sano, eso está bien. En un sistema frágil, se convierte en una tormenta de reconexiones sincronizadas que parece un DDoS autoinducido.

5) Tiempo: la dependencia silenciosa

Muchos bugs dependen del tiempo: caducidad de certificados, lógica de refresco de tokens, cron jobs, rotación de logs, contadores alcanzando un umbral, safepoints de JVM bajo presión de heap. Un reinicio puede “solucionar” el síntoma al reiniciar relojes y contadores en espacio de usuario, mientras la condición subyacente sigue avanzando hacia el siguiente precipicio.

Reiniciar vs reboot vs ciclo de energía: elige el martillo más pequeño que funcione

Reinicio de servicio

Úsalo cuando la falla parezca confinada a un solo proceso o a un pequeño conjunto de daemons. Ejemplos: memoria desbocada en un servicio, pool de workers atascado, cola interna bloqueada, recarga de configuración que salió mal. Un reinicio preserva el estado del kernel, evita el rescan de almacenamiento y es más rápido de revertir.

Reboot del nodo

Úsalo cuando las capas del kernel o orientadas al hardware parezcan sospechosas: reinicios recurrentes de drivers, procesos inmatables en estado D, bloqueos de I/O del sistema de archivos, NICs con flapping, desincronización severa del reloj, o si necesitas aplicar una actualización de kernel.

Ciclo de energía (reset duro)

Úsalo cuando el sistema no responde a un reboot limpio, o el plano de gestión muestra hardware atascado (eventos BMC, problemas PCIe, HBA bloqueado). Esta es la opción de “necesito que los electrones se detengan y vuelvan a empezar”. Puede ser necesaria. Nunca es suave.

Broma #2: Hacer power-cycle es como apagar y encender a tu compañero de trabajo: efectivo, pero Recursos Humanos querrá un informe postmortem.

Una regla para decidir que funciona bajo presión

Empieza en la parte alta de la pila y baja solo si la evidencia te empuja:

  • Si un servicio se está comportando mal: reinicia el servicio.
  • Si muchos servicios fallan en un nodo: reinicia el nodo (después de drenar si es posible).
  • Si el nodo no puede reiniciarse o el hardware está atascado: realiza un power-cycle.

Y sin importar lo que elijas: captura suficiente evidencia para que el próximo incidente sea más corto.

Guía de diagnóstico rápido: encuentra el cuello de botella antes de “arreglarlo”

Este es el orden de triaje que funciona cuando el pager suena fuerte y tienes cinco minutos para ser útil. El objetivo no es ser brillante. El objetivo es dejar de adivinar.

Primero: ¿es un equipo, un servicio o toda la flota?

  • Comprueba si el síntoma se correlaciona con un nodo, una AZ/rack, un despliegue o una dependencia.
  • Si múltiples nodos muestran síntomas idénticos simultáneamente, los reinicios suelen ser ruido. Busca dependencias compartidas (DNS, auth, backend de almacenamiento, red).

Segundo: ¿CPU, memoria, I/O o red?

  • Limitado por CPU: alta carga, cola de ejecución alta, bajo iowait, top muestra hilos calientes.
  • Presión de memoria: actividad de swap, stalls de reclaim, OOM kills, RSS en crecimiento.
  • Limitado por I/O: alto iowait, latencia de disco en aumento, tareas bloqueadas, advertencias del sistema de archivos.
  • Limitado por red: retransmisiones, pérdidas, saturación de conntrack, timeouts DNS.

Tercero: señales del kernel y hardware

  • dmesg/journal muestra reinicios de dispositivo, enlace abajo/arriba, errores de sistema de archivos, tareas colgadas.
  • Errores SMART, degradación de pool ZFS, flapping de multipath.

Cuarto: elige la mitigación más pequeña que restituya el servicio

  • Reinicia un servicio si el nodo parece sano.
  • Drena y reinicia si el estado a nivel de nodo es sospechoso.
  • Haz failover si la ruta de almacenamiento/red es inestable.

Quinto: después de la estabilidad, convierte la mitigación en diagnóstico

  • Anota qué cambió después del reinicio: latencia, tasas de error, contadores del kernel, ratios de acierto de caché.
  • Crea una hipótesis que puedas probar antes del próximo incidente.

Tareas prácticas: comandos, salidas y decisiones (12+)

Estos son los comandos “antes de reiniciar” y “justo después de reiniciar” que realmente quiero en una checklist de incidentes. Cada uno incluye qué significa la salida y qué decisión tomas a partir de ella.

1) Uptime y carga: ¿estamos en muerte lenta o fallo repentino?

cr0x@server:~$ uptime
 14:22:10 up 87 days,  3:41,  2 users,  load average: 18.44, 17.90, 16.72

Significado de la salida: 87 días de actividad; los promedios de carga son altos y persistentes (no un pico corto).

Decisión: Si es un solo nodo y la carga es anormal, procede a separar CPU vs I/O. No reinicies aún; recopila por qué la carga es alta.

2) Instantánea de top: CPU vs iowait vs proceso desbocado

cr0x@server:~$ top -b -n 1 | head -n 20
top - 14:22:25 up 87 days,  3:41,  2 users,  load average: 18.44, 17.90, 16.72
Tasks: 312 total,   2 running, 310 sleeping,   0 stopped,   0 zombie
%Cpu(s):  8.3 us,  2.1 sy,  0.0 ni, 21.7 id, 67.6 wa,  0.0 hi,  0.3 si,  0.0 st
MiB Mem :  64049.2 total,   1800.5 free,  51221.4 used,  11027.3 buff/cache
MiB Swap:   8192.0 total,   8120.0 free,     72.0 used.  10341.8 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
18342 postgres  20   0 12.1g  9.2g  9120 S  120.0  14.7  36:12.44 postgres

Significado de la salida: iowait es enorme (67.6% wa). La CPU espera en disco, no está procesando trabajo.

Decisión: No reinicies una base de datos porque está esperando en disco; encuentra primero el cuello de botella de almacenamiento. Reiniciar puede empeorar el tiempo de recuperación y provocar tormentas de I/O.

3) Identificar tareas bloqueadas (la trampa clásica “el reinicio lo arregla”)

cr0x@server:~$ ps -eo pid,state,comm,wchan:32 | awk '$2 ~ /^D/ {print}'
21991 D kworker/u96:2      nvme_poll
18342 D postgres           io_schedule

Significado de la salida: Procesos en sueño no interrumpible (estado D), esperando rutas de I/O.

Decisión: Reiniciar el servicio no ayudará. Investiga almacenamiento/NVMe/HBA/multipath. Si la ruta de I/O está atascada y puedes hacer failover, hazlo; de lo contrario planifica un reinicio con evidencia capturada.

4) Mensajes del kernel para almacenamiento o reinicios de drivers

cr0x@server:~$ sudo dmesg -T | tail -n 20
[Mon Jan 21 13:58:12 2026] nvme nvme0: I/O 47 QID 4 timeout, aborting
[Mon Jan 21 13:58:12 2026] nvme nvme0: Abort status: 0x371
[Mon Jan 21 13:58:13 2026] nvme nvme0: resetting controller
[Mon Jan 21 13:58:18 2026] nvme nvme0: failed to set APST feature (-19)

Significado de la salida: Timeouts NVMe y reinicios de controlador; el kernel te está diciendo que el dispositivo es poco fiable.

Decisión: Un reinicio puede recuperar temporalmente el dispositivo, pero trátalo como trabajo de hardware/firmware/driver. Programa reemplazo o actualización de firmware; no normalices los “siestas NVMe” semanales.

5) Latencia de disco y saturación con iostat

cr0x@server:~$ iostat -x 1 3
Linux 6.5.0-21-generic (server) 	01/21/2026 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          7.89    0.00    2.34   66.85    0.00   22.92

Device            r/s     w/s   rkB/s   wkB/s  avgrq-sz avgqu-sz   await  r_await  w_await  svctm  %util
nvme0n1         12.0   420.0   512.0  8752.0     43.1    198.4   451.2     9.8   462.5    2.1  99.7

Significado de la salida: %util ~99.7 y await ~451ms: el dispositivo está saturado y la latencia es terrible.

Decisión: Deja de culpar a la app. Reduce la carga de escritura, mueve datos calientes o añade capacidad de IOPS. Reiniciar no cambiará las leyes físicas.

6) Encontrar qué sistemas de archivos están llenos (el mito más antiguo “reiniciar lo arregla”)

cr0x@server:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/nvme0n1p2  220G  219G  1.2G 100% /
tmpfs            32G  1.2G   31G   4% /run

Significado de la salida: El sistema de archivos root está prácticamente lleno. Muchos servicios fallan de maneras extrañas cuando no pueden escribir logs o archivos temporales.

Decisión: Libera espacio inmediatamente (logs, core dumps, artefactos antiguos). Reiniciar no creará espacio en disco; solo puede retrasar las escrituras hasta que vaya a peor.

7) Identificar directorios grandes rápidamente

cr0x@server:~$ sudo du -xhd1 /var | sort -h | tail -n 10
1.1G	/var/cache
2.9G	/var/lib
4.8G	/var/crash
58G	/var/log

Significado de la salida: /var/log es enorme; /var/crash indica crashes repetidos o core dumps.

Decisión: Rota/comprime logs, muévelos fuera del nodo, arregla el loop de crash. Considera limitar core dumps. No reinicies hasta detener el crecimiento.

8) Chequeo de presión de memoria: ¿el kernel se está reclamando hasta morir?

cr0x@server:~$ free -m
               total        used        free      shared  buff/cache   available
Mem:           64049       59721         811         922        3516        1920
Swap:           8192        6130        2062

Significado de la salida: Poca memoria disponible y uso significativo de swap. La máquina probablemente está haciendo thrashing.

Decisión: Si un servicio concreto está hinchado, reinícialo. Si es sistémico (muchos procesos, caches del kernel que no reclaman, fragmentación), planifica un reinicio pero captura primero los procesos culpables.

9) ¿Quién consume memoria ahora mismo?

cr0x@server:~$ ps -eo pid,comm,rss --sort=-rss | head -n 10
  PID COMMAND           RSS
18342 postgres      9654320
22107 java          8421000
 9821 node          1320040

Significado de la salida: Unos pocos procesos dominan la memoria. Es una buena noticia: un reinicio dirigido puede arreglarlo sin reiniciar todo.

Decisión: Reinicia o recicla al principal ofensor después de confirmar que puede reiniciarse con seguridad (HA, reinicio rolling, drenar).

10) Salud de servicios systemd y fallos recientes

cr0x@server:~$ systemctl --failed
  UNIT                 LOAD   ACTIVE SUB    DESCRIPTION
● app-worker.service   loaded failed failed Background worker
● nginx.service        loaded failed failed A high performance web server

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state.
SUB    = The low-level unit activation state.

Significado de la salida: Servicios específicos han fallado; no necesariamente es una falla del nodo.

Decisión: Intenta reiniciar el servicio e inspecciona logs. Si fallan por disco lleno, DNS o configuración, reiniciar es irrelevante.

11) Logs del journal alrededor de la ventana de fallo

cr0x@server:~$ sudo journalctl -u nginx.service -S "10 minutes ago" --no-pager | tail -n 20
Jan 21 14:13:41 server nginx[29110]: nginx: [emerg] open() "/var/log/nginx/access.log" failed (28: No space left on device)
Jan 21 14:13:41 server systemd[1]: nginx.service: Main process exited, code=exited, status=1/FAILURE

Significado de la salida: Falla explícita: no hay espacio en el dispositivo.

Decisión: Libera espacio en disco y luego reinicia nginx. Reiniciar es una pérdida de tiempo y probablemente fallará de nuevo.

12) Pérdidas y errores de red (contadores de interfaz)

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    RX:  bytes  packets  errors  dropped  missed  mcast
    9876543210  12345678  0       48219    0       0
    TX:  bytes  packets  errors  dropped  carrier collsns
    8765432109  11223344  0       0        0       0

Significado de la salida: Las pérdidas RX son altas. Eso puede significar problemas de driver, límites de buffers del ring, o congestión upstream.

Decisión: Investiga ajustes de offload de la NIC, dimensionamiento de buffers, contención de CPU del host, o congestión en el switch upstream. Reiniciar puede reiniciar contadores y “arreglar” temporalmente un driver atascado, pero necesitas causalidad.

13) Sanidad de resolución DNS (chequeo rápido para “todo está roto”)

cr0x@server:~$ resolvectl query api.internal
api.internal: resolve call failed: Timeout was reached

Significado de la salida: Timeouts DNS. Esto a menudo se disfraza de fallo de aplicación en muchos servicios.

Decisión: No reinicies todo. Arregla DNS o la ruta del resolvedor. Considera caché local del resolvedor o resolvers de failover.

14) Salud del sistema de archivos: errores ext4 visibles en logs

cr0x@server:~$ sudo dmesg -T | grep -E "EXT4-fs error|I/O error|Buffer I/O" | tail -n 5
[Mon Jan 21 14:01:12 2026] EXT4-fs error (device nvme0n1p2): ext4_find_entry:1587: inode #131081: comm nginx: reading directory lblock 0
[Mon Jan 21 14:01:12 2026] Buffer I/O error on dev nvme0n1p2, logical block 9123456, lost async page write

Significado de la salida: Errores reales de sistema de archivos y de I/O. Esto no es un bug de la aplicación.

Decisión: Trátalo como un incidente de almacenamiento. Reduce escrituras, haz failover, planifica mantenimiento. Reiniciar puede empeorar el riesgo de corrupción si el hardware falla.

15) Estado de pool ZFS (si usas ZFS, debes mirarlo)

cr0x@server:~$ sudo zpool status -x
pool 'tank' is degraded
One or more devices could not be used because the label is missing or invalid.

Significado de la salida: El pool está degradado; la redundancia está reducida.

Decisión: No reinicies a la ligera. Un reinicio puede desencadenar resilvering y picos de I/O. Reemplaza/arregla el dispositivo faltante primero o programa una ventana de mantenimiento controlada con límites claros de I/O.

16) Flapping de multipath (a SAN le encanta “sanar” tras reinicios)

cr0x@server:~$ sudo multipath -ll | head -n 25
mpatha (3600508b400105e210000900000490000) dm-2 DELL,MD36xxi
size=2.0T features='1 queue_if_no_path' hwhandler='1 alua' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| `- 3:0:0:1 sdb 8:16 active ready running
`-+- policy='service-time 0' prio=10 status=enabled
  `- 4:0:0:1 sdc 8:32 active ready running

Significado de la salida: Existen rutas con diferentes prioridades (ALUA). Si ves “failed faulty running” o caminos alternando, tienes un problema de fabric/controlador.

Decisión: Involucra al equipo de almacenamiento/red; no lo enmascares con reinicios. Si queue_if_no_path está activo, puedes estar acumulando latencia hasta que todo haga timeout.

17) Antes de reiniciar: captura un bundle de incidente ligero

cr0x@server:~$ sudo sh -c 'date; uname -a; uptime; free -m; df -h; dmesg -T | tail -n 200' > /var/tmp/pre-reboot-triage.txt

Significado de la salida: Has preservado el estado básico que un reinicio va a borrar (especialmente la cola de dmesg y snapshots de recursos).

Decisión: Si debes reiniciar, hazlo después de guardar este archivo en un lugar durable (logs centrales, adjunto de ticket, scp a bastión).

Tres micro-historias corporativas de la era del botón de reinicio

Micro-historia 1: El incidente causado por una suposición errónea

El equipo tenía un clúster de servidores de aplicación detrás de un balanceador de carga. Cada nodo tenía NVMe local para cache efímera, y el sistema real de registro era una base de datos remota. El modelo mental era: “el disco local es solo caché; si muere, reiniciamos y vuelve.”

Una tarde, la tasa de error subió en una línea diagonal limpia. La latencia aumentó, pero solo para un subconjunto de peticiones. El on-call reinició el servicio de la app. Sin cambio. Reiniciaron un nodo. Ese nodo volvió rápido y parecía sano cinco minutos, luego degradó otra vez. Reiniciaron dos nodos más. Mismo cuento, ahora con más thrash visible para clientes.

La suposición errónea fue sutil: el NVMe local no era meramente una caché. Albergaba un spool write-ahead para eventos salientes, diseñado para sobrevivir reinicios de procesos y breves fallos de red. Reiniciar borró el spool porque estaba en un tmpfs montado “temporal por diseño”. En la práctica, fue temporal por accidente.

Cuando el colector upstream se ralentizó, el spool se llenó y la app aplicó backpressure. Ese comportamiento era correcto. Pero el reinicio borró el spool y creó la ilusión de recuperación—hasta que la vía lenta downstream lo volvió a llenar. Mientras tanto, el spool borrado significó eventos perdidos, lo que disparó reintentos compensatorios más tarde y alargó la cola del incidente.

Lo arreglaron moviendo el spool a almacenamiento persistente (con políticas de ciclo de vida explícitas), añadiendo alertas sobre la profundidad del spool y cambiando los runbooks: “nunca reiniciar para limpiar backpressure a menos que aceptes pérdida de datos”. El botón de reinicio no causó el cuello de botella. Solo hizo que el cuello de botella fuera deshonesto.

Micro-historia 2: La optimización que salió mal

Un grupo de plataforma decidió reducir el tiempo de reinicio para una flota de nodos. Reinicios más rápidos significaban parches más rápidos, evacuaciones más rápidas y menos riesgo de downtime. Así que optimizaron el arranque: paralelizaron el inicio, redujeron el logging, recortaron comprobaciones “lentas” y deshabilitaron un escaneo de almacenamiento que “nunca encontraba nada”.

Durante semanas, pareció una victoria. Los reinicios bajaron de minutos a menos de un minuto. Las ventanas de cambio se hicieron más cortas. La gente dejó de temer las actualizaciones de kernel. El botón de reinicio se volvió más seguro, así que se usó más.

Entonces un nodo se reinició durante un parche rutinario y volvió con un espejo de almacenamiento degradado. Nadie lo notó porque el escaneo que lo habría detectado estaba desactivado. El nodo se reincorporó y reanudó carga. Bajo carga, el disco restante empezó a mostrar errores intermitentes. La capa de aplicación vio timeouts y reintentó. Los reintentos generaron más carga. Bucle de realimentación positiva clásico.

Cuando alguien revisó la salud del almacenamiento, el nodo estaba en espiral de fallo: el manejo de errores generaba más I/O que el servicio normal. Habían eliminado una señal temprana. Habían cambiado fiabilidad por un mejor cronómetro.

La solución no fue abandonar la optimización; fue entender lo que eliminaron. Reinstauraron las comprobaciones de salud, las hicieron asíncronas cuando fue posible, y exigieron que la admisión del nodo al clúster pase esas comprobaciones. Reinicio rápido está bien. Reinicio rápido hacia almacenamiento roto es simplemente una forma más rápida de hacerse daño.

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

Otra empresa, otra cultura. El equipo de plataforma tenía un ritual que llamaban “snapshots pre-mortem”. No era sofisticado: antes de cualquier mitigación disruptiva (reinicio, failover, reinicio rolling), ejecutaban un pequeño conjunto de comandos y guardaban la salida en el ticket del incidente.

Durante un incidente, un nodo empezó a dejar caer peticiones sin patrón obvio. CPU bien. Memoria bien. Los logs del servicio no ayudaban. Todos querían reiniciar porque era la manera más rápida de detener el dolor.

El on-call siguió la práctica aburrida de todos modos. Capturó la cola de dmesg, iostat y contadores de interfaz. dmesg mostró reinicios ocasionales de NIC. Contadores de interfaz mostraron RX drops en aumento. iostat estaba limpio. Esa evidencia cambió la decisión: en lugar de reinicios repetidos, drenaron el nodo y reemplazaron la configuración de la NIC (función virtual en este caso). También ajustaron afinidad de interrupciones en el host.

El nodo volvió a servicio sin un solo reinicio. Más importante, el equipo no perdió horas “arreglando” un problema de red con reinicios que solo habrían limpiado contadores y reiniciado el estado del driver. El hábito de snapshots aburridos no solo salvó el día; salvó la narrativa. El postmortem tuvo evidencia, no folklore.

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

1) “Reiniciar lo arregló” se convierte en el título del ticket

Síntoma: El incidente se resuelve tras un reinicio; no se toma ninguna acción adicional.

Causa raíz: Evidencia destruida; amnesia organizacional. El sistema sigue frágil.

Solución: Exigir un bundle forense mínimo antes del reinicio y una hipótesis post-incidente. Si no puedes hacer ambos, admite que eliges disponibilidad sobre aprendizaje—y programa el aprendizaje para después.

2) Reinicios de servicio en bucle

Síntoma: systemd muestra un servicio en flap; se reinicia cada pocos segundos.

Causa raíz: Dependencia externa caída (DNS, DB, disco lleno), mala configuración o fallos de permisos.

Solución: Usa journalctl -u para encontrar el primer error; arregla la dependencia. Reinicios no son recuperación si la causa es determinística.

3) “Es CPU” porque el load average sube

Síntoma: El promedio de carga sube; los ingenieros asumen saturación de cómputo.

Causa raíz: Load incluye tareas ejecutables y no interrumpibles. I/O wait puede inflar la carga con bajo uso de CPU.

Solución: Revisa iowait en top/iostat y busca procesos en estado D. Si iowait es alto, trátalo como un problema de almacenamiento/ruta de I/O.

4) Reiniciar la base de datos durante un incidente de I/O

Síntoma: Latencia DB se dispara; reiniciar “ayuda” brevemente; luego peor.

Causa raíz: Saturación de almacenamiento o errores de dispositivo; el reinicio dispara recuperación, reproduce WAL, calienta caché desde frío y aumenta I/O.

Solución: Reduce amplificación de escrituras, para trabajos pesados, mueve datos calientes, limita compactions/checkpoints y arregla almacenamiento. Reinicia solo después de contener.

5) Power-cycle oculta un disco fallando

Síntoma: Hangs de I/O ocasionales; power-cycle restaura servicio por días.

Causa raíz: Bug de firmware de disco o medio degradado; los resets borran estados de error temporalmente.

Solución: Correlaciona errores de dmesg con stats SMART o degradación de pool; reemplaza hardware, actualiza firmware, valida cableado/backplane.

6) Vaciar cachés “arregla” el rendimiento

Síntoma: Tras reiniciar, la latencia mejora mucho y luego empeora lentamente.

Causa raíz: Contaminación de caché, fragmentación, fuga de memoria o cardinalidad ilimitada (por ejemplo cachés por inquilino).

Solución: Mide ratio de aciertos de caché y comportamiento de expulsión; implementa límites de caché, TTLs y métricas. No trates el reinicio como gestión de caché.

7) Reinicios de nodos Kubernetes causan reprogramaciones en cadena

Síntoma: Reiniciar un nodo provoca un pico de latencia en todo el clúster.

Causa raíz: Presupuestos de disrupción ausentes, capacidad de reserva demasiado baja, autoscaling agresivo o cargas stateful pesadas reprogramadas a la vez.

Solución: Drena correctamente, aplica PDBs, mantén headroom y limita la tasa de rollouts. Reiniciar está bien; estampidas no.

8) Tratar timeouts de red como bugs de aplicación

Síntoma: Timeouts aleatorios entre servicios; reiniciar algunos nodos “ayuda”.

Causa raíz: Problemas con el resolvedor DNS, pérdidas de paquetes, agotamiento de conntrack o mismatch de MTU.

Solución: Revisa el resolvedor, pérdidas de interfaz y conntrack; arregla la condición de red. Los reinicios pueden resetear conntrack y parecer útiles, por eso la gente los sigue haciendo.

Listas de verificación / plan paso a paso

Checklist A: Antes de pulsar reset (producción)

  1. Confirma el alcance: un nodo vs flota vs dependencia.
  2. Captura el bundle forense mínimo: uptime, instantánea de top, iostat, df -h, cola de dmesg, fallos de servicios.
  3. Revisa salud de almacenamiento: errores en dmesg, estado pool/RAID, saturación de dispositivo.
  4. Revisa lo básico de red: pérdidas de interfaz, resolución DNS, sanidad de tablas de rutas si es relevante.
  5. Elige la mitigación más pequeña: reiniciar servicio → reiniciar nodo → power-cycle.
  6. Planifica impacto en clientes: drenar tráfico, cordonar el nodo, hacer failover si es posible.
  7. Comunica: “Mitigación: reinicio; objetivo: restaurar. Evidencia capturada. Siguiente paso: causa raíz.”

Checklist B: Reinicio controlado en un clúster (la forma segura)

  1. Cordona/drena el nodo (o retíralo del balanceador).
  2. Confirma que las cargas stateful son seguras (replicación sana, no hay reconstrucción en curso).
  3. Reinicia una vez. Si no ayudó, no lo hagas de nuevo sin sentido.
  4. Al volver, valida health checks y métricas clave antes de reintroducir tráfico.
  5. Vigila efectos de calentamiento de caché y estampidas de reconexión.

Checklist C: Después del reinicio (convierte en aprendizaje)

  1. Compara métricas clave: latencia, tasa de error, iowait, pérdidas, uso de memoria pre/post.
  2. Extrae una hipótesis: “El reinicio ayudó porque el reset del driver limpió X” es un punto de partida, no un final.
  3. Haz un cambio de hardening: alerta, límite, prueba o actualización. Uno por incidente basta para acumular mejoras.
  4. Actualiza el runbook: incluye los comandos exactos y la regla de decisión que fue correcta.

Preguntas frecuentes

1) ¿Reiniciar un servidor en producción siempre es malo?

No. Reinicios no controlados son malos. Un reinicio controlado—después de drenar tráfico y capturar evidencia—es una mitigación legítima, especialmente para estado del kernel/driver.

2) ¿Por qué reiniciar “arregla” problemas que no podemos reproducir?

Porque muchas fallas son estado emergente: fugas, fragmentación, acumulación de colas o dispositivos atascados. El reinicio restablece ese estado. No lo explica.

3) ¿Debo reiniciar el servicio o el nodo?

Reinicia el servicio si el nodo parece sano (no hay tormenta de iowait, no hay pila de procesos en estado D, no hay errores del kernel). Reinicia el nodo cuando sospeches problemas del kernel/driver/ruta de I/O.

4) ¿Cuál es la cosa más importante antes de reiniciar?

Capturar evidencia del kernel y recursos: cola de dmesg, iostat, top, df -h y logs relevantes del servicio. Si reinicias sin esto, eliges la ignorancia.

5) ¿Cómo sé si el cuello de botella es disco I/O?

Busca alto iowait en top, alto await y %util en iostat -x y procesos en estado D esperando I/O.

6) ¿Puede un reinicio empeorar un incidente de almacenamiento?

Sí. Los reinicios pueden desencadenar reconstrucciones/resilverings, amplificación por caché fría, replays de journal y tormentas de reconexión a almacenamiento compartido. Estabiliza primero y luego reinicia con intención.

7) En Kubernetes, ¿es aceptable reiniciar un nodo?

Sí, si cordonas y drenas correctamente, respetas pod disruption budgets y mantienes headroom en el clúster. Trata el reinicio de nodo como una actualización rolling, no como una sorpresa.

8) ¿Por qué vemos “funciona tras reiniciar” con problemas de red?

Porque el reinicio resetea tablas conntrack, limpia estados transitorios del driver y fuerza resolución DNS y sesiones TCP nuevas. También por eso enmascara el defecto real de red.

9) ¿Cómo reducimos la dependencia de reinicios?

Añade límites (memoria, disco, profundidad de colas), mejora la observabilidad (desglose de latencia por capa) y haz que los modos de fallo conocidos sean self-healing (health checks que reinician el componente correcto, no todo el nodo).

10) ¿Deberíamos automatizar reinicios con watchdogs?

A veces. Para appliances de propósito único y nodos edge, los watchdogs pueden ser correctos. Para sistemas complejos y stateful, un reinicio automático sin captura de evidencia y límites de tasa es una excelente forma de borrar las únicas pistas que tenías.

Conclusión: siguientes pasos para reducir “reiniciar como estilo de vida”

La era del botón de reinicio no va de vergüenza. Va de claridad. Los reinicios son honestos porque admiten que un sistema ha acumulado estado sobre el que no puedes razonar bajo presión. Son deshonestos porque borran el rastro salvo que lo preserves deliberadamente.

Si gestionas sistemas en producción, haz tres cosas esta semana:

  1. Estandariza el bundle pre-reinicio (cinco comandos, un archivo, siempre adjunto al incidente).
  2. Adopta la regla del martillo más pequeño (reinicia servicio antes que nodo; reinicia nodo antes que power-cycle; haz failover antes de reconstruir).
  3. Convierte cada reinicio exitoso en una hipótesis que puedas probar: almacenamiento, red, memoria, kernel o dependencia. Luego refuerza un punto débil.

Reiniciar no es fracasar. Reiniciar sin aprender sí lo es.

← Anterior
Debian 13: Corregir “Demasiadas redirecciones” en Nginx eliminando el bucle canónico/HTTPS
Siguiente →
Certificados VPN: hazlo bien sin el sufrimiento permanente de los autofirmados

Deja un comentario