Ubuntu 24.04 : iperf affiche la vitesse mais l’application est lente — goulots d’étranglement cachés à vérifier (cas n°24)

Cet article vous a aidé ?

Votre tableau de bord SRE est calme, les LED des liaisons sont satisfaisantes, et iperf3 vient de crier « 10 Gbit/s » comme s’il en était fier. Pendant ce temps, l’application réelle a l’air d’envoyer des requêtes par pigeon voyageur. C’est le type d’incident qui déclenche des débats sur Slack : « Ce ne peut pas être le réseau, iperf est bon. » « C’est toujours le réseau. » Les deux peuvent avoir tort.

Le cas n°24 est le piège classique : un benchmark de débit prouve que le tuyau est large, mais votre charge a besoin d’autre chose — faible latence de queue, ordonnancement CPU correct, files stables, résolution DNS prévisible, ou stockage capable de suivre. Je vais vous montrer où les goulots d’étranglement se cachent sur Ubuntu 24.04, comment les détecter avec des commandes que vous pouvez réellement exécuter, et comment prendre des décisions à partir des sorties au lieu de collectionner des captures d’écran pour un postmortem.

Playbook de diagnostic rapide

Quand l’application est lente mais que iperf3 a l’air d’aller bien, n’« optimisez » rien pour l’instant. Localisez d’abord la classe du goulot d’étranglement : CPU/interruptions, TCP/chemin, résolution de noms/TLS, stockage, ou concurrence applicative. Voici l’ordre qui permet de trouver le coupable le plus vite en production.

1) Confirmer que le symptôme est la latence, pas seulement le débit

  • Mesurez le timing des requêtes côté client (logs applicatifs, timings curl, statistiques du client BD).
  • Exécutez un outil de latence (ping, mtr, retransmissions ss) pendant que le ralentissement se produit.

2) Vérifier la pression CPU et le déséquilibre softirq/irq

  • Si le CPU est saturé, le réseau peut être « rapide » dans iperf (un flux sur un cœur) alors que votre vraie application est bloquée sur softirq, TLS, GC, ou appels système.
  • Recherchez un softirq élevé, du iowait, ou du throttling cgroup.

3) Vérifier l’état TCP : retransmissions, congestion, trous MTU

  • ss -ti montre les retransmissions et le pacing.
  • Un mauvais appariement MTU et un PMTUD cassé produisent souvent « rapide parfois » et des « blocages mystérieux ».

4) Vérifier l’enqueue et les pertes : anneaux NIC, qdisc, bufferbloat

  • Les pertes peuvent être invisibles pour iperf si ses flux récupèrent ; votre appli peut ne pas le faire.
  • Surveillez ethtool -S, nstat et les statistiques qdisc.

5) Vérifier le stockage et le système de fichiers : iowait, écritures sync, subtilités NFS/SMB

  • Si l’application attend le disque, les benchmarks réseau sont sans objet.
  • Consultez iostat, pidstat -d et les options de montage.

6) Vérifier les dépendances « plomberie » : DNS, heure, TLS, proxies

  • Un DNS lent ressemble à un « réseau lent » et fait perdre du temps à tout le monde.
  • Les handshakes TLS qui bloquent peuvent dominer le P99 même avec une liaison parfaite.

Idée paraphrasée (attribuée) : Werner Vogels a poussé l’idée d’optimiser pour la queue, car les utilisateurs vivent la partie la plus lente. C’est le cœur de ce cas : iperf vous dit la largeur médiane du tuyau ; vos utilisateurs sont coincés dans la queue.

Pourquoi iperf paraît bon alors que votre application souffre

iperf3 est un excellent outil. C’est aussi un outil très spécifique : il mesure le débit (et un peu de perte/jitter en UDP) sous un motif de flux synthétique. Les applications réelles demandent généralement un autre ensemble de garanties :

  • La distribution de latence, pas la bande passante brute. Beaucoup d’applications envoient de petites requêtes, attendent des réponses, puis envoient d’autres requêtes. Le pipeline n’est jamais plein. iperf le remplit.
  • Beaucoup de flux concurrents. Le défaut d’iperf est un ou quelques flux. Votre maillage de services peut compter des milliers de connexions.
  • Coût CPU par octet élevé. TLS, compression, parsing JSON, journalisation, copies noyau, checksums et stacks réseaux en espace utilisateur consomment du CPU. iperf peut être relativement léger en CPU par comparaison.
  • Chemins de code différents. Votre appli peut passer par des proxies, NAT, conntrack, DNS, load balancers L7, sidecars ou VPN. iperf est souvent point-à-point et contourne le chemin réel.
  • Tailles de paquets différentes. MSS, MTU, GSO/TSO, GRO/LRO changent le comportement. Les motifs de charge d’iperf ne sont pas ceux de votre application.
  • Rétro-pression différente. Les applis peuvent bloquer sur le disque, des verrous, des pools de BD, ou des rate limiters. La socket devient le messager qu’on blâme à tort.

Voici la vérité inconfortable : iperf rapide ne prouve presque rien au-delà de « deux hôtes peuvent pousser des octets quand on leur demande gentiment ». Le trafic de production n’est pas demandé gentiment.

Petite blague #1 : iperf, c’est comme un test sur tapis roulant : il prouve que votre cœur fonctionne, mais il n’explique pas pourquoi vous êtes essoufflé en portant des sacs de courses.

Faits intéressants et brève histoire utiles

  • TCP a été conçu pour la fiabilité avant que la vitesse ne soit à la mode. Il est excellent pour transformer la perte en latence quand les files se remplissent.
  • Linux utilise des disciplines de queue avancées depuis des années. Les paramètres modernes favorisent l’équité (fq_codel) pour lutter contre le bufferbloat, mais votre environnement peut les écraser.
  • Le terme « bufferbloat » est devenu courant dans les années 2010. Trop de buffering peut faire paraître le débit excellent tandis que la latence interactive s’effondre.
  • La modulation d’interruptions et NAPI ont changé la donne. Les cartes NIC sont passées d’« interruption par paquet » à des lots, échangeant latence contre efficacité CPU — bénéfique jusqu’à un certain point.
  • TSO/GSO/GRO sont des miracles de performance avec des effets secondaires. Les offloads réduisent le CPU en groupant les paquets, mais peuvent masquer des schémas de perte et compliquer le dépannage.
  • conntrack n’est pas gratuit. Le suivi d’état NAT et des pare-feu peut devenir le goulot bien avant que la liaison soit saturée.
  • Les échecs PMTUD sont un bug classique « ça marche en labo ». Si les ICMP « Fragmentation needed » sont bloqués, certains chemins noient les gros paquets et créent des stalls étranges.
  • Le DNS est passé d’« annoyance » à dépendance critique. Les microservices ont transformé les résolutions en charge élevée QPS ; les timeouts deviennent visibles par l’utilisateur.
  • TLS est devenu plus rapide, et aussi plus lourd. TLS 1.3 a réduit les allers-retours mais a transféré plus de travail au CPU. Sur des hôtes chargés, les handshakes peuvent encore dominer.

Tâches pratiques : commandes, sorties et décisions

Ce sont des tâches réelles que vous pouvez exécuter sur Ubuntu 24.04. Chacune comprend : la commande, ce que la sortie signifie, et la décision à prendre. Exécutez-les pendant le ralentissement si possible ; sinon vous diagnostiquez un fantôme.

Task 1: Reproduire iperf d’une façon qui ressemble à votre appli

cr0x@server:~$ iperf3 -c 10.0.0.20 -P 8 -t 20
Connecting to host 10.0.0.20, port 5201
[SUM]   0.00-20.00  sec  22.8 GBytes  9.79 Gbits/sec  0             sender
[SUM]   0.00-20.04  sec  22.8 GBytes  9.77 Gbits/sec                  receiver

Ce que cela signifie : Plusieurs flux parallèles (-P 8) peuvent masquer des limites par flux. Si votre appli utilise beaucoup de connexions, c’est plus proche que d’utiliser un seul flux.

Décision : Si un seul flux est lent mais que le multi-flux est rapide, suspectez des contraintes par flux : contrôle de congestion, MTU/PMTUD, policers, ou un goulot CPU/IRQ unique.

Task 2: Mesurer la latence et la stabilité du chemin avec mtr

cr0x@server:~$ mtr -rwzc 200 10.0.0.20
Start: 2025-12-30T10:12:31+0000
HOST: server                       Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.0.0.1                    0.0%   200   0.25  0.32  0.19  1.90  0.18
  2.|-- 10.0.0.20                   0.0%   200   0.42  0.55  0.35  5.70  0.44

Ce que cela signifie : Une moyenne faible mais des pics élevés de latence suggèrent de l’enqueue ou des pertes/retransmissions intermittentes.

Décision : Si les pires cas coïncident avec la lenteur applicative, passez aux vérifications des files/périodes de drop et des retransmissions TCP.

Task 3: Voir si l’hôte manque de CPU ou est bloqué en iowait

cr0x@server:~$ uptime
 10:14:02 up 12 days,  3:21,  2 users,  load average: 18.42, 16.90, 14.11

Ce que cela signifie : La charge moyenne est la somme des tâches exécutable + non interruptibles. Une charge élevée peut venir d’une contention CPU ou d’attentes I/O.

Décision : Une charge élevée avec une faible utilisation CPU signifie souvent des E/S bloquantes (disque ou système de fichiers réseau) ou de la contention sur des verrous. Ne touchez pas au tuning NIC avant de savoir.

Task 4: Décomposer CPU, softirq et iowait

cr0x@server:~$ mpstat -P ALL 1 5
Linux 6.8.0-xx-generic (server)  12/30/2025  _x86_64_  (32 CPU)

12:14:21     CPU   %usr   %sys  %iowait  %soft  %idle
12:14:22     all   38.10  21.33    0.15   18.40  22.02
12:14:22      7   10.00  15.00    0.00   70.00   5.00

Ce que cela signifie : Le CPU 7 est submergé par %soft (softirq). C’est le traitement de paquets et assimilés.

Décision : Si un ou deux CPU sont saturés en softirq, vous avez probablement un déséquilibre IRQ/RPS/RFS. Corrigez cela avant de blâmer « le réseau ».

Task 5: Identifier quelles interruptions sont chaudes

cr0x@server:~$ cat /proc/interrupts | egrep -i 'eth0|mlx|ixgbe|enp|eno' | head
  98:  192837465   0   0   0   PCI-MSI 524288-edge      enp5s0f0-TxRx-0
  99:     120044   0   0   0   PCI-MSI 524289-edge      enp5s0f0-TxRx-1
100:     118900   0   0   0   PCI-MSI 524290-edge      enp5s0f0-TxRx-2

Ce que cela signifie : La queue 0 capte presque toutes les interruptions. Les autres queues sont inactives.

Décision : Activez ou corrigez l’affinité IRQ (ou utilisez irqbalance avec précaution), et vérifiez que les files RSS sont configurées pour répartir la charge.

Task 6: Vérifier les offloads NIC et l’état du lien

cr0x@server:~$ sudo ethtool enp5s0f0
Settings for enp5s0f0:
	Supported link modes:   1000baseT/Full 10000baseT/Full
	Speed: 10000Mb/s
	Duplex: Full
	Auto-negotiation: on
	Link detected: yes

Ce que cela signifie : Le lien est négocié à la vitesse/duplex attendue. Si vous voyez 1000Mb/s de façon inattendue, arrêtez-vous et corrigez le câblage/SFP/la config du port du switch.

Décision : Corrigez la discordance physique/couche liaison avant de faire quoi que ce soit « intelligent » en logiciel.

Task 7: Rechercher les pertes au niveau NIC et les overruns d’anneau

cr0x@server:~$ sudo ethtool -S enp5s0f0 | egrep -i 'drop|discard|miss|overrun|timeout' | head -n 20
rx_missed_errors: 18234
rx_no_buffer_count: 14590
tx_timeout_count: 0

Ce que cela signifie : rx_no_buffer_count suggère que le NIC/driver a manqué de buffers de réception — souvent un problème de taille d’anneau, de starvation CPU/softirq, ou de budgets mémoire trop faibles sous pression.

Décision : Si ces compteurs augmentent pendant le ralentissement, traitez la distribution CPU/IRQ et envisagez le tuning des anneaux (ethtool -g/-G). Vérifiez aussi si l’hôte manque de mémoire.

Task 8: Inspecter les tailles d’anneau (et si vous pouvez les changer)

cr0x@server:~$ sudo ethtool -g enp5s0f0
Ring parameters for enp5s0f0:
Pre-set maximums:
RX:	4096
TX:	4096
Current hardware settings:
RX:	512
TX:	512

Ce que cela signifie : Les anneaux sont petits par rapport au maximum. De petits anneaux peuvent dropper lors de micro-burst ; de gros anneaux peuvent augmenter la latence en bufferisant trop. Choisissez votre poison en connaissance de cause.

Décision : Si vous constatez des drops RX et des pics de latence sous charge bursty, augmenter modérément l’anneau RX peut aider. Si votre plainte est la latence de queue sous charge modérée, n’augmentez pas aveuglément les buffers.

Task 9: Vérifier les retransmissions TCP et la santé des sockets

cr0x@server:~$ ss -ti dst 10.0.0.20 | head -n 20
ESTAB 0 0 10.0.0.10:46322 10.0.0.20:443
	 cubic wscale:7,7 rto:204 rtt:3.2/0.8 ato:40 mss:1448 pmtu:1500 rcvmss:1448 advmss:1448
	 bytes_sent:184233 bytes_retrans:12480 bytes_acked:171753 segs_out:2219 segs_in:1962 data_segs_out:2010

Ce que cela signifie : Un bytes_retrans non négligeable est un signal fort. Les retransmissions se transforment en latence, head-of-line blocking, et lenteurs visibles par l’utilisateur.

Décision : Si les retransmissions coïncident avec les périodes lentes, concentrez-vous sur la perte sur le chemin, les drops en file, les policers, les problèmes MTU, ou le driver NIC.

Task 10: Vérifier les statistiques réseau du noyau pour retransmissions et timeouts

cr0x@server:~$ nstat -az | egrep 'TcpRetransSegs|TcpTimeouts|TcpExtTCPSynRetrans|IpExtInNoRoutes'
TcpRetransSegs             18432              0.0
TcpTimeouts                 1220              0.0
TcpExtTCPSynRetrans          219              0.0

Ce que cela signifie : L’augmentation des retransmissions/timeouts pointe vers la perte, un mauvais queueing, ou des trous sur le chemin. Les retransmissions SYN peuvent indiquer des drops SYN (firewall, conntrack, ou listener surchargé).

Décision : Si les retransmissions SYN montent en flèche, inspectez les limites conntrack, les règles de pare-feu, et la file d’accept/backlog sur le serveur.

Task 11: Détecter les trous MTU/PMTUD avec une sonde contrôlée

cr0x@server:~$ ping -M do -s 1472 -c 5 10.0.0.20
PING 10.0.0.20 (10.0.0.20) 1472(1500) bytes of data.
1472 bytes from 10.0.0.20: icmp_seq=1 ttl=64 time=0.42 ms
1472 bytes from 10.0.0.20: icmp_seq=2 ttl=64 time=0.44 ms

--- 10.0.0.20 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms

Ce que cela signifie : Ceci confirme que l’MTU 1500 fonctionne de bout en bout. Si cela échoue avec « Frag needed » ou des drops silencieux, vous avez un mauvais MTU ou des ICMP bloqués provoquant l’échec de PMTUD.

Décision : Si cela échoue, corrigez la cohérence MTU ou autorisez les ICMP nécessaires. Ne « résolvez » pas le problème avec un MSS clamping aléatoire à moins de contrôler tout le chemin et d’en comprendre l’impact.

Task 12: Inspecter qdisc et le comportement de mise en file

cr0x@server:~$ tc -s qdisc show dev enp5s0f0
qdisc mq 0: root
qdisc fq_codel 0: parent :1 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms ecn
 Sent 29837294812 bytes 21833890 pkt (dropped 482, overlimits 0 requeues 1221)
 backlog 0b 0p requeues 1221

Ce que cela signifie : Les drops au niveau qdisc peuvent être sains (drop contrôlé) ou symptomatiques (limite trop petite, appli bursty). Les requeues suggèrent de la contention ou du pacing.

Décision : Si vous voyez des drops soutenus et une latence croissante, ajustez les queues et le pacing — mais seulement après avoir vérifié CPU et drops NIC. Si la latence de queue est le problème, fq_codel est en général votre allié ; le remplacer par pfifo_fast revient à voyager en 2009.

Task 13: Vérifier la pression conntrack (goulot NAT/pare-feu)

cr0x@server:~$ sudo sysctl net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_max = 262144
cr0x@server:~$ sudo cat /proc/sys/net/netfilter/nf_conntrack_count
258901

Ce que cela signifie : Vous êtes proche de la limite. Quand conntrack est plein, les nouvelles connexions échouent ou stagnent. iperf peut encore fonctionner s’il réutilise des connexions ou si vous testez en dehors du chemin réel.

Décision : Augmentez nf_conntrack_max (en tenant compte de la mémoire), réduisez le churn de connexions, ou contournez conntrack pour le trafic qui n’en a pas besoin. Vérifiez aussi les timeouts adaptés à votre charge.

Task 14: Confirmer que le DNS n’est pas le « problème réseau »

cr0x@server:~$ resolvectl query api.internal.example
api.internal.example: 10.0.0.20                        -- link: enp5s0f0
                     (A) -- flags: answer
                      52ms

Ce que cela signifie : 52ms pour résoudre un nom interne est suspect dans un contexte LAN. Quelques-unes de ces requêtes par chaîne et soudain « l’appli est lente ».

Décision : Si la latence DNS est élevée ou incohérente, inspectez le chemin du résolveur (systemd-resolved, upstream DNS, domaines de recherche, retries). Cachez là où c’est approprié et corrigez l’amont.

Task 15: Chronométrer une requête complète : DNS + connect + TLS + premier octet

cr0x@server:~$ curl -sS -o /dev/null -w 'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' https://10.0.0.20/health
dns:0.000 connect:0.003 tls:0.118 ttfb:0.146 total:0.147

Ce que cela signifie : Le handshake TLS domine. Votre « réseau lent » est en réalité du CPU, un manque d’entropie, la taille de la chaîne de certificats, OCSP stapling, ou une terminaison TLS surchargée.

Décision : Si TLS est lent, profilez le point de terminaison : CPU, suites, résumés de session, taille de la chaîne, et si un proxy fait un travail supplémentaire.

Task 16: Vérifier l’attente et la saturation des E/S disque (parce que l’appli écrit quelque part)

cr0x@server:~$ iostat -xz 1 3
Device            r/s     w/s    rkB/s    wkB/s  await  svctm  %util
nvme0n1         120.0   950.0   5200.0  88100.0  24.10   0.70  92.00

Ce que cela signifie : Le disque est ~92% utilisé et l’attente moyenne est de 24ms. Les applis qui attendent le disque auront « l’impression d’un réseau lent » parce que les réponses ne sont pas produites.

Décision : Si %util est élevé et que l’attente augmente pendant les incidents, corrigez la contention de stockage : séparez les charges, ajustez les patterns fsync, ajoutez du cache ou scalez le stockage.

Task 17: Trouver quel processus fait les I/O ou est throttlé

cr0x@server:~$ pidstat -dl 1 5
# Time   UID   PID  kB_rd/s kB_wr/s  iodelay  Command
10:18:01 1001 21422     0.00  8420.00     120  postgres
10:18:01 0     9981     0.00  1200.00      40  fluent-bit

Ce que cela signifie : La base de données et l’agent de logs se concurrencent. Dans la pratique, les logs prennent souvent en premier le budget de latence.

Décision : Si votre journalisation/télémétrie est lourde, rate-limitez-la, sortez-la du chemin critique, ou envoyez-la sur un disque séparé. L’observabilité qui cause des pannes est de l’art, pas de l’ingénierie.

Task 18: Vérifier le throttling CPU des cgroups (commun dans les containers)

cr0x@server:~$ cat /sys/fs/cgroup/system.slice/docker.service/cpu.stat
usage_usec 8922334455
user_usec  6122334400
system_usec 2800000055
nr_periods  238994
nr_throttled 82211
throttled_usec 992233445

Ce que cela signifie : Le service est throttlé. Cela crée des pics de latence, des stalls de connexion et des lenteurs TLS — même si le NIC est correct.

Décision : Augmentez le quota CPU, réduisez le travail CPU par requête, ou rééquilibrez le placement. Si vous throttlez, cessez d’interpréter l’output d’iperf comme la réalité.

Trois mini-récits d’entreprise depuis le terrain

Mini-récit 1 : L’incident causé par une mauvaise supposition

Ils avaient une fenêtre de migration et une checklist. Quelqu’un a lancé iperf3 entre les anciens serveurs d’applis et le nouveau cluster de base de données. Il a saturé la ligne. Ils ont déclaré le réseau « validé » et ont poursuivi.

Lundi matin, la file de tickets s’est remplie de « l’appli gèle pendant 10–30 secondes ». Pas de crash. Pas d’erreur dure. Juste de longues pauses humiliantes. L’équipe réseau montrait les résultats iperf. L’équipe DB montrait des graphes CPU « corrects ». L’équipe applicative a réécrit trois timeouts clients dans la panique et a empiré la situation.

Le vrai problème était un MTU mismatch à travers une frontière VLAN. Le nouveau chemin avait des jumbo frames activées sur un sous-ensemble de ports de switch, tandis qu’un pare-feu au milieu dropait les ICMP « fragmentation needed ». Les petits paquets passaient, d’où un ping correct et pourquoi beaucoup de requêtes fonctionnaient. Certaines tailles de payload déclenchaient l’échec PMTUD et étaient blackholées jusqu’à ce que TCP timeout et essaie des segments plus petits.

iperf semblait excellent parce que le test utilisait un chemin différent (un saut routé direct qui contournait le pare-feu) et parce que le comportement du flux récupérait. L’appli, avec beaucoup de connexions TLS éphémères et quelques réponses plus larges, tombait souvent dans les cas limites cassés.

La correction fut ennuyeuse : MTU cohérent, autoriser les ICMP nécessaires pour PMTUD, et un chemin standard pour les tests. La leçon n’était pas « iperf est mauvais ». La leçon était « l’hypothèse que iperf prouve tout le chemin est un mensonge que vous vous êtes raconté ».

Mini-récit 2 : L’optimisation qui s’est retournée contre eux

Une équipe plateforme voulait réduire l’utilisation CPU sur leurs nœuds Ubuntu 24.04. Le traitement réseau ressortait dans les flamegraphs comme du temps softirq. Quelqu’un a proposé d’activer des offloads plus agressifs et d’augmenter les anneaux NIC « pour ne jamais dropper ». Ça semblait raisonnable. Et c’est parti en production un vendredi, ce qui est un fort indicateur d’optimisme.

L’utilisation CPU a baissé. Succès, non ? Mais le symptôme client — la latence P99 — s’est dégradé. Pas un peu. Des appels qui étaient stables sont devenus spiky et imprévisibles. La direction l’a remarqué parce qu’elle remarque toujours quand on touche à la latence en queue.

Le problème était le bufferbloat classique, mais à l’intérieur de l’hôte. Les anneaux agrandis et les queues plus profondes absorbèrent les bursts au lieu de dropper tôt, donc TCP n’eut pas de signaux de congestion opportuns. Les paquets restèrent plus longtemps en buffer, et les flux interactifs attendirent derrière des transferts bulk. Les graphiques de débit étaient excellents. L’expérience utilisateur ne l’était pas.

Le rollback a immédiatement amélioré le P99. Ensuite ils ont fait la chose mature : ré-appliqué les changements progressivement, mesuré la latence tail, conservé l’équité des files, et ajusté les anneaux juste assez pour que les drops ne soient plus pathologiques.

Petite blague #2 : Rien ne rend un système « rapide » comme bufferiser les requêtes jusqu’à la semaine prochaine.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Un service proche de la finance avait des SLO de latence stricts et la mauvaise habitude de tomber en panne bruyamment en fin de trimestre. L’équipe n’avait pas le temps pour du debugging héros. Ils firent quelque chose de terne : standardiser un runbook de performance « golden » pour chaque classe d’hôte.

Chaque nœud était livré avec la même baseline : MTU cohérent, paramètres qdisc validés, templates d’affinité IRQ par modèle NIC, et un petit ensemble d’exporters « toujours actifs » qui suivaient TcpRetransSegs, softirq CPU, et attente disque. Ils fixèrent aussi le comportement DNS : résolveurs explicites, listes de search courtes, et cache si approprié.

Quand un ralentissement survint, l’astreinte ne débattit pas d’idéologie. Ils comparèrent l’hôte live aux sorties baseline. Un nœud montra une hausse de rx_no_buffer_count et avait une version de noyau différente à cause d’un reboot manqué. C’était tout. Pas de thriller mystérieux.

Ils drainèrent le nœud, redémarrèrent sur le bon noyau, et l’incident prit fin. Le postmortem fut court et un peu embarrassant, ce qui est le meilleur : « nous avions une baseline, nous avons détecté une dérive, nous avons corrigé la dérive ».

La pratique n’était pas excitante. Elle était efficace. La majorité du travail de fiabilité consiste à empêcher votre futur vous d’être surpris.

Erreurs courantes : symptômes → cause → correction

Cette section est où je deviens opiniâtre. Ce sont des schémas qui font perdre des jours parce qu’ils semblent plausibles. Servez-vous en comme test olfactif.

1) « iperf est rapide, donc le réseau est OK »

Symptôme : iperf annonce plusieurs Gbit/s ; l’appli a des latences P95/P99 élevées et des timeouts.

Cause : Vous avez validé le débit pour un petit nombre de flux, pas la perte, le jitter, le queueing ou la latence des dépendances. Le trafic réel emprunte des chemins différents (proxies/NAT/VPN/maillage).

Correction : Re-lancez des tests sur le chemin réel (même VIP, même DNS, même TLS) et mesurez retransmissions, drops qdisc, et temps DNS/TLS. Utilisez des breakdowns curl -w et ss -ti.

2) « L’appli est lente seulement sous charge »

Symptôme : Ça marche à faible trafic, s’effondre pendant les pics ; iperf hors-peak est parfait.

Cause : Queueing et bufferbloat, saturation softirq, épuisement conntrack, ou contention disque sous concurrence réelle.

Correction : Observez pendant le pic. Capturez mpstat, nstat, ethtool -S, tc -s, iostat. Corrigez la ressource la plus serrée : répartition CPU/IRQ, équité qdisc, dimensionnement conntrack, ou isolation stockage.

3) « La perte de paquets est négligeable, donc ça ne peut pas importer »

Symptôme : Perte < 1%, pourtant des stalls et retries visibles par l’utilisateur.

Cause : TCP est sensible à la perte, surtout pour les flux courts et pendant le slow start. Même des drops modestes peuvent gonfler la latence tail.

Correction : Localisez le point de drop : drops d’anneau NIC, drops qdisc, policers de switch, Wi‑Fi/underlay, ou liens sursaturés. Les drops ne se valent pas ; ceux au mauvais moment font plus de dégâts.

4) « On a augmenté les buffers, maintenant c’est stable » (jusqu’à ce que ça ne le soit plus)

Symptôme : Moins de drops, moins d’interactivité, P99 en hausse.

Cause : Trop de buffering cause du délai d’enqueue ; l’équité entre flux se dégrade ; TCP voit la congestion plus tard.

Correction : Préférez l’équité de queue et le drop contrôlé aux buffers profonds. Ajustez les tailles d’anneaux prudemment et mesurez la latence, pas seulement le débit.

5) « C’est le overhead Kubernetes/service mesh » (parfois vrai, souvent paresseux)

Symptôme : iperf sur l’hôte est rapide ; pod-à-pod ou service-à-service est lent.

Cause : MTU overlay mismatch, pression conntrack, scale iptables de kube-proxy, throttling CPU des sidecars, ou voisins bruyants en cgroups.

Correction : Vérifiez MTU bout-en-bout, surveillez la compte conntrack, mesurez le throttling CPU par pod, et confirmez que le test suit le même chemin que le trafic production.

6) « La base de données est lente, mais le réseau est rapide »

Symptôme : Requêtes BD bloquées ; iperf OK ; CPU semble correct.

Cause : Latence de stockage (fsync, WAL, NFS, NVMe saturé), ou contention de verrous qui ressemble à « attente d’octets ».

Correction : Mesurez iostat await, I/O par processus avec pidstat -d, et événements d’attente spécifiques à la base. N’utilisez pas d’outils réseau pour diagnostiquer le stockage.

Listes de vérification / plan étape par étape

Checklist A : Quand quelqu’un dit « iperf est OK »

  1. Demandez : « Qu’est-ce qui est précisément lent ? » Identifiez si c’est le temps de connexion, le TLS, le premier octet ou la réponse totale.
  2. Confirmez le chemin applicatif : nom DNS, VIP, chaîne de proxies, NAT, overlay, zones de pare-feu. Assurez-vous que votre test emprunte le même chemin.
  3. Capturez retransmissions et timeouts : ss -ti, nstat.
  4. Capturez les drops : ethtool -S, tc -s qdisc.
  5. Capturez softirq CPU et distribution IRQ : mpstat, /proc/interrupts.
  6. Capturez la latence stockage : iostat -xz, pidstat -d.
  7. Ce n’est qu’ensuite que vous envisagez le tuning. Si vous touchez au tuning d’abord, vous ne faites que modifier la scène du crime.

Checklist B : Corriger les hotspots IRQ/softirq en sécurité

  1. Vérifiez que RSS est activé et que plusieurs queues existent (ethtool -l si supporté).
  2. Inspectez les interruptions par queue dans /proc/interrupts.
  3. Vérifiez si irqbalance tourne et s’il aide ou nuit à votre charge.
  4. Changez une chose à la fois (affinité ou RPS), puis mesurez la distribution softirq et la latence applicative.
  5. Enregistrez votre configuration finale dans le gestionnaire de configs. La dérive est le tueur silencieux.

Checklist C : Valider MTU bout-en-bout

  1. Confirmez l’MTU des interfaces sur tous les hôtes participants (ip link show).
  2. Sondez avec ping -M do à la taille attendue.
  3. Si overlay/VPN existe, tenez compte de l’overhead d’encapsulation et réduisez l’MTU intérieur en conséquence.
  4. Assurez-vous que les messages ICMP nécessaires pour PMTUD ne sont pas bloqués par votre politique de sécurité.
  5. Retestez le comportement applicatif (handshakes TLS, grandes réponses) après les changements.

Checklist D : Quand ça sent le DNS

  1. Chronométrez les résolutions avec resolvectl query pendant l’incident.
  2. Vérifiez si les domaines de recherche provoquent des NXDOMAIN répétés.
  3. Contrôlez la santé des upstreams résolveurs et si le cache est efficace.
  4. Confirmez que l’appli ne fait pas de résolutions par requête à cause d’un manque de pooling ou d’une mauvaise config client.

FAQ

1) Si iperf est rapide, le réseau peut-il quand même être en cause ?

Oui. iperf prouve surtout la bande passante sous un schéma de flux précis. Votre problème peut venir de la perte, du jitter, du délai d’enqueue, de PMTUD, de policers, ou d’un chemin différent impliquant NAT/proxies.

2) Dois-je lancer iperf avec plus de flux parallèles ?

Souvent, oui. Utilisez -P pour imiter la concurrence de connexions. Si de nombreux flux sont rapides mais qu’un seul est lent, suspectez des contraintes par flux (perte, policers, MTU, contrôle de congestion).

3) Quel est l’indicateur le plus rapide que des paquets sont perdus ?

La montée des retransmissions dans ss -ti et nstat, plus des compteurs NIC comme rx_no_buffer_count ou des drops qdisc dans tc -s. Les pertes n’apparaissent pas toujours dans un ping.

4) Pourquoi je vois un softirq élevé et l’appli ralentit ?

Le softirq est l’endroit où le noyau traite les paquets. S’il est concentré sur un seul cœur (fréquent avec une mauvaise distribution IRQ/RSS), vos threads applicatifs se disputent le CPU et subissent des délais. Répartissez interruptions et steering de paquets sur plusieurs CPU.

5) Augmenter les buffers NIC est-ce une bonne idée ?

Parfois. Cela peut réduire les drops lors de bursts, mais aussi augmenter la latence en bufferisant davantage. Si votre SLO est la latence, ajustez prudemment et mesurez le P99 avant/après.

6) Comment le DNS peut-il ralentir mon « réseau » ?

Chaque lookup est une dépendance réseau avec timeouts et retries. Dans les microservices, les requêtes DNS se retrouvent souvent sur le chemin critique plus fréquemment qu’on ne l’avoue. Chronométrez avec resolvectl et détaillez le timing des requêtes avec curl -w.

7) Le stockage peut-il être le goulot même si les clients se plaignent de « réponses lentes » ?

Absolument. Si le serveur ne peut pas lire ou écrire rapidement, il ne peut pas répondre rapidement. Vérifiez iostat await et %util, puis identifiez les processus qui causent les I/O.

8) Pourquoi ça n’arrive que dans des containers ou Kubernetes ?

Les containers ajoutent des limites cgroup, des réseaux overlay, et souvent des chemins lourds en conntrack. Throttling CPU, overhead MTU et épuisement conntrack sont courants. Mesurez le throttling et le comptage conntrack directement.

9) Dois-je désactiver les offloads (TSO/GRO/LRO) pour « corriger la latence » ?

Pas en premier lieu. Désactiver les offloads augmente souvent l’usage CPU et peut empirer la latence tail sous charge. Changez les offloads seulement si vous avez une preuve d’un bug driver/firmware ou d’une interaction spécifique.

10) Que faire si iperf est rapide, ping est OK, et tout de même tout se fige ?

Regardez la « plomberie » : temps de handshake TLS, DNS, conntrack, files accept/backlog, et extinctions de pool applicatifs (connexions BD, pools de threads). Les outils réseau ne révèlent pas toujours ces éléments directement.

Conclusion : prochaines étapes réalisables aujourd’hui

Si vous retenez une chose du cas n°24, que ce soit celle-ci : le débit n’est pas l’expérience utilisateur. iperf est un instrument grossier ; votre appli est un organisme pointilleux qui se soucie de la queue.

Faites ceci ensuite, dans cet ordre :

  1. Capturez un seul « slow request » détaillé (curl -w ou timing applicatif) pour identifier si la douleur vient du DNS, de la connexion, du TLS, ou du temps serveur.
  2. Pendant l’incident, collectez quatre snapshots : mpstat, ss -ti, nstat, iostat. Ceux-ci suffisent généralement à dire quel sous-système ment.
  3. Si softirq/IRQs sont chauds, corrigez la distribution avant d’ajuster les buffers.
  4. Si les retransmissions/timeouts augmentent, chassez les drops et les problèmes MTU bout-en-bout.
  5. Si l’attente stockage est élevée, arrêtez de blâmer le réseau et allez avoir la conversation inconfortable « le disque est en feu ».
  6. Consignez une baseline et faites-la respecter. Le meilleur incident est celui que vous terminez en comparant des sorties, pas en improvisant.
Suivant →
LGA vs PGA : pourquoi les broches ont migré vers la carte mère

Laisser un commentaire