Proxmox Corosync “link down”: por qué el clúster fluctúa y cómo estabilizarlo

¿Te fue útil?

La interfaz de Proxmox está en verde. Luego pasa a rojo. Luego tus nodos deciden que vuelven a ser individuales, como un sistema distribuido pasando por una ruptura.
Los registros de Corosync muestran link down, el quórum desaparece, HA se pone nervioso y de repente tu ventana de mantenimiento “simple” tiene público en vivo.

“Link down” no es un capricho místico de Corosync. Es un síntoma: pérdida de paquetes, jitter, desajuste de MTU, comportamientos extraños de offload de la NIC, mal diseño de anillos,
desincronización horaria, hosts saturados o un clúster de dos nodos que finge que las reglas de quórum no se aplican. Volvamos a hacerlo aburrido.

En Proxmox VE, Corosync es la capa de comunicación del clúster. Es la parte que decide si los nodos pueden escucharse de forma fiable y si
el clúster sigue formando un único grupo coherente. Cuando Corosync indica link down, no está hablando necesariamente de una caída del portador Ethernet
(aunque puede ser). Está hablando de su propia ruta de transporte—su anillo—siendo inservible porque los mensajes no llegan dentro de la ventana temporal esperada,
o porque detecta una partición.

Corosync tiene opiniones claras. Prefiere declarar un enlace caído a aceptar de forma silenciosa una comunicación no fiable. Es un buen instinto: las comunicaciones
poco fiables del clúster provocan el tipo de caos “la mitad de los nodos piensa X, la otra mitad piensa Y” que convierte almacenamiento y HA en máquinas de responsabilidad.

Traducción práctica: link down de Corosync significa que el plano de control del clúster está experimentando pérdida de paquetes, jitter excesivo, reordenamiento
o retrasos de planificación largos
—y que está excediendo la tolerancia de Corosync tal como está definida por los timeouts de token y la lógica de retransmisión. Arregla la red y
el comportamiento del host; no te limites a “aumentar timeouts hasta que deje de quejarse” a menos que hayas medido las compensaciones.

Una verdad seca: si tu anillo de Corosync es inestable, todo lo que hay encima se vuelve mentiroso. La interfaz miente. HA miente. “Funcionó ayer” también miente.

Hechos y contexto: por qué Corosync actúa así

  • Corosync evolucionó desde el proyecto OpenAIS (mediados de los 2000) para proporcionar mensajería de grupo fiable para clústeres; no empezó como una función de Proxmox.
  • El protocolo Totem (el núcleo de mensajería de Corosync) está diseñado en torno a membresía y mensajería ordenada; es conservador respecto a particiones.
  • La membresía basada en token es un enfoque clásico: si no puedes pasar el “token” (conceptualmente) a tiempo, quedas fuera. Por eso los timeouts importan.
  • El quórum en dos nodos es históricamente incómodo en la mayoría de pilas de clustering; existen dispositivos de quórum externos porque “2” es un número político, no tolerante a fallos.
  • Antes se recomendaba multicast para algunas pilas de clústeres, pero los datacenters modernos a menudo lo deshabilitan o lo tratan de forma inconsistente, empujando hacia unicast.
  • La redundancia de anillos no es nueva: los clústeres HA llevan tiempo usando redes duales (pública + heartbeat privada) porque “un switch” no es una estrategia.
  • Los modos de bonding en Linux llevan sorpresas bajo pérdida de paquetes o ruteo asimétrico; el tráfico de clúster es donde “casi bien” se convierte en “no bien”.
  • Los errores por desajuste de MTU son antiguos y siguen prosperando: los jumbo frames que caen silenciosamente o fragmentan pueden crear justamente la pérdida intermitente que mata un anillo token.

Por qué los clústeres fluctúan: los modos de fallo que importan

1) Pérdida de paquetes (los microbursts importan)

Corosync no necesita una “gran pérdida” para causarte problemas. Algunos paquetes perdidos en una ventana estrecha pueden desencadenar retransmisiones y retrasos de token, llevando a una decisión de enlace caído.
Los microbursts—picos cortos de congestión—son famosos por ser invisibles para monitorización simplista. Un switch puede estar “bien” de media mientras pierde el único paquete que tu clúster necesitaba.

2) Jitter y latencia de planificación (el host también es la red)

Incluso si la ruta de red es perfecta, un host cargado puede comportarse como una red con pérdidas si los hilos de Corosync no pueden ejecutarse. Sobrecommit de CPU, tormentas de interrupciones,
bloqueos de almacenamiento y fallos a nivel de kernel pueden retrasar el procesamiento. Corosync mide el tiempo en tiempo real; tu planificador mide el tiempo en “cuando me toque”.

3) Desajuste de MTU y rarezas de fragmentación

Los clústeres tienden a vivir en redes “especiales”: VLANs, jumbo frames, bonds, bridges, offloads de NIC, reglas de firewall y a veces redes overlay.
El desajuste de MTU es el clásico: los pings funcionan (pequeños), pero paquetes mayores fragmentan o se pierden, y Corosync obtiene timeouts intermitentes.

4) Errores de diseño de anillos: puntos únicos de fallo disfrazados de “redundancia”

Si ring0 y ring1 comparten el mismo switch, la misma NIC, el mismo slave de bond o la misma ruta upstream, no tienes redundancia. Tienes dos nombres para un solo problema.
Corosync flapping felizmente ambos anillos si tus “dos anillos” son en realidad un único dominio de fallo.

5) Unicast/multicast mal configurado o “ayuda” del firewall

Corosync necesita entrega consistente. Un multicast medio configurado, IGMP snooping actuando mal o un firewall que elimina fragmentos UDP pueden volver inestable la membresía.
Corosync usa UDP; UDP más “política de firewall empresarial” es una relación que requiere asesoramiento.

6) Deriva de sincronización horaria y saltos de reloj

Los timeouts de token asumen relojes sensatos. NTP/chrony que rebasa el tiempo hacia atrás, o hosts con fuentes de tiempo muy distintas, puede amplificar el jitter y provocar sospechas falsas.
Corosync no depende estrictamente de relojes sincronizados como algunas bases de datos, pero comportamientos de tiempo erráticos empeoran diagnósticos y timeouts.

7) Casos límite de quórum (especialmente clústeres de dos nodos)

En el momento en que un nodo no puede ver al otro, hay una decisión: ¿quién es “el clúster”? En dos nodos, no hay mayoría sin ayuda.
Proxmox ofrece qdevice/qnetd para evitar el clásico baile de split-brain. Ignora eso y los flaps de enlace se convierten en eventos de “clúster caído”.

Broma #1: Un clúster de dos nodos sin qdevice es como una llamada de conferencia con solo dos personas—cuando se queda en silencio, ambos asumen que el otro colgó.

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

El objetivo es encontrar el cuello de botella rápidamente: ¿es la ruta de red, la planificación del host o el diseño de quórum? No empieces editando timeouts.
Empieza por demostrar dónde están ocurriendo la pérdida o el retraso.

Primero: confirma que es inestabilidad de membresía de Corosync, no “rareza de la UI”

  • Revisa el estado de Corosync y del clúster: cambios de membresía, estado de anillos, votos esperados.
  • Revisa los registros alrededor del flap: ¿qué nodo declaró primero el link down?

Segundo: valida la ruta de transporte (pérdida, MTU, firewall, simetría de ruteo)

  • Realiza ping dirigidos con DF y cargas útiles mayores sobre las interfaces de Corosync.
  • Captura un tcpdump corto durante una ventana de flap; busca huecos e ICMP frag-needed.
  • Revisa contadores del switch (aunque “el equipo de red dice que está bien”).

Tercero: comprueba el host por bloqueos (CPU, interrupciones, softnet drops, pausas de almacenamiento)

  • Busca picos de ksoftirqd, drops de RX, desbordes de buffers de ring.
  • Comprueba si ZFS scrubs, backups o replicación saturan IO/CPU durante los flaps.
  • Verifica que la sincronización horaria sea estable (sin saltos grandes, sin “pánico de slew de NTP”).

Cuarto: verifica la estrategia de quórum

  • ¿Dos nodos? Consigue un qdevice. ¿Tres nodos? Asegura que los votos esperados coinciden con la realidad.
  • Confirma que no exista un voto “muerto” oculto en la configuración.

Tareas prácticas: comandos, salida esperada y decisiones

Estas son las comprobaciones que ejecuto realmente cuando un clúster empieza a flappear. Cada una incluye una decisión: qué hacer según lo que veas.

Task 1: Confirma membresía del clúster y quórum

cr0x@server:~$ pvecm status
Cluster information
-------------------
Name:             prod-cluster
Config Version:   42
Transport:        knet
Secure auth:      on

Quorum information
------------------
Date:             Thu Dec 25 10:12:03 2025
Quorum provider:  corosync_votequorum
Nodes:            3
Node ID:          0x00000001
Ring ID:          1.3a
Quorate:          Yes

Votequorum information
----------------------
Expected votes:   3
Highest expected: 3
Total votes:      3
Quorum:           2
Flags:            Quorate

Qué significa: Si Quorate: No o Total votes cae repentinamente, no estás ante un “pequeño fallo de comunicaciones”—estás ante un evento de partición.

Decisión: Si el quórum se pierde de forma intermitente, prioriza las comprobaciones de estabilidad del transporte (Tareas 4–10) y el diseño de quórum (Tarea 12). No ajustes HA primero.

Task 2: Comprueba estado del anillo de Corosync y estado por enlace

cr0x@server:~$ corosync-cfgtool -s
Printing ring status.
Local node ID 1
RING ID 0
        id      = 192.168.50.11
        status  = ring 0 active with no faults
RING ID 1
        id      = 192.168.51.11
        status  = ring 1 active with no faults

Qué significa: Si ves faulty o solo un anillo activo, has perdido redundancia o la ruta es inestable.

Decisión: Si ring1 está faulty, revisa cableado/VLAN/MTU en ring1 específicamente. No asumas “ring0 está bien así que estamos a salvo”—los failover flaps aún pueden desestabilizar la membresía.

Task 3: Extrae el fragmento relevante de registros de Corosync alrededor del flap

cr0x@server:~$ journalctl -u corosync --since "10 minutes ago" --no-pager
Dec 25 10:05:41 pve1 corosync[1642]:   [KNET  ] link: host: 2 link: 0 is down
Dec 25 10:05:41 pve1 corosync[1642]:   [TOTEM ] Token has not been received in 1000 ms
Dec 25 10:05:41 pve1 corosync[1642]:   [TOTEM ] A processor failed, forming new configuration.
Dec 25 10:05:42 pve1 corosync[1642]:   [QUORUM] Members[2]: 1 3
Dec 25 10:05:47 pve1 corosync[1642]:   [KNET  ] link: host: 2 link: 0 is up

Qué significa: Las líneas “Token has not been received” y “forming new configuration” son el churn de membresía. La línea KNET identifica qué par/enlace cayó.

Decisión: Identifica qué nodo reporta la caída primero y qué peer está implicado. Luego prueba exactamente esa ruta de red (Tareas 4–8).

Task 4: Verifica que Corosync usa las interfaces que crees

cr0x@server:~$ grep -E "ring0_addr|ring1_addr|transport|link_mode" /etc/pve/corosync.conf
        transport: knet
        link_mode: passive
        ring0_addr: 192.168.50.11
        ring1_addr: 192.168.51.11

Qué significa: Esto confirma direccionamiento y transporte. Subredes equivocadas o definiciones de anillo faltantes son comunes tras “cambios rápidos”.

Decisión: Si las direcciones no coinciden con la red dedicada prevista, corrígelo primero. Corosync en una LAN compartida y ocupada es pedir jitter.

Task 5: Comprueba MTU de extremo a extremo con ping DF (pequeño y grande)

cr0x@server:~$ ping -c 3 -M do -s 8972 192.168.50.12
PING 192.168.50.12 (192.168.50.12) 8972(9000) bytes of data.
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500
ping: local error: message too long, mtu=1500

--- 192.168.50.12 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2046ms

Qué significa: Tu ruta de MTU es 1500 (o algo en el camino lo es), así que las expectativas de jumbo son erróneas.

Decisión: O configura jumbo de forma consistente en NIC/switch/VLAN/bridge/bond, o estandariza en 1500 en todos lados para Corosync. MTU mixto es combustible para flaps.

Task 6: Confirma MTU en las interfaces Linux reales usadas (incluyendo bridge/bond)

cr0x@server:~$ ip -d link show vmbr1
4: vmbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
    bridge forward_delay 1500 hello_time 200 max_age 2000 stp_state 0 priority 32768 vlan_filtering 1

Qué significa: Si vmbr1 está a 9000 pero el bond o la NIC esclava está a 1500, sigues perdiendo. La MTU debe coincidir en toda la cadena.

Decisión: Revisa MTU en bondX y las NIC subyacentes. Corrige inconsistencias antes de tocar los timers de Corosync.

Task 7: Mide pérdida y latencia con fping (red de corosync)

cr0x@server:~$ fping -c 200 -p 20 192.168.50.12 192.168.50.13
192.168.50.12 : xmt/rcv/%loss = 200/199/0%, min/avg/max = 0.20/0.35/4.10
192.168.50.13 : xmt/rcv/%loss = 200/192/4%, min/avg/max = 0.21/0.60/18.70

Qué significa: 4% de pérdida con picos de 18 ms en una red de clúster no es “aceptable”. Es generador de link-down.

Decisión: Si ves cualquier pérdida, para y busca la causa física/lógica (drops en switch, cable/óptica defectuosa, mismatch de duplex, uplink congestionado).

Task 8: Revisa contadores de errores y drops en Linux

cr0x@server:~$ ip -s link show dev eno2
3: eno2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    RX:  bytes packets errors dropped  missed   mcast
    987654321  1234567      0   4821       0  112233
    TX:  bytes packets errors dropped carrier collsns
    876543210  1122334      0      0       0       0

Qué significa: RX dropped indica que el host descarta paquetes (a menudo buffer de ring, driver o presión de CPU/interrupciones).

Decisión: Si los drops aumentan durante los flaps, investiga interrupciones/softnet (Tarea 9), tamaños de colas de NIC y carga del host (Tarea 10).

Task 9: Comprueba drops en softnet backlog (el kernel no da abasto)

cr0x@server:~$ awk '{print NR-1, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16}' /proc/net/softnet_stat | head
0 00000000 00000000 00000018 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
1 00000000 00000000 000001a2 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Qué significa: La tercera columna (en hex) son paquetes descartados por backlog de softnet. Valores distintos de cero que crecen bajo carga son una pista clarísima.

Decisión: Si estos contadores suben durante los flaps, reduce la presión de interrupciones (IRQ affinity), ajusta las colas de la NIC y evita saturar el host con tráfico ruidoso en la NIC de Corosync.

Task 10: Correlaciona flaps con presión de CPU y bloqueos de IO

cr0x@server:~$ vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 102400  12345 678901    0    0    20    40  900 1500 12  4 83  1  0
 8  2      0  51200  12000 650000    0    0  8000 12000 4000 9000 35 20 25 20  0
 7  3      0  49000  11800 640000    0    0  9000 14000 4200 9200 33 22 20 25  0

Qué significa: Alto r (cola de ejecución), wa (espera IO) no trivial y muchos cambios de contexto pueden alinearse con retrasos de Corosync.

Decisión: Si los flaps se correlacionan con backups, scrubs o replicación, prográmalos o limita su velocidad, y aísla el tráfico de Corosync (NIC/VLAN dedicada, QoS).

Task 11: Confirma que la sincronización horaria es estable (ejemplo con chrony)

cr0x@server:~$ chronyc tracking
Reference ID    : 0A0A0A01 (ntp1)
Stratum         : 3
Ref time (UTC)  : Thu Dec 25 10:10:58 2025
System time     : 0.000231456 seconds slow of NTP time
Last offset     : -0.000102334 seconds
RMS offset      : 0.000356221 seconds
Frequency       : 12.345 ppm fast
Residual freq   : -0.012 ppm
Skew            : 0.045 ppm
Root delay      : 0.001234 seconds
Root dispersion : 0.002345 seconds
Update interval : 64.0 seconds
Leap status     : Normal

Qué significa: Saludable: offsets pequeños, estrato estable, sin problemas de leap. Si ves offsets grandes o pasos frecuentes, el tiempo es sospechoso.

Decisión: Arregla la estabilidad de NTP/chrony antes de afinar Corosync. El caos horario vuelve la diagnosis imposible y los timeouts de token impredecibles.

Task 12: Valida votos esperados y (si hace falta) presencia de qdevice

cr0x@server:~$ pvecm qdevice status
QDevice information
-------------------
Status:           OK
QNetd host:       10.10.10.50
QDevice votes:    1
TLS:              enabled
Algorithm:        ffsplit

Qué significa: En clústeres de dos nodos, qdevice marca la diferencia entre “breve parpadeo de enlace” y “todos entran en pánico”.

Decisión: Si tienes dos nodos y no hay qdevice, programa añadir uno. Si qdevice existe pero su estado no es OK, arréglalo—no confíes en la esperanza.

Task 13: Revisa estadísticas runtime de Corosync (knet) por errores de enlace

cr0x@server:~$ corosync-cmapctl | grep -E "knet.*(rx|tx|errors|retries|latency)" | head -n 12
runtime.totem.knet.pmtud_interval = 60
runtime.totem.knet.link.0.packets_rx = 2849921
runtime.totem.knet.link.0.packets_tx = 2790012
runtime.totem.knet.link.0.errors = 12
runtime.totem.knet.link.0.retries = 834
runtime.totem.knet.link.0.latency = 420

Qué significa: Errores y retries crecientes suelen alinearse con pérdida física o problemas de MTU/PMTUD.

Decisión: Si los retries aumentan durante los flaps, trátalo como un defecto de red hasta probar lo contrario. “Pero vMotion funciona” no exime.

Task 14: Captura tráfico de Corosync brevemente para detectar fragmentación/ICMP

cr0x@server:~$ tcpdump -i vmbr1 -nn -c 50 udp port 5405
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on vmbr1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
10:12:11.120001 IP 192.168.50.11.5405 > 192.168.50.12.5405: UDP, length 1240
10:12:11.120220 IP 192.168.50.12.5405 > 192.168.50.11.5405: UDP, length 1240
10:12:11.121003 IP 192.168.50.11 > 192.168.50.12: ICMP 192.168.50.11 udp port 5405 unreachable, length 1276

Qué significa: ICMP unreachable es un gran signo: firewall, dirección bind incorrecta o un nodo que no está escuchando en esa interfaz.

Decisión: Si ves unreachable/frag-needed, corrige ruteo/firewall/MTU. Si ves silencio durante los flaps, sospecha drops más cerca del inicio del camino.

Task 15: Verifica estado del firewall para las interfaces de Corosync

cr0x@server:~$ pve-firewall status
Status: enabled/running

Qué significa: Un firewall habilitado está bien, pero significa que debes confirmar reglas que permitan Corosync en la interfaz/VLAN correcta.

Decisión: Si los flaps comenzaron después de cambios en el firewall, audita reglas del datacenter y del host y confirma que UDP 5405/5404 (según configuración) está permitido entre nodos.

Tres microhistorias corporativas de la vida real (anonimizadas)

Microhistoria 1: El incidente causado por una suposición errónea

Una empresa mediana migró de la mentalidad “un solo host potente” a un clúster Proxmox de tres nodos. Hicieron lo sensato—dedicaron una VLAN para Corosync—y lo insensato—pusieron esa VLAN en los mismos top-of-rack switches que una red de almacenamiento muy ocupada sin pensar en patrones de congestión.

La suposición errónea fue simple: “El tráfico de clúster es pequeño, así que puede compartir cualquier cosa.” La mayor parte del tiempo funcionó. Los gráficos mostraban bajo ancho de banda medio.
Todos asintieron y la solicitud de cambio se cerró emocionalmente.

Entonces llegaron las copias de seguridad semanales y un trabajo interno de exportación de datos que saturó la VLAN de almacenamiento. Los buffers del switch se llenaron, se formaron microbursts y la VLAN de Corosync
sufrió daño colateral. Los nodos perdían membresía por unos segundos—lo justo para activar la lógica de fencing de HA y alterar algunas VMs.

La solución no fue ajustar timeouts de Corosync. Movieron Corosync a un par de switches físicamente separados y NICs dedicadas, y dejaron de enrutar tráfico de backup por los mismos uplinks que las comunicaciones del clúster. La teoría de “el tráfico pequeño puede compartir todo” murió en silencio, como debía ser.

Microhistoria 2: La optimización que salió mal

Otra organización decidió “optimizar latencia” habilitando jumbo frames en todas partes. El equipo de red puso MTU 9000 en los switches. El equipo de virtualización puso MTU 9000 en los bridges Linux. Celebraron pronto, que es una forma fiable de invocar la realidad.

El problema: un dispositivo intermedio—un firewall antiguo que hacía ruteo VLAN para una subred de gestión—imponía silenciosamente MTU 1500. PMTUD fue inconsistente debido a reglas de filtrado, así que los paquetes grandes se perdían sin ICMP útil. Los pings funcionaban. SSH funcionaba. Todo funcionaba excepto lo que necesitaba entrega UDP consistente bajo carga: Corosync.

El clúster empezó a “flappear” aleatoriamente varias veces al día. El equipo intentó aumentar los timeouts de token. Los flaps se hicieron menos frecuentes, pero la recuperación fue más lenta y las decisiones de failover se volvieron torpes. Cambiaron corrección por entumecimiento.

La solución fue aburrida y quirúrgica: imponer MTU consistente de extremo a extremo (o estandarizar en 1500 para Corosync) y dejar de bloquear ICMP relacionado con PMTUD en enlaces internos. El clúster se silenció. La “optimización” había sido un generador distribuido de desajustes de MTU.

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

Un equipo de servicios financieros ejecutaba Proxmox con Ceph y trataba las comunicaciones del clúster como tráfico de control de producción: NICs dedicadas, switches dedicados y una lista de verificación escrita para cualquier cambio de red.
También tenían la costumbre poco elegante de capturar un tcpdump corto antes y después de cada cambio que tocara la red del clúster.

Una tarde, los flaps empezaron inmediatamente tras una actualización rutinaria de firmware del switch. El equipo de red insistió en que no había cambiado la configuración. Casi siempre es verdad—hasta que no lo es.
El equipo de virtualización presentó la evidencia de su práctica aburrida: las capturas antes/después mostraron ráfagas periódicas de pérdida UDP cada 30 segundos.

Correlacionaron esas ráfagas con un cambio en el comportamiento de IGMP snooping del switch (la actualización tocó los valores por defecto). Corosync estaba ejecutándose en un modo que dependía de supuestos sobre el manejo del multicast. Con la evidencia, el equipo de red ajustó la configuración de snooping para esa VLAN y validó con contadores.

El clúster se estabilizó en minutos. El hábito del tcpdump no les hizo populares en las reuniones, pero les hizo tener razón cuando importaba.

Estabilizar por diseño: red, anillos, quórum y tiempo

Construye una red de clúster como si la sintieras

Corosync es sensible a latencia, pérdida y jitter. Trata la red de Corosync como tráfico de plano de control. Eso suele significar:
VLAN dedicada como mínimo, NICs físicas dedicadas idealmente y un par de switches dedicados si te lo puedes permitir.

Si debes compartir, aplica QoS y evita vecinos ruidosos conocidos (backups, replicación, reconstrucciones de almacenamiento). No apuestes la membresía del clúster a la idea de que tu top-of-rack bufferizará todo para siempre.

Usa dos anillos, pero hazlos diferentes dominios de fallo

Dos anillos son buenos. Dos anillos que comparten un único switch no lo son. Si ring0 y ring1 terminan en la misma pila de switches, el mismo par de bonded,
o el mismo router upstream, has construido “teatro de redundancia.”

Ideal: ring0 en una NIC y par de switches, ring1 en otra NIC y otro par de switches. Aceptable: ring1 comparte par de switches pero usa NICs diferentes y cableado distinto,
si has validado que la pila de switches en sí es altamente disponible y no está saturada.

Sé conservador con la MTU

Los jumbo frames no son malos. Los jumbo mixtos sí. Si no puedes demostrar consistencia de MTU a través de NICs, bonds, bridges, puertos de switch, trunks VLAN y cualquier dispositivo L3 intermedio,
quédate con 1500 para Corosync. Dormirás mejor.

No enmascares problemas afinando timeouts

Corosync tiene perillas: timeouts de token, retransmisiones y comportamiento de consenso. Existen porque hay entornos diferentes. Pero afinar no es un sustituto de arreglar pérdida.
Timeouts más largos pueden reducir sensibilidad a jitter transitorio, pero también aumentan el tiempo de detección de fallos. Eso significa fencing más lento, failover más lento y periodos más largos donde el clúster discrepa.

Aquí está tu compensación: timeouts cortos significan detección de fallo rápida pero más sensibilidad; timeouts largos significan menos falsos positivos pero reacción más lenta.
Ajusta solo tras medir latencia y pérdida base y después de haber arreglado defectos de transporte obvios.

Quórum: deja de fingir que dos nodos son tres

Si ejecutas dos nodos, añade un qdevice (qnetd) en un tercer host independiente. Puede ser pequeño. Puede ser una VM en un dominio de fallo distinto. No debe estar en el mismo host físico que intentas arbitrar. Sí, hay gente que lo hace. No, eso no cuenta.

Si ejecutas tres o más nodos, verifica que los votos esperados coincidan con la realidad y elimina nodos obsoletos de la configuración. Los votos zombis son cómo te quedas sin quórum cuando todo “parece arriba”.

Sincronización horaria: aburrida, fundamental e innegociable

Chrony con upstreams estables es la respuesta habitual. Evita grandes saltos de tiempo en nodos en ejecución a menos que entiendas los efectos secundarios. Si tus registros muestran saltos de tiempo,
tus diagnósticos se convierten en ficción. Arregla el tiempo primero; todo lo demás será más fácil.

Una cita sobre fiabilidad para tener en una nota adhesiva: Idea parafraseada de John Allspaw: “La fiabilidad viene de permitir aprendizaje seguro y rápido, no de culpar a las personas cuando los sistemas nos sorprenden.”

Broma #2: Aumentar los timeouts de Corosync para dejar de recibir flaps es como subir el volumen de la radio para arreglar la luz de avería del motor—cambia el ambiente, no el problema.

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

1) Síntoma: link down aleatorio durante backups

Causa raíz: el tráfico de backup congestiona switch/uplink compartido; microbursts eliminan UDP de Corosync.

Solución: aislar Corosync en NIC/VLAN/switch dedicado; aplicar QoS; limitar concurrencia de backups; confirmar con pruebas fping de pérdida.

2) Síntoma: flaps solo en un anillo (ring1 sigue faulty)

Causa raíz: VLAN de ring1 mal etiquetada, cable/óptica defectuosa, desajuste de MTU o IP/subnet incorrecta.

Solución: valida /etc/pve/corosync.conf, ejecuta pings DF en ring1, revisa contadores con ip -s link, reemplaza componentes físicos sospechosos.

3) Síntoma: tras habilitar jumbo frames, el clúster se vuelve inestable

Causa raíz: despliegue parcial de MTU; PMTUD bloqueado; fragmentación/drop afectando UDP.

Solución: imponer consistencia de MTU end-to-end o revertir a 1500 para Corosync; permitir tipos ICMP esenciales internamente; validar con pings DF.

4) Síntoma: “Quórum perdido” en clúster de dos nodos durante breves flaps

Causa raíz: no hay desempate externo; el mecanismo clásico de prevención de split-brain actúa.

Solución: desplegar qdevice/qnetd; asegúrate de que esté en un dominio de fallo independiente; verifica con pvecm qdevice status.

5) Síntoma: Corosync parece bien, pero la membresía churnea bajo carga de CPU

Causa raíz: latencia de planificación; backlog de softirq; procesamiento de paquetes retrasado.

Solución: reduce la contención (pin interrupts, ajustar RPS/XPS, disminuir tráfico ruidoso), evita saturar la CPU del host durante operaciones críticas.

6) Síntoma: un nodo frecuentemente “inicia el flap”

Causa raíz: ese host tiene problemas de driver de NIC, drops RX, firmware malo o una VM vecina que satura el bridge.

Solución: compara ip -s link, softnet_stat y registros entre nodos; actualiza firmware/driver de NIC; aísla la NIC del clúster de bridges de invitados si es posible.

7) Síntoma: flaps después de cambios en el firewall

Causa raíz: puertos UDP bloqueados, fragmentos eliminados o reglas asimétricas entre nodos.

Solución: permite explícitamente Corosync UDP entre direcciones de anillo; confirma con tcpdump y ss -u -lpn (añade esto a tu runbook si lo necesitas).

8) Síntoma: flaps coinciden con mantenimiento de switch o eventos STP

Causa raíz: reconvergencia de spanning tree, flaps de puerto, renegociación LACP causando pérdida en ráfagas.

Solución: usa portfast/edge donde corresponda, valida hashing de LACP, evita reconvergencia L2 en la VLAN de Corosync y considera anillos duales sobre pares de switches independientes.

Listas de verificación / plan paso a paso

Plan paso a paso para estabilizar (haz esto en orden)

  1. Confirma que el síntoma es real: captura pvecm status, corosync-cfgtool -s y los últimos 10 minutos de logs de Corosync en todos los nodos. Necesitas marcas temporales y cuál nodo declaró primero.
  2. Congela cambios: deja de “ayudar” ajustando mientras mides. Deshabilita migraciones no esenciales y tareas de mantenimiento pesadas hasta que las comunicaciones sean estables.
  3. Demuestra MTU end-to-end: pings DF con la máxima carga prevista en cada anillo entre cada par de nodos. Corrige desajustes inmediatamente.
  4. Mide pérdida/jitter: ejecuta fping durante unos minutos. Cualquier pérdida es inaceptable para el plano de control.
  5. Inspecciona drops en el host: revisa ip -s link y /proc/net/softnet_stat. Si el host descarta, el switch es inocente (por una vez).
  6. Valida simetría de ruteo: asegúrate de que el tráfico de Corosync se quede en la interfaz prevista y no haga hairpin por routers o firewalls.
  7. Revisa estabilidad horaria: confirma salud de chrony/NTP; asegúrate de que no haya pasos de tiempo durante incidentes.
  8. Arregla diseño de quórum: dos nodos → añade qdevice; tres o más → verifica votos esperados, elimina nodos obsoletos, verifica qdevice si se usa.
  9. Solo entonces considera afinar: si tu entorno tiene jitter inevitable (enlaces de larga distancia, overlays cifrados), ajusta timeouts con cuidado y documenta compensaciones.

Lista operativa para cualquier cambio de red que toque Corosync

  • Registra estado actual de anillos y membresía.
  • Ejecuta pings DF para ambos anillos hacia cada nodo.
  • Ejecuta un burst de fping de 2–5 minutos y archiva resultados.
  • Revisa contadores ip -s link antes/después.
  • Confirma que las reglas de firewall no cambian para las VLANs de anillo.
  • Después del cambio: valida que corosync-cfgtool -s no muestre fallos y que la membresía sea estable al menos 30 minutos.

Preguntas frecuentes

1) ¿“link down” significa que el enlace físico de la NIC realmente se cayó?

No necesariamente. Significa que Corosync considera su enlace de transporte como no saludable. Puede ser pérdida física, pero más a menudo es pérdida/jitter más allá de la tolerancia.
Verifica siempre con ip -s link, contadores del switch y registros.

2) ¿Debería simplemente aumentar el timeout de token?

No como primera medida. Si aumentas timeouts para ocultar pérdida, ralentizas la detección de fallos y puedes empeorar el comportamiento de HA. Arregla la estabilidad del transporte primero y afina con cautela si hay una necesidad medida.

3) ¿Está bien ejecutar Corosync en la red de gestión?

“Está bien” es una decisión de negocio. Si la red de gestión es tranquila, dedicada y estable, vale. Si se comparte con tráfico de usuarios, backups o ruteo impredecible,
estás construyendo un generador de flaps. VLAN dedicada como mínimo es la línea base sensata.

4) ¿Necesito dos anillos?

Si te importa el tiempo de actividad, sí. Pero solo si son dominios de fallo separados. Dos anillos en la misma pila de switches es solo un poco mejor que uno, y a veces peor si añade complejidad sin aislamiento real.

5) ¿Por qué mi clúster de tres nodos aún pierde quórum a veces?

Generalmente porque un nodo se aísla intermitentemente o está sobrecargado, o porque los votos esperados están mal configurados (entrada de nodo obsoleta). Revisa pvecm status y los registros.
Si un nodo “desaparece” repetidamente, diagnostica la ruta de red de ese nodo y la carga del host.

6) ¿Puede el tráfico de Ceph causar flaps de Corosync?

Absolutamente, si comparten NICs/switches/uplinks y Ceph recovery o backfill saturan la ruta. Ceph puede crear patrones de ráfagas y alto ancho de banda sostenido.
Corosync no necesita mucho ancho de banda, pero necesita entrega consistente.

7) ¿Es necesario multicast para Corosync?

Los clústeres Proxmox modernos usan comúnmente knet/comportamiento estilo unicast según la configuración. Multicast puede funcionar, pero con frecuencia se maneja mal en redes empresariales.
Si dependes de multicast, valida el comportamiento de IGMP snooping y confirma que los switches tratan la VLAN correctamente.

8) ¿Cuál es la prueba más rápida de que un desajuste de MTU es el culpable?

Un ping DF con carga grande que falle en un camino y tenga éxito en otro. Si esperas jumbo, prueba cerca de 9000. Si falla con “message too long” o se cae silenciosamente,
has encontrado un problema real, no una teoría.

9) ¿Puede una CPU ocupada realmente hacer que Corosync piense que la red está caída?

Sí. Si el host no puede procesar interrupciones de red o programar Corosync a tiempo, los paquetes se pierden o retrasan. Revisa drops de softnet y correlaciona flaps con presión de CPU/IO.

10) ¿Y si solo tengo dos nodos y no puedo añadir un tercero para qdevice?

Entonces acepta que no tienes un modelo de quórum resiliente. Puedes operar, pero tendrás que elegir entre disponibilidad y seguridad durante particiones.
Si el negocio requiere HA, encuentra un tercer dominio de fallo para qnetd—even una máquina pequeña externa—antes de culpar a Corosync por hacer su trabajo.

Conclusión: siguientes pasos que reducen el ruido del pager

“Corosync link down” no es un rompecabezas de configuración. Es tu clúster diciéndote que el plano de control no puede confiar en la red o en el host bajo condiciones reales.
Trátalo como un defecto de fiabilidad en producción.

Siguientes pasos que realmente mueven la aguja:

  • Demuestra consistencia de MTU en cada ruta de anillo con pings DF y corrige desajustes.
  • Mide la pérdida con fping y elimínala—especialmente los microbursts de uplinks compartidos.
  • Revisa drops a nivel de host (softnet, RX drops) y reduce contención de interrupciones/CPU.
  • Haz los anillos reales: dominios de fallo separados, no solo IPs distintas.
  • Arregla el diseño de quórum: dos nodos obtienen qdevice; tres nodos verifican votos y eliminan zombis.
  • Solo entonces afina los timeouts de Corosync y documenta la compensación en tiempo de detección de fallos.

El estado final estable es aburrido: sin churn de membresía, sin reconfiguraciones sorpresivas y sin debates nocturnos sobre si “probablemente es la red”.
Cuando Corosync se silencia, el resto de tu stack Proxmox empieza a decir la verdad de nuevo.

← Anterior
MariaDB frente a PostgreSQL: valores predeterminados — uno perdona, otro castiga
Siguiente →
Regla del 80% de ZFS: mito, verdad y la verdadera ‘zona peligrosa’

Deja un comentario