QoS de red que realmente funciona (sin adivinar prioridades)

¿Te fue útil?

La QoS suele aparecer tras un incidente. La replicación de almacenamiento se volvió “lenta”, la calidad de las llamadas se transformó en jazz submarino y el panel del CEO se congeló justo cuando alguien lo pidió. Entonces alguien dice las palabras mágicas: “¿Podemos simplemente subir la prioridad?”

Puedes hacerlo. Y también puedes incendiar tu red con un valor DSCP bienintencionado. Esta es la guía para quienes quieren una QoS que puedan demostrar que funciona: cuellos de botella medidos, límites de confianza explícitos y shaping en el único lugar que realmente importa.

QoS no es “prioridad”; es un contrato

La QoS real es un contrato entre flujos en competencia y un cuello de botella. Dice: “Cuando exista contención, estas clases reciben al menos X, como máximo Y, y los flujos sensibles a la latencia no se ahogan detrás de transferencias masivas.” Eso es todo. Todo lo demás es marketing.

La mayoría de fallos de QoS provienen de uno de tres errores:

  • Hiciste shaping en el lugar equivocado. No puedes arreglar la congestión en el núcleo “priorizando” paquetes en el borde si la verdadera cola está en un equipo de un ISP aguas arriba que no controlas.
  • Adivinaste prioridades. “El almacenamiento es importante” no es una definición de clase. Es un sentimiento. Los sentimientos no sobreviven a los microburst.
  • Confiaste marcas que no debías. Si puntos finales no confiables pueden marcar EF, lo harán. A veces por accidente. A veces “porque el proveedor nos lo dijo”.

La buena QoS es aburrida: es medición más control de tasa más equidad. No es un arcoíris de valores DSCP pegados en todo lo que alguna vez perdió un paquete.

Una idea parafraseada de una persona que construyó muchos sistemas fiables: parafraseo: “La esperanza no es una estrategia.” — atribuida a Gordon R. Dickson, repetida a menudo en círculos de ingeniería.

Broma #1: Los planes de QoS basados en “qué es importante” son como los organigramas: hermosos hasta que intentas enrutar el tráfico a través de ellos.

Datos interesantes y breve historia (para que dejes de repetirlo)

Algo de contexto ayuda porque las redes siguen reinventando los mismos errores con nuevos acrónimos.

  1. IntServ/RSVP vino primero y perdió en su mayoría. La visión de los 90 era reservas por flujo en toda la red. No escaló operacionalmente y DiffServ ganó por ser más simple y “suficientemente bueno”.
  2. DiffServ fue diseñado para agregados. DSCP no estaba pensado para que cada aplicación se autodeclarara importante; estaba pensado para que dominios de red clasificaran y trataran tráfico en bloque.
  3. Bufferbloat se reconoció ampliamente a finales de los 2000. Los búferes profundos en equipos de consumo hacían que el rendimiento pareciera excelente en benchmarks mientras la latencia explotaba en uso real.
  4. RED intentó evitar la acumulación de colas temprano. Random Early Detection precede a la popularidad actual de AQM; era poderoso pero delicado, por eso no lo viste en todas partes.
  5. FQ-CoDel fue un punto de inflexión práctico. Combinó equidad (flow queueing) con AQM (CoDel) y no requirió magia de ajuste por enlace.
  6. La reescritura de DSCP es común en producción. Muchos ISP blanquean o remapean DSCP en los bordes de peering; las suposiciones de QoS suelen morir en el primer salto externo.
  7. Ethernet tiene sus propios bits de prioridad. 802.1p PCP puede funcionar dentro de una LAN, pero no es lo mismo que IP DSCP, y los errores de mapeo son un generador clásico de incidentes.
  8. Las colas de “prioridad” pueden asfixiar todo lo demás. La prioridad estricta siempre fue un arma cargada; es segura solo con policing o límites.
  9. QoS en Wi‑Fi no es lo mismo que en cableado. 802.11e/WMM ayuda, pero la contención de aire, la adaptación de velocidad y los reintentos suelen dominar la experiencia del usuario.

Un modelo mental que sobrevive en producción

1) Encuentra el cuello de botella y controla la cola en ese cuello de botella

La QoS solo tiene sentido donde los paquetes se encolan. Normalmente es en el enlace más estrecho (uplink al ISP, circuito WAN, túnel inter-AZ, cabecera VPN, tiempo de aire de Wi‑Fi). Si no controlas la cola allí, estás negociando con la física.

El truco clave es hacer shaping por debajo de la tasa real del enlace. Si tu WAN es 1 Gbps pero el policer del proveedor actúa a 940 Mbps, shapea a 900–920 Mbps para que la cola se forme en tu equipo (donde puedes programar de forma justa) en lugar de en la suya (donde no puedes).

2) Separa “sensibles a latencia” de “bulk”, pero no crees diez clases

La mayoría de organizaciones necesitan de tres a cinco clases, no doce:

  • Interactivo en tiempo real: voz, media de videoconferencia, quizá telemetría tipo gaming. Presupuesto de jitter bajo.
  • Interactivo: SSH, RDP, pequeñas peticiones API, DNS. La baja latencia importa más que el ancho de banda.
  • Predeterminado: la mayoría del tráfico web y de servicios.
  • Bulk: backups, replicación, descargas de artefactos, exportaciones grandes.
  • Scavenger (opcional): cosas que quieres que terminen alguna vez pero nunca a costa de humanos.

Si no puedes articular una clase con una declaración de política (“al menos X, como máximo Y, objetivo de latencia Z”), no la crees. No estás diseñando un mapa de metro. Estás evitando peleas en una sola puerta.

3) Límites de confianza: los endpoints mienten, incluso sin querer

El marcado puede hacerse en endpoints, pero la aplicación debe hacerse en un límite que controles: switch ToR, vSwitch del host, router de borde, gateway WAN. La red debe tratar las marcas de endpoints como pistas a menos que el endpoint esté gestionado y auditado.

4) La equidad no es opcional

Un flujo elefante puede arruinarte el día sin usar mucho ancho de banda en promedio. Los microburst y la acumulación de colas crean picos de latencia que parecen “lentitud aleatoria”. El fair queueing (FQ) aísla flujos para que una transferencia masiva no se quede delante de todos como un camión bloqueando un puente de un solo carril.

5) La QoS es un ciclo de retroalimentación: medir, aplicar, verificar, repetir

Si no observas drops, marcas ECN, retraso en la cola y utilización por clase, estás haciendo una danza interpretativa con los encabezados de paquetes.

Guion de diagnóstico rápido

Esta es la versión “el pager está sonando”. El objetivo es identificar si tienes un problema de capacidad, un problema de encolamiento, un problema de clasificación o un problema de ruta en menos de 15 minutos.

Primero: confirma que el síntoma es real y ubica el alcance

  1. ¿Es latencia, pérdida o rendimiento? Pide una métrica concreta: RTT p95, % de pérdida de paquetes, goodput Mbps. “Lento” no es una métrica.
  2. ¿Es un sitio, una VLAN, una VPN, un ISP, un host? Reduce el radio de impacto rápido.
  3. ¿Está ligado a la carga? Si se correlaciona con ventanas de backup o despliegues, ya tienes una clase sospechosa.

Segundo: encuentra el enlace cuello de botella y comprueba si se está encolando localmente o aguas arriba

  1. Revisa la utilización y errores de la interfaz en el egress sospechoso.
  2. Revisa estadísticas de la disciplina de cola (drops/overlimits) donde haces shaping.
  3. Compara el throughput medido con la tasa contratada. Si estás golpeando un policer del proveedor, verás pérdida sin drops locales a menos que hagas shaping por debajo.

Tercero: valida la clasificación y los límites de confianza

  1. Captura una pequeña muestra y confirma que DSCP/PCP son lo que crees.
  2. Verifica que los dispositivos en el camino preserven las marcas. Un switch “servicial” puede reescribir todo a best-effort.
  3. Confirma que tu scheduler no está dejando morir por inanición al tráfico predeterminado por prioridad estricta.

Cuarto: decide qué palanca tirar

  • Si la cola está aguas arriba: shapea más bajo para que tu cola se forme localmente.
  • Si la cola es local y hay picos de latencia: habilita FQ + AQM (fq_codel/cake) en el egress afectado.
  • Si el tráfico equivocado está en la clase equivocada: arregla la clasificación en el límite (iptables/nftables, política del switch o política del CNI de kube).
  • Si simplemente te falta capacidad: QoS puede triagear, no crear ancho de banda. Compra/actualiza o reduce carga.

Dónde la QoS realmente funciona (y dónde es teatro)

El único lugar donde la programación importa: la cola de egress

La QoS funciona mejor en egress porque ahí el dispositivo controla el tiempo de transmisión. La QoS de ingress trata principalmente de policing (descartar) o remarcar. No puedes “retrasar” paquetes entrantes que ya llegaron; solo puedes descartarlos o confiar en que el upstream reduzca la velocidad.

Mejores lugares para aplicar

  • Router de borde Internet/WAN: tu última oportunidad antes del proveedor. Shapea aquí. Pon la “cola inteligente” aquí.
  • Gateway VPN: el cifrado oculta puertos L4; la clasificación debe ocurrir antes de la encapsulación (o basarse en encabezados internos si está soportado).
  • Hipervisor/host: equidad por VM y por pod evita que un tenant se convierta en la aspiradora de la oficina.
  • Controlador/AP de Wi‑Fi: la equidad de tiempo de aire y el mapeo WMM pueden importar más que la pureza DSCP.

Lugares donde la gente lo intenta y suele fallar

  • Switches núcleo cuando el cuello de botella es un circuito WAN. Estás priorizando hacia un agujero negro. La cola está en otro lado.
  • Middleboxes aleatorios con comportamiento de buffers desconocido. Si no puedes observar el retraso de cola, estás ajustando a ciegas.
  • Botones de “prioridad” en la aplicación sin enforcement en la red. Enhorabuena, pusiste una etiqueta.

Broma #2: Las colas de prioridad estricta son como la pizza gratis en una postmortem: alguien siempre toma de más y el resto de la sala se resentirá.

Clasificación sin adivinar: marca menos, confía menos

Empieza con “predeterminado” y “bulk”, luego gana derecho a “realtime”

La estrategia de QoS más segura no es adivinar qué apps son “importantes”. Es separar el tráfico por comportamiento y potencial de daño:

  • Bulk es identificable: transferencias de larga duración y alto BDP, backups, replicación, descargas de imágenes de contenedores, sincronización de almacenamiento de objetos. Puede retrasarse.
  • Interactivo es pequeño y explosivo: DNS, SSH, llamadas API. Necesita baja demora de cola, no ancho de banda masivo.
  • Realtime es sensible al jitter: flujos de media de voz/video. Necesita baja latencia y pérdida acotada.

Nota lo que falta: “tráfico del CEO”. No hagas eso.

Estrategia DSCP: elige un vocabulario pequeño

En la práctica, un conjunto pequeño de DSCP es robusto entre dispositivos:

  • CS0 para predeterminado (best effort)
  • AF21/AF31 para interactivo (elige uno y apégate)
  • EF para media en tiempo real (úsalo con moderación, policíalo)
  • CS1 para scavenger/bulk-bajo (a veces llamado “menor que best effort”)

Si tu equipo de red ya tiene un plan DSCP, no improvises. Alinea y documenta el límite de confianza: dónde se aceptan marcas, dónde se reescriben y dónde se ignoran.

Patrones de límites de confianza que envejecen bien

  • LAN empresarial: confiar en DSCP de endpoints de voz/video gestionados; remarcar todo lo demás en access/ToR.
  • Centro de datos: marcar en el borde de la carga de trabajo (host/vSwitch) según identidad de cgroup/pod; no confiar en VMs invitadas.
  • Nube híbrida: asumir que DSCP será blanqueado en algún límite; aplicar equidad con shaping + FQ de todos modos.

Policing: el precio de la prioridad estricta

Si tienes una cola de prioridad estricta (por ejemplo, para voz), debes policiarla o limitarla. De lo contrario, un flujo bulk mal marcado puede asfixiar todo. Así nacen los incidentes de “la QoS lo empeoró”.

Shaping y encolamiento: elige el cuchillo correcto

Shaping vs policing

  • Shaping retrasa paquetes para ajustarse a una tasa. Reduce pérdidas, mejora la predictibilidad y hace que TCP se comporte. Necesita buffer y añade algo de latencia, pero la latencia controlada vence a la latencia aleatoria.
  • Policing descarta paquetes que exceden una tasa. Es simple y duro. Úsalo para hacer cumplir límites (especialmente en clases de prioridad), no para “gestionar” tráfico normal.

Disciplinas de cola que importan en Linux

En Linux, tu caja de herramientas por defecto se ve así:

  • fq_codel: excelente por defecto para control de latencia en enlaces típicos; ideal para “hacer que la red vuelva a sentirse normal”.
  • cake: todo en uno excelente para shaping + equidad + manejo diffserv; popular en bordes. No siempre disponible en kernels empresariales, pero cuando está, es un regalo.
  • HTB: shaping con clases (classful) con tasas/techos explícitos; estable operativamente si mantienes saneado el número de clases.
  • TBF: token bucket simple; válido para shaping de una sola tasa pero no para equidad multi-clase.

Qué recomiendo para la mayoría de bordes en producción

  • Si puedes usar cake: shapea a ~90–95% de la tasa real del enlace y usa diffserv4 o diffserv8 según tu modelo de clases.
  • Si no puedes: usa HTB para shaping + garantías por clase, y pon fq_codel (o fq) bajo cada clase para equidad.

Por qué “prioridad” no es el valor predeterminado correcto

La prioridad estricta es apropiada para una clase pequeña y policíada en tiempo real. No es un botón general de “hacer esto más rápido”. Si haces todo de alta prioridad, has inventado best-effort otra vez, con más pasos y peores modos de falla.

Nota específica sobre almacenamiento: la replicación es bulk, pero también riesgo de pager

El tráfico de replicación suele ser bulk y tolerante a latencia, pero puede crear incidentes secundarios cuando satura un enlace y causa timeouts en otros sitios. Trátalo como bulk con una tasa mínima razonable y un máximo. Lo quieres fiable, no dominante.

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

Estas son las tareas que realmente ejecutas durante diseño, despliegue y depuración. Cada una incluye qué significa la salida y la decisión que tomas a partir de ella.

Tarea 1: Confirma velocidad/duplex del enlace y detecta problemas de autonegociación

cr0x@server:~$ sudo ethtool eth0
Settings for eth0:
	Supported ports: [ TP ]
	Supported link modes:   1000baseT/Full
	                        10000baseT/Full
	Supported pause frame use: Symmetric
	Supports auto-negotiation: Yes
	Advertised link modes:  10000baseT/Full
	Advertised auto-negotiation: Yes
	Speed: 10000Mb/s
	Duplex: Full
	Auto-negotiation: on
	Link detected: yes

Significado: Si ves 100Mb/s o Half duplex, tu “problema QoS” es en realidad un problema físico/de negociación de enlace.

Decisión: Arregla primero la velocidad/duplex. La QoS no puede salvar un enlace half-duplex de colisiones y fallos.

Tarea 2: Revisa errores y drops de interfaz (driver/NIC/camino)

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq 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
      987654321  123456      0     234       0    1234
    TX:  bytes packets errors dropped carrier collsns
      876543210  234567      0      12       0       0

Significado: Los drops de RX pueden indicar congestión upstream o incapacidad del host para procesar paquetes. Los drops de TX suelen indicar drops de qdisc o presión en el ring buffer.

Decisión: Si hay errores/carrier, arregla físico/driver. Si los drops se correlacionan con carga, pasa a estadísticas de cola y shaping.

Tarea 3: Identifica el qdisc actual y si ya tienes FQ/AQM

cr0x@server:~$ tc -s qdisc show dev eth0
qdisc mq 0: root
qdisc fq_codel 8012: parent :12 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn
 Sent 123456789 bytes 234567 pkt (dropped 123, overlimits 0 requeues 10)
 backlog 0b 0p requeues 10
  maxpacket 1514 drop_overlimit 123 new_flow_count 456 ecn_mark 789

Significado: Tienes fq_codel activo. Los drops indican presión en la cola; las marcas ECN indican que AQM está señalando congestión sin dropear (si los endpoints lo soportan).

Decisión: Si ves pfifo_fast o no hay AQM y tienes picos de latencia, habilitar fq_codel/cake en el cuello de botella es un movimiento de alto impacto.

Tarea 4: Mide rápidamente síntomas de encolamiento con ping bajo carga

cr0x@server:~$ ping -c 20 -i 0.2 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.42 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.39 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=35.12 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=42.77 ms

--- 10.0.0.1 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 3805ms
rtt min/avg/max/mdev = 0.36/6.88/42.77/13.10 ms

Significado: El RTT máximo salta a decenas de ms mientras el mínimo permanece sub-ms: encolamiento clásico (bufferbloat) durante la contención.

Decisión: Añade shaping + AQM en el cuello de botella de egress. No “priorices” al azar; arregla la cola.

Tarea 5: Revisa cambios de ruta/camino (porque no toda latencia es congestión)

cr0x@server:~$ ip route get 8.8.8.8
8.8.8.8 via 192.0.2.1 dev eth0 src 192.0.2.10 uid 0
    cache

Significado: Confirma qué gateway e interfaz están en juego.

Decisión: Si el tráfico “lento” usa una interfaz/túnel diferente a la que asumías, tu política de QoS podría estar en el egress equivocado por completo.

Tarea 6: Verifica marcas DSCP en tráfico real (no confíes en las configuraciones)

cr0x@server:~$ sudo tcpdump -i eth0 -vv -c 5 'udp and (port 5060 or portrange 16384-32767)'
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:00:01.123456 IP (tos 0xb8, ttl 64, id 1234, offset 0, flags [DF], proto UDP (17), length 214) 192.0.2.50.40000 > 192.0.2.60.20000: UDP, length 172
12:00:01.123789 IP (tos 0x00, ttl 64, id 1235, offset 0, flags [DF], proto UDP (17), length 214) 192.0.2.51.40002 > 192.0.2.60.20002: UDP, length 172

Significado: Un stream es EF (tos 0xb8), otro es CS0 (tos 0x00). Tus endpoints son inconsistentes o la política está reescribiendo.

Decisión: Decide si hacer cumplir el marcado en el límite (recomendado) y si confiarás en las marcas de los endpoints para esas fuentes.

Tarea 7: Comprueba si el host está reescribiendo DSCP (o no)

cr0x@server:~$ sysctl net.ipv4.tcp_ecn net.ipv4.conf.all.rp_filter
net.ipv4.tcp_ecn = 2
net.ipv4.conf.all.rp_filter = 1

Significado: ECN está habilitado (2 = habilitar y probar), rp_filter es estricto (1). rp_filter estricto puede romper rutas asimétricas y causar caídas “aleatorias”.

Decisión: Si haces routing basado en políticas, multihoming o ciertos túneles, considera relajar rp_filter y valida el comportamiento DSCP de extremo a extremo.

Tarea 8: Inspecciona reglas iptables mangle para marcado (legacy pero común)

cr0x@server:~$ sudo iptables -t mangle -S
-P PREROUTING ACCEPT
-P OUTPUT ACCEPT
-A OUTPUT -p udp --dport 53 -j DSCP --set-dscp-class AF21
-A OUTPUT -p tcp --dport 22 -j DSCP --set-dscp-class AF21
-A OUTPUT -p tcp --dport 873 -j DSCP --set-dscp-class CS1

Significado: DNS/SSH marcados como interactivo; rsync marcado como scavenger. Esto es basado en comportamiento y sensato.

Decisión: Manténlo pequeño. Evita listas gigantes de puertos. Si las apps cambian puertos (hola, QUIC), perderás la clasificación de todos modos.

Tarea 9: Inspecciona nftables para marcado (el moderno por defecto)

cr0x@server:~$ sudo nft list ruleset
table inet mangle {
  chain output {
    type route hook output priority mangle; policy accept;
    udp dport 53 ip dscp set af21
    tcp dport { 22, 443 } ip dscp set af21
    tcp dport 2049 ip dscp set cs1
  }
}

Significado: La cadena output marca tráfico por puerto; NFS (2049) puesto en CS1 aquí (cuestionable a menos que realmente lo quieras scavenger).

Decisión: Cuestiónalo. El tráfico de almacenamiento puede necesitar una cuota mínima, no estado scavenger, según tus modos de falla.

Tarea 10: Valida que el shaping esté activo y a la tasa correcta

cr0x@server:~$ sudo tc qdisc show dev eth0
qdisc htb 1: root refcnt 2 r2q 10 default 30 direct_packets_stat 0 direct_qlen 1000
qdisc fq_codel 10: parent 1:10 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn
qdisc fq_codel 20: parent 1:20 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn
qdisc fq_codel 30: parent 1:30 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn

Significado: HTB root con tres clases, fq_codel en cada una. Esto es una línea base sólida.

Decisión: Ahora verifica tasas/techos de clases y que el tráfico predeterminado vaya a la clase destinada.

Tarea 11: Lee estadísticas de clases HTB para ver quién gana y quién se queda sin recursos

cr0x@server:~$ sudo tc -s class show dev eth0
class htb 1:10 root rate 50Mbit ceil 200Mbit burst 15Kb cburst 15Kb
 Sent 98765432 bytes 123456 pkt (dropped 0, overlimits 0 requeues 0)
class htb 1:20 root rate 200Mbit ceil 900Mbit burst 15Kb cburst 15Kb
 Sent 876543210 bytes 234567 pkt (dropped 0, overlimits 0 requeues 0)
class htb 1:30 root rate 50Mbit ceil 900Mbit burst 15Kb cburst 15Kb
 Sent 4567890123 bytes 3456789 pkt (dropped 4321, overlimits 9876 requeues 123)

Significado: La clase 1:30 (probablemente bulk/predeterminado según mapping) está alcanzando overlimits y drops, lo que indica que está siendo restringida y se está encolando. Las otras están bien.

Decisión: Si 1:30 es bulk, bien. Si es tráfico predeterminado de usuarios, lo clasificaste mal y estás castigando a lo incorrecto.

Tarea 12: Revisa conntrack y ve si “pocos flujos” dominan

cr0x@server:~$ sudo conntrack -S
cpu=0 found=123456 invalid=12 ignore=0 insert=34567 insert_failed=0 drop=0 early_drop=0 error=0 search_restart=123

Significado: No es una métrica de QoS directamente, pero picos de invalid/insert_failed pueden indicar sobrecarga del host causando drops que parecen “problemas de QoS de red”.

Decisión: Si conntrack está estresado, arregla eso (tuning, offload, capacidad) antes de culpar a las disciplinas de cola.

Tarea 13: Confirma el encolamiento de NIC y comportamiento multiqueue

cr0x@server:~$ sudo ethtool -l eth0
Channel parameters for eth0:
Pre-set maximums:
RX:		0
TX:		0
Other:		0
Combined:	8
Current hardware settings:
RX:		0
TX:		0
Other:		0
Combined:	8

Significado: 8 canales combinados sugiere multi-queue; la configuración de qdisc debe tener en cuenta mq. Algunos setups de shaping solo afectan una cola a menos que se apliquen correctamente.

Decisión: Si haces shaping, asegúrate de aplicarlo en la raíz (o usa IFB/ingress si es necesario). Un shaping mal aplicado falla en silencio.

Tarea 14: Encuentra el egress “real” en un host con VLANs/bonds

cr0x@server:~$ ip -d link show bond0
5: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 52:54:00:aa:bb:cc brd ff:ff:ff:ff:ff:ff
    bond mode 802.3ad miimon 100 updelay 0 downdelay 0

Significado: Interfaz bondeada. Si adjuntas qdisc al nivel equivocado (bond vs subif VLAN vs físico), los resultados varían.

Decisión: Aplica QoS en la interfaz que realmente encola. A menudo es el bond o el miembro físico dependiendo del driver y offloads.

Tarea 15: Confirma si GRO/GSO/TSO offloads están ocultando comportamiento de cola

cr0x@server:~$ sudo ethtool -k eth0 | egrep 'gro|gso|tso'
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on

Significado: Los offloads pueden reducir CPU y cambiar la fragmentación; el shaping y la clasificación basados en tamaños de paquete pueden comportarse diferente.

Decisión: Normalmente deja offloads activos en servidores, pero si depuras comportamiento raro de qdisc, prueba a alternarlos (con cuidado) en ventana de mantenimiento.

Tarea 16: Prueba que un dispositivo en el camino esté borrando DSCP

cr0x@server:~$ sudo tcpdump -i eth0 -vv -c 3 'icmp and host 198.51.100.10'
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
12:05:00.000001 IP (tos 0x88, ttl 64, id 7000, offset 0, flags [DF], proto ICMP (1), length 84) 192.0.2.10 > 198.51.100.10: ICMP echo request, id 1, seq 1, length 64
12:05:00.010001 IP (tos 0x00, ttl 51, id 8000, offset 0, flags [none], proto ICMP (1), length 84) 198.51.100.10 > 192.0.2.10: ICMP echo reply, id 1, seq 1, length 64

Significado: Enviaste con tos 0x88 (combinación DSCP/ECN); la respuesta es CS0. No es concluyente por sí solo, pero si también capturas en el extremo lejano y ves DSCP reseteado, algo reescribe.

Decisión: Deja de depender de DSCP a través de ese límite. Usa shaping/equidad que no dependa de marcas preservadas.

Tres micro-historias corporativas desde las trincheras de QoS

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

Una fintech mediana tenía una “VLAN de voz” y la creencia de larga data: los paquetes de voz son sagrados. Implementaron un nuevo cliente softphone y un nuevo modelo de switch en el mismo trimestre. El cliente marcó media como EF, señalando “expedited forwarding”. Los switches se configuraron para confiar en DSCP en puertos de acceso porque eso era lo que hacían los viejos teléfonos.

Luego, un equipo no relacionado desplegó un agente telemétrico de alto throughput que, por defecto del proveedor, también marcó sus flujos UDP como EF. Nadie lo notó porque todo funcionaba bien con baja carga, y los dashboards de la plataforma de telemetría parecían “en tiempo real”.

Una mañana de lunes, un backlog en telemetría causó tráfico sostenido marcado EF. Los switches de distribución tenían colas de prioridad estricta para EF sin policing—porque la voz “nunca usa tanto ancho de banda”. Esa suposición era cierta para teléfonos de escritorio. Era falsa para software en hosts de propósito general.

El resultado fue quirúrgico: las llamadas de voz sonaron bien, la telemetría fluyó como campeona y todo lo demás se degradó. El DNS se volvió lento. Las llamadas API expiraron. Soporte culpó al firewall, el equipo de firewall culpó al ISP y el ISP pidió capturas que nadie pudo interpretar bajo presión.

La solución fue aburrida e inmediata: dejar de confiar en DSCP en puertos de acceso generales, remarcar EF solo para endpoints de voz autenticados y policiar EF a un porcentaje máximo por puerto. La voz se mantuvo limpia, la telemetría siguió funcionando y el tráfico predeterminado dejó de ahogarse.

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

Una empresa retail tenía una WAN privada con múltiples sitios y una ventana nocturna de backups. Los backups consumían tanto ancho que el equipo de red creó una clase bulk y la capó agresivamente. Buena intención: proteger tráfico de negocio durante el día. Lo desplegaron en todas partes, incluidos los uplinks del centro de datos.

Los backups se ralentizaron, como esperaban. Luego, días después, una réplica de base de datos comenzó a retrasarse. No lo suficiente para alertar de inmediato, pero sí para empujar la replicación hacia atrás. Una prueba de failover rutinaria esa semana tardó más de lo cómodo para admitir.

Lo que pasó: la replicación y los backups compartían puertos y patrones de forma que el clasificador no pudo distinguir. El “cap bulk” se aplicó a más que backups. El sistema no falló ruidosamente; se degradó silenciosamente. Eso es peor.

Intentaron “arreglarlo” creando más clases: una para backups, otra para replicación, otra para metadatos de almacenamiento, otra para todo lo demás. Empeoró porque la precisión del clasificador bajó y la política se volvió imposible de razonar. Un mes después, nadie sabía a qué clase pertenecía un flujo dado, lo que significaba que nadie podía predecir el comportamiento bajo contención.

La solución real: reducir el número de clases, clasificar replicación por identidad del endpoint (servidores de backup vs nodos de replicación) y dar a la replicación una cuota mínima con un techo razonable. Además: shapear en los bordes WAN, no en uplinks aleatorios del centro de datos donde la congestión no era el cuello de botella.

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

Una compañía SaaS ejecutaba clusters Kubernetes multi-tenant con incidentes periódicos de “vecino ruidoso”. Desde temprano decidieron una regla sosa: nada de DSCP controlado por tenants. Todo el egress de pods se remarcaría en el nodo según namespace y un conjunto pequeño de etiquetas de servicio. Documentaron el mapeo y lo hicieron cumplir en revisión de código.

También aplicaron shaping en el egress a Internet en cada gateway NAT del cluster ligeramente por debajo del policer conocido del proveedor. Bajo ese shaping usaban fq_codel para equidad y mantenían exactamente cuatro clases: realtime (raro), interactivo, predeterminado, bulk. Bulk tenía un techo, interactivo tenía una pequeña garantía y realtime estaba estrictamente policionado.

Un día, un tenant lanzó una función de “exportación de datos” que empezó a saturar el egress. Soporte vio un pico en latencia de UI y temió un incidente repetido. Pero los gráficos contaron la historia claramente: la utilización de la clase bulk se pegó a su techo, interactivo se mantuvo estable y predeterminado se degradó solo ligeramente.

El on-call no se lanzó a inventar nuevas prioridades. Le dijeron al tenant, con honestidad, “Tu trabajo está en la clase bulk, está capado por diseño y terminará en N horas.” Luego ayudaron al tenant a programar las exportaciones y ofrecieron un tier superior con techos de bulk más altos. Sin crisis, sin cambio de política a medianoche, sin misterio.

Esto es cómo luce “QoS que funciona”: una política que puedes explicar a un ingeniero cansado a las 3 a.m., con instrumentación que confirma que la política hace lo que pretendías.

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

1) “QoS está habilitada pero la latencia aún salta durante subidas”

Síntoma: p95 de latencia salta cuando alguien satura el uplink; aparecen pérdidas en el borde del ISP; el dispositivo local muestra pocos drops.

Causa raíz: La cola está aguas arriba (policer del proveedor / módem cable / CPE no gestionado). No controlas la cola del cuello de botella.

Solución: Shapea el egress por debajo de la tasa realmente aplicada (a menudo 90–95%). Usa cake o HTB+fq_codel para que tu equipo posea la cola.

2) “Pusimos todo en alta prioridad y ahora nada funciona”

Síntoma: El tráfico predeterminado se queda sin recursos; timeouts aleatorios; la voz está bien; el monitoring dice que el enlace no está lleno.

Causa raíz: La cola de prioridad estricta no está policíada; tráfico mal marcado la inunda y asfixia otras colas.

Solución: Policía/limita la clase de prioridad estricta. Reduce quién puede marcar EF. Considera planificadores WRR/DRR en vez de prioridad estricta salvo para pequeño realtime.

3) “Tras habilitar QoS, el throughput cayó 30%”

Síntoma: Transferencias bulk más lentas de lo esperado incluso con enlace vacío; CPU en router/host aumentó.

Causa raíz: Shaper puesto a una tasa demasiado baja, o qdisc (cake/fq_codel) funcionando en hardware poco potente, o interacciones con offloads.

Solución: Valida la tasa real del enlace; ajusta el shaper; asegura capacidad hardware; considera mover el shaping a una caja que lo soporte; mantén reglas simples.

4) “Solo algunas aplicaciones reciben el tratamiento previsto”

Síntoma: Un mismo servicio se comporta distinto en hosts/subredes; capturas muestran DSCP inconsistentes.

Causa raíz: Múltiples puntos de marcado (endpoints + firewall + switch) reescribiendo DSCP; límite de confianza inconsistente.

Solución: Elige una autoridad de marcado por límite. Documenta. Haz cumplir: o confías en endpoints gestionados o remarcas en el ingreso a tu dominio.

5) “La QoS funciona en cable pero usuarios Wi‑Fi siguen quejándose”

Síntoma: Llamadas por cable bien; llamadas Wi‑Fi con jitter; picos de pérdida con más clientes.

Causa raíz: La contención de tiempo de aire y los reintentos dominan; mapeo WMM incorrecto o no aplicado; buffers del AP inflados.

Solución: Ajusta Wi‑Fi por separado: habilita WMM, asegúrate que el mapeo DSCP→AC es correcto, reduce bufferbloat en el borde WLAN, prefiere 5/6 GHz, gestiona densidad de clientes.

6) “Marcamos tráfico pero los switches lo ignoran”

Síntoma: DSCP presente en paquetes pero sin cambio de comportamiento; contadores QoS del switch no se mueven.

Causa raíz: Confianza DSCP deshabilitada en puertos, o mapeo DSCP→cola no configurado, o limitaciones de hardware.

Solución: Confirma QoS habilitado globalmente; configura el límite de confianza; mapea DSCP/PCP a colas; verifica con contadores y pruebas de congestión.

7) “El tráfico interactivo sigue con lag bajo carga bulk”

Síntoma: SSH se congela cuando corren backups; la utilización general no está al máximo.

Causa raíz: No hay equidad en la cola del cuello de botella (pfifo), o interactivo está en la misma cola que bulk, o la clase no tiene cuota mínima.

Solución: Usa fq_codel/cake; asegura que la clase interactiva tenga al menos una pequeña garantía; verifica la clasificación con captura de paquetes.

Listas de verificación / plan paso a paso

Paso a paso: implementa QoS que puedas defender en una revisión

  1. Identifica el/los enlace(s) cuello de botella. Egress a internet, circuitos WAN, túneles VPN, uplinks de controladores Wi‑Fi. Si no lo sabes, mide utilización y latencia bajo carga.
  2. Decide tu modelo de clases (3–5 clases). Escribe una frase de política por cada una: cuota mínima, tope máximo y por qué.
  3. Define límites de confianza. Dónde se confía DSCP/PCP; dónde se sobrescribe; dónde se ignora.
  4. Elige mecanismo de encolamiento/shaping por límite. Cake si está disponible; si no HTB+fq_codel. No mezcles planificadores exóticos a menos que puedas observar y revertir.
  5. Fija la tasa de shaping por debajo de la tasa aplicada. Empieza en 90–95% del throughput sostenible medido; ajusta tras verificación.
  6. Policia clases de prioridad estricta. EF tiene cap. Siempre. Si no, estás escribiendo un outage en tu configuración.
  7. Implementa clasificación en un único lugar. Preferir nodo/ToR/borde sobre la aplicación. Mantén reglas cortas y basadas en identidad cuando sea posible.
  8. Instrumenta. Sigue utilización por clase, drops, marcas ECN, backlog de cola y SLOs de latencia de usuarios finales.
  9. Prueba bajo contención controlada. Genera carga bulk; verifica que interactivo/realtime se mantengan estables; captura paquetes para confirmar marcas y mapeos.
  10. Documenta el “por qué”. Incluye ejemplos: “Backups son CS1, capados a X, programados fuera de horas.” El tú futuro olvidará. El tú presente renunciará.
  11. Despliega gradualmente. Un sitio/enlace a la vez. Ten listo un comando de rollback.
  12. Haz un game day. Saturen intencionalmente; confirma que el sistema falla de forma ordenada y predecible.

Lista: qué capturar durante un incidente de QoS

  • Estadísticas de interfaz (bytes, drops, errores) en el egress sospechoso.
  • Estadísticas de qdisc (drops, overlimits, marcas ECN, backlog).
  • Muestras de latencia (min/avg/max) en reposo y bajo carga.
  • Captura de paquetes mostrando DSCP/PCP para al menos un flujo afectado.
  • Verificación de ruta (route, estado de túneles, gateway NAT usado).
  • Historial de cambios: qué se desplegó/cambió en las últimas 24 horas.

Preguntas frecuentes

1) ¿Debería priorizar ACKs TCP?

A veces. En enlaces muy asimétricos (uplink pequeño, downlink grande), priorizar ACKs puede mejorar el throughput descendente y reducir bloqueos. Pero no adivines: primero confirma que la saturación de uplink está causando el colapso downstream. Si usas cake, ya maneja mucho de esto bien.

2) ¿Es suficiente DSCP o necesito shaping?

DSCP por sí solo es una petición. El shaping es la aplicación. Si no controlas la cola del cuello de botella, DSCP son en su mayoría vibes. Usa DSCP para clasificación dentro de tu dominio, pero asume que puede ser blanqueado fuera.

3) ¿Por qué no poner todo “AF41” y listo?

Porque la contención sigue existiendo. Si todo es premium, nada lo es. Peor aún, pierdes la capacidad de aislar tráfico bulk, que es la principal ganancia para la experiencia del usuario.

4) ¿La QoS puede arreglar pérdida de paquetes por un cable malo u óptica defectuosa?

No. Eso no es congestión; es física, hardware o configuración. Arregla capa 1/2 primero. La QoS solo gestiona contención en un enlace funcional.

5) ¿Cuántas clases debería tener?

Tres a cinco para la mayoría. Más clases aumentan el riesgo operativo: mala clasificación, inanición inesperada y políticas que nadie puede razonar durante incidentes.

6) ¿Dónde debería marcar tráfico en Kubernetes?

En el límite del nodo (red del host) según identidad de namespace/workload, no dentro de pods. Los pods se configuran fácilmente mal y los clusters multi-tenant requieren un límite de confianza firme.

7) ¿ECN reemplaza la QoS?

No. ECN ayuda a endpoints a reaccionar a la congestión sin drops, pero no define quién obtiene ancho de banda bajo contención. ECN junto con FQ/AQM es excelente; ECN solo no asigna equitativamente entre tipos de tráfico.

8) ¿Cuál es el cambio más sencillo para “mejorar hoy”?

Habilita fq_codel (o cake) en el egress cuello de botella real y shapea ligeramente por debajo de la tasa aplicada. Esto suele reducir picos de latencia drásticamente sin clasificación elaborada.

9) ¿La replicación de almacenamiento debería ser “alta prioridad” alguna vez?

Rara vez. La replicación necesita fiabilidad y una cuota mínima, no prioridad estricta. Si la priorizas por encima del tráfico interactivo, estás optimizando para el tipo de uptime equivocado.

10) ¿Cómo pruebo que la QoS funciona?

Reproduce contención y muestra: (a) los contadores de clase cambian como esperabas, (b) la latencia interactiva se mantiene estable, (c) el bulk tarda más pero termina, (d) drops/retraso de cola están controlados en tu shaper, no aguas arriba.

Conclusión: próximos pasos que puedes hacer esta semana

Si tu estrategia de QoS es “subir la prioridad”, estás a un flujo mal marcado de un incidente extraño y largo. La alternativa no es complicada, solo disciplinada: controla la cola del cuello de botella, mantén pocas clases, aplica límites de confianza y mide lo que tu scheduler realmente hace.

Próximos pasos prácticos:

  1. Elige un cuello de botella conocido (egress a internet o borde WAN) e implementa shaping al 90–95% del throughput sostenido observado.
  2. Habilita fq_codel o cake en ese egress y captura estadísticas de qdisc antes/después bajo carga.
  3. Define un plan DSCP mínimo (CS0, un AF para interactivo, EF para realtime pequeño policíado, CS1 para scavenger) y documenta dónde confías en él.
  4. Ejecuta una prueba de saturación controlada y demuestra que la latencia interactiva se mantiene razonable.
  5. Escribe el plan de rollback. No porque vayas a fallar, sino para dormir tranquilo.

Haz esto y la QoS será lo que debería haber sido: comportamiento predecible durante la contención, no una Ouija de red.

← Anterior
Intel VT-d vs AMD-Vi: ¿Cuál ofrece realmente mejor passthrough?
Siguiente →
Guía de instalación de Ubuntu 24.04 LTS: arranque dual, Secure Boot y cero pérdida de datos

Deja un comentario