CreaRack-SL

Hotfix 2.21.4: la "autocuración" del motor SNMP era un diagnóstico equivocado

Cuándo

24 de agosto de 2026, dentro de una racha de 4 hotfixes seguidos el mismo día sobre el bucle SNMP del Local Agent (2.21.1 → 2.21.2 → 2.21.3 → 2.21.4, en unas 3 horas). Este es el cuarto y último: revierte lo que hizo el hotfix anterior (2.21.3, “el motor SNMP se cura solo”, v1.83.3) pocos minutos después de publicarlo.

Síntomas visibles

Tras publicar 2.21.3 —que recreaba el motor pysnmp al detectar 5 cuelgues SNMP seguidos, asumiendo el motor compartido corrupto—, la verificación en el Agente del CCIB (un site con muchos puntos de acceso) mostró 23 recreaciones del motor en 5 minutos con las peticiones colgándose exactamente igual que antes del parche. Cada recreación además borraba la línea base de ancho de banda (que solo tiene una muestra), dejando ese gráfico en blanco.

Causa raíz

El motor SNMP nunca estuvo corrupto. El CCIB tiene 123 puntos de acceso monitorizados y solo 48 responden — el número de siempre, no una regresión. Los ~75 restantes están apagados también para SNMP (no solo para ping), y con ellos pysnmp no devuelve su propio timeout de 5 segundos: la petición se queda colgada hasta que el Agente la corta por su cuenta (SNMP_HARD_TIMEOUT, entonces en 10 s). Recrear el motor no resolvía nada porque el problema no estaba en el motor, sino en que cada uno de esos 75 hosts cuesta el tope completo — y 2.21.3 malinterpretó ese patrón como “motor corrupto”.

Fix aplicado

Commit b2e4540547ffe4bea0cd96d9dee33eca789b5a17 (PR #433, Agent 2.21.4, SaaS v1.83.4):

  • Se retira por completo la recreación automática del motor SNMP añadida en 2.21.3 (SNMP_HANG_RECREATE_THRESHOLD y la lógica en SentinelScheduler.note_snmp_hang, terminal/agent/sentinel/scheduler.py). Un cuelgue ahora solo cuenta como fallo del target.
  • El cortacircuitos de SNMP (_circuit_breaker) ya existente es quien abre esos targets a los 5 fallos — su trabajo original, sin la capa de “autocuración” de por medio.
  • SNMP_HARD_TIMEOUT baja de 10 a 7 segundos (terminal/agent/config.py) — timeout real de pysnmp (5 s) más margen, para que las primeras vueltas tras actualizar (con los 75 hosts muertos aún sin abrir por el cortacircuitos) no tarden minutos.
  • El test TestHangsNeverRecreateEngine (tests/agent/test_snmp_hard_timeout_and_prune.py) sustituye a TestEngineSelfHeal: verifica que 12 cuelgues seguidos NO disparan recreate_snmp_engine y que engine_recreations se queda a 0.

Lecciones

  • Un síntoma que encaja con un fallo conocido (motor pysnmp compartido que se corrompe, ya visto en el incidente que motivó 2.21.1) puede tener otra causa: aquí era simplemente volumen de hosts muertos, no corrupción.
  • El propio mecanismo de verificación de 2.21.3 (mirar /sentinel/status tras desplegar) fue lo que destapó el error a los pocos minutos — las 23 recreaciones en 5 min sin que los cuelgues bajaran era la prueba de que la hipótesis estaba equivocada.
  • Recrear un recurso compartido como respuesta a un fallo tiene coste (aquí, perder la única muestra de la línea base de ancho de banda), y ese coste hay que pesarlo contra la certeza real del diagnóstico antes de aplicarlo.

Preventivos futuros

  • Queda abierto (documentado en el CHANGELOG como “límite honesto”) por qué pysnmp no honra su propio timeout ante hosts sin respuesta ARP — candidato: retries=0 combinado con una respuesta ICMP unreachable que el dispatcher asíncrono no traduce en error. No se investiga en este hotfix.
  • El indicador de salud a vigilar tras cualquier cambio en esta área: engine_recreations en /sentinel/status debe quedarse a 0, y cycles debe seguir creciendo sin parar.

Véase también

  • [[incident—20260717—monitoring-targets-stuck-down]]
  • [[incident—20260722—flapping-ws-redis-py-8]]
  • [[feature—monitoring—sonda-tcp]]
  • [[feature—monitoring—tcp-probe-suppression-v1634]]
  • [[crearack-tech—agents—dev-terminal]]