Ubuntu 24.04 : Déconnexions aléatoires — diagnostiquer les pertes NIC et les offloads sans superstition

Cet article vous a aidé ?

Les déconnexions aléatoires sur un serveur sont une douleur particulière : rien n’est « down » assez longtemps pour appeler l’équipe réseau, mais tout est cassé assez longtemps pour vous faire paraître peu fiable. SSH se fige. Les RPC expirent. Les montages de stockage se bloquent comme s’ils réfléchissaient à leur existence. Et quand vous vous connectez, le lien est « correct ».

C’est là que naît la superstition. On coupe les offloads comme on éteint une lumière hantée. On redémarre. On accuse les « mises à jour Ubuntu ». Vous pouvez faire mieux. L’objectif n’est pas de trouver un sysctl magique. L’objectif est de prouver où les paquets sont perdus : sur le câble, sur le commutateur, dans la NIC, dans le pilote, dans le chemin de réception du noyau, ou dans votre configuration.

Un modèle mental opérationnel : où les « déconnexions » se produisent réellement

La plupart des « déconnexions aléatoires » ne sont pas des déconnexions. Ce sont des pertes transitoires, des réordonnancements, des blocages ou de brèves renégociations du lien que votre application interprète comme une défaillance. Il faut séparer les modes de défaillance :

  • Flaps de lien : le lien physique bascule down/up (câble, SFP, port de commutateur, autoneg). Linux l’enregistrera souvent clairement.
  • Réinitialisations pilote/NIC : le périphérique reste « up » mais le pilote réinitialise les files, le firmware ou le DMA. Cela ressemble à un clignotement ; les logs peuvent être subtils.
  • Surcharge du chemin de réception : le lien est up, mais les anneaux RX débordent ou le softnet backlog laisse tomber des paquets. Aucune erreur physique n’est requise.
  • Interactions offload/caractéristiques : checksum offload, GRO/LRO, TSO/GSO, offload VLAN ou XDP peuvent créer des comportements étranges avec certains commutateurs, tunnels ou révisions de NIC.
  • Trous noirs PMTU : le lien est ok ; la découverte PMTU ne l’est pas. Certains flux se bloquent ; les pings « fonctionnent ».
  • Comportement erratique de bonding/LACP/VLAN/bridge : vous avez construit quelque chose d’ingénieux et maintenant ça mange parfois des paquets.

Votre travail est d’étiqueter correctement l’événement. Une fois fait, la correction devient franchement simple.

Idée paraphrasée (avec attribution) : John Allspaw soutient depuis longtemps que la fiabilité vient du traitement des opérations comme une science des preuves, pas comme un théâtre du blâme.

Playbook de diagnostic rapide (premier/second/troisième)

Quand vous êtes d’astreinte, vous n’avez pas le temps d’admirer des graphes de paquets. Commencez ici. L’objectif est de déterminer quel niveau vous trompe.

Premier : confirmer s’il s’agit d’un flap de lien, d’une réinitialisation du pilote, ou d’une congestion/perte

  1. Journaux noyau autour de la fenêtre d’événement : lien down/up vs reset vs timeout de file.
  2. Compteurs NIC : les erreurs CRC et d’alignement hurlent physique ; rx_missed_errors et rx_no_buffer hurlent anneaux/interruptions.
  3. Softnet drops : si le noyau fait tomber avant que votre app voie les paquets, vous le trouverez ici.

Second : isoler la « bizarrerie d’offload » du « véritable problème de capacité »

  1. Vérifiez l’état des offloads et les versions pilote/firmware.
  2. Reproduisez avec un test de trafic contrôlé (même un iperf3 basique) et surveillez les compteurs.
  3. Si désactiver un offload « corrige » le problème, prouvez pourquoi : les compteurs changent, les resets cessent, ou un empaquetage particulier cesse de casser.

Troisième : validez commutateur, optiques et câblage comme un adulte

  1. Cherchez les erreurs FEC/CRC, erreurs de symbole et renégociations aux deux extrémités.
  2. Échangez optiques/câble pour éliminer le physique. Ce n’est pas glamour, mais c’est rapide.
  3. Confirmez les paramètres LACP du partenaire et le MTU bout en bout.

Règle de décision : Si l’OS montre lien down/up, commencez par le physique et la configuration du port du commutateur. Si le lien reste up mais que les compteurs augmentent et que les softnet drops explosent, ajustez l’hôte. Si la NIC se réinitialise, regardez pilote/firmware et santé d’alimentation/PCIe.

Faits et contexte que vous voudrez connaître plus tôt

  • Fait 1 : Les « erreurs de checksum » dans des captures peuvent être des artefacts : avec le TX checksum offload, les paquets peuvent sembler incorrects sur l’hôte avant que la NIC ne les corrige sur le câble.
  • Fait 2 : GRO (Generic Receive Offload) dans Linux est un mécanisme logiciel ; LRO est piloté par la NIC et historiquement plus susceptible de mal se comporter avec les tunnels et certains motifs de trafic.
  • Fait 3 : La pile réseau Linux a le RSS depuis longtemps, mais l’affectation des files aux cœurs CPU reste une source fréquente d’auto-sabotage sur les systèmes multi-socket.
  • Fait 4 : Beaucoup de « pertes aléatoires » attribuées aux noyaux étaient en réalité des micro-bursts sur le commutateur : des pics courts qui débordent les buffers plus vite que votre intervalle de monitoring ne le montre.
  • Fait 5 : Energy Efficient Ethernet (EEE) a une longue histoire d’être « bien en théorie » et « mystérieusement instable en pratique » sur du matériel multi-fournisseur.
  • Fait 6 : Sur les NIC modernes, le firmware fait partie de votre surface de fiabilité. Une mise à jour du pilote sans mise à jour du firmware peut vous laisser avec de nouveaux bugs et un microcode ancien.
  • Fait 7 : Les disputes d’autonégociation ne sont pas un vestige des années 1990. Elles apparaissent aujourd’hui via des DACs défectueux, des optiques marginales ou des réglages forcés d’un côté.
  • Fait 8 : Le bonding (LACP) est robuste, mais seulement si les deux côtés s’accordent sur le hashing, le mode LACP et la définition de « up ». Sinon il échoue de manière délicieusement intermittente.
  • Fait 9 : Les trous noirs PMTU restent fréquents parce que le filtrage ICMP est encore traité comme une « sécurité », alors qu’il agit souvent comme un « générateur de pannes aléatoires ».

Tâches pratiques (commandes + signification + décision)

Ci‑dessous les tâches terrain que vous pouvez exécuter sur Ubuntu 24.04. Chaque commande inclut ce que la sortie signifie et ce que vous devez faire ensuite. Copier/coller est autorisé. Les vibes ne le sont pas.

Task 1: Identify the NIC, driver, and firmware you’re actually running

cr0x@server:~$ sudo ethtool -i eno1
driver: ixgbe
version: 6.8.0-31-generic
firmware-version: 0x800003e7
expansion-rom-version:
bus-info: 0000:3b:00.0
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

Signification : Vous avez maintenant un tuple précis : version du noyau, nom du pilote, version du firmware, bus PCI. Ce tuple est ce que vous corrélez avec les réinitialisations et les bizarreries connues. « Intel 10G » n’est pas un tuple.

Décision : Si les déconnexions coïncident avec des mises à jour récentes du noyau, conservez cette sortie dans les notes d’incident. Si le firmware est très ancien par rapport à votre flotte, planifiez une mise à jour du firmware. Si le pilote est inclus dans le noyau mais que le vendeur recommande un pilote externe plus récent, considérez cela comme une hypothèse, pas une religion.

Task 2: Check for link flaps and driver resets in the kernel log

cr0x@server:~$ sudo journalctl -k --since "2 hours ago" | egrep -i "eno1|link is|down|up|reset|watchdog|tx timeout|nic"
[ 7432.112233] ixgbe 0000:3b:00.0 eno1: NIC Link is Down
[ 7435.556677] ixgbe 0000:3b:00.0 eno1: NIC Link is Up 10 Gbps, Flow Control: RX/TX
[ 8121.000111] ixgbe 0000:3b:00.0 eno1: Detected Tx Unit Hang
[ 8121.000222] ixgbe 0000:3b:00.0 eno1: Reset adapter

Signification : La première paire est un vrai flap de lien. Les lignes suivantes indiquent un blocage Tx détecté et une réinitialisation du pilote/NIC — une catégorie différente de problème.

Décision : L’apparition lien down/up vous oriente vers optiques/câble/port du commutateur/autoneg/EEE. Un Tx hang/reset vous oriente vers pilote/firmware/PCIe/gestion d’alimentation et le comportement des files/interruptions.

Task 3: Watch live link state and negotiated parameters

cr0x@server:~$ sudo ethtool eno1 | egrep -i "Speed|Duplex|Auto-negotiation|Link detected"
Speed: 10000Mb/s
Duplex: Full
Auto-negotiation: on
Link detected: yes

Signification : C’est votre référence. Si vous voyez la vitesse basculer (10G vers 1G) ou l’autoneg désactivé d’un côté, vous avez un problème de configuration ou physique.

Décision : Si les flaps coïncident avec des renégociations ou des changements de vitesse, arrêtez de bidouiller les offloads. Parlez au commutateur et échangez les composants.

Task 4: Pull NIC counters that reveal physical vs host drops

cr0x@server:~$ sudo ethtool -S eno1 | egrep -i "crc|align|symbol|discard|drop|miss|overrun|timeout" | head -n 30
rx_crc_errors: 0
rx_align_errors: 0
rx_symbol_err: 0
rx_discards: 124
rx_dropped: 0
rx_missed_errors: 98765
tx_timeout_count: 3

Signification : Les erreurs CRC/align/symbol indiquent une corruption de la couche physique. rx_missed_errors indique généralement que la NIC n’a pas pu DMA les paquets dans les buffers hôtes assez vite (étoffement d’anneau / modulation d’interruption / ordonnancement CPU).

Décision : Si les erreurs physiques sont non nulles et augmentent pendant les incidents, traitez-le comme un problème de câble/optique/port de commutateur. Si les missed errors augmentent tandis que les erreurs physiques restent nulles, concentrez-vous sur les anneaux RX, IRQ, NAPI et la contention CPU.

Task 5: Inspect softnet drops (kernel dropping before the socket layer)

cr0x@server:~$ awk '{print NR-1, $1, $2, $3, $4, $5}' /proc/net/softnet_stat | head
0 0000001a 00000000 0000003f 00000000 00000000
1 00000020 00000000 00000110 00000000 00000000

Signification : Le champ 1 est les paquets traités, le champ 2 est les paquets perdus (en hex), le champ 3 est time_squeeze. Les drops/time_squeeze indiquent que le CPU/softirq n’a pas pu suivre.

Décision : Si les drops augmentent pendant les déconnexions, il ne s’agit pas d’un « mystère ». Vous êtes face à une surcharge ou à un mauvais placement CPU/IRQ. Passez aux tâches IRQ/RSS.

Task 6: Confirm whether NIC interrupts are mapped sensibly

cr0x@server:~$ grep -i eno1 /proc/interrupts | head -n 10
  98:  12345678   0   0   0  IR-PCI-MSI 524288-edge  eno1-TxRx-0
  99:         12   0   0   0  IR-PCI-MSI 524289-edge  eno1-TxRx-1
 100:         10   0   0   0  IR-PCI-MSI 524290-edge  eno1-TxRx-2

Signification : La file 0 fait tout le travail tandis que les autres files sont inactives. Cela peut arriver à cause d’un mauvais RSS, du type de flux, ou d’un problème d’affectation.

Décision : Si une file est chaude et les autres froides, corrigez RSS/nombre de files et envisagez l’affinité IRQ. Si l’hôte est multi-socket, assurez-vous que les files NIC se trouvent sur des cœurs NUMA locaux.

Task 7: Check RSS and number of combined channels

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

Signification : Cette NIC supporte jusqu’à 64 files combinées, actuellement configurée pour 8. Ce n’est pas « mauvais », mais cela doit correspondre à vos cœurs CPU et à la charge.

Décision : Si vous voyez des missed errors ou des softnet drops et que vous avez des ressources CPU disponibles, augmenter les channels combinés peut aider. Si vous êtes déjà CPU-bound, plus de files peuvent ajouter de l’overhead. Ajustez délibérément.

Task 8: Change channel count (temporarily) to test a hypothesis

cr0x@server:~$ sudo ethtool -L eno1 combined 16
cr0x@server:~$ sudo ethtool -l eno1 | tail -n +1
Channel parameters for eno1:
Pre-set maximums:
RX:		0
TX:		0
Other:		0
Combined:	64
Current hardware settings:
RX:		0
TX:		0
Other:		0
Combined:	16

Signification : Vous avez augmenté le parallélisme des files. Si les pertes disparaissent sous charge, vous avez trouvé un goulot d’étranglement de réception. Si la latence s’aggrave et que le CPU monte, vous en avez trop fait.

Décision : Ne conservez la modification que si vous pouvez prouver l’amélioration via compteurs et symptômes applicatifs. Rendez-la persistante via des hooks systemd-networkd/NetworkManager ou des règles udev, pas en espérant qu’elle survive au redémarrage.

Task 9: Check offload features currently enabled

cr0x@server:~$ sudo ethtool -k eno1 | egrep -i "rx-checksumming|tx-checksumming|tso|gso|gro|lro|rx-vlan-offload|tx-vlan-offload|ntuple"
rx-checksumming: on
tx-checksumming: on
tcp-segmentation-offload: on
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: off
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off

Signification : GRO/TSO/GSO/checksum offloads sont activés. LRO est désactivé (souvent une bonne valeur par défaut). L’offload VLAN est activé.

Décision : Ne désactivez pas tout « pour être sûr ». Désactivez une seule fonctionnalité à la fois, uniquement pour valider une interaction suspectée. Si vous désactivez le checksum, attendez‑vous à une augmentation CPU et possiblement à un débit réduit ; vous échangez des hypothèses de correction contre un coût mesurable.

Task 10: Toggle a single offload to test for a bug (and watch counters)

cr0x@server:~$ sudo ethtool -K eno1 gro off
cr0x@server:~$ sudo ethtool -k eno1 | grep -i generic-receive-offload
generic-receive-offload: off

Signification : GRO est désactivé. Si votre problème est lié à GRO (souvent avec tunnels/encapsulation ou certaines combinaisons NIC/pilote boguées), les symptômes peuvent changer rapidement.

Décision : Si désactiver GRO élimine les blocages mais augmente le CPU et réduit le débit, vous avez probablement trouvé une limite du noyau/du pilote. Alors soit (a) vous laissez GRO off pour cette interface, (b) vous changez noyau/pilote/firmware, ou (c) vous repensez l’encapsulation. Choisissez selon les contraintes métier, pas par orgueil.

Task 11: Check MTU and whether you’re accidentally fragmenting or blackholing

cr0x@server:~$ ip -br link show eno1
eno1             UP             10.10.0.12/24 fe80::1234:56ff:fe78:9abc/64
cr0x@server:~$ ip link show eno1 | egrep -i "mtu|state"
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP mode DEFAULT group default qlen 1000

Signification : Le MTU est 9000. Si votre chemin de commutateur ou le pair est en 1500, vous avez maintenant une panne intermittente reproductible : les petits paquets fonctionnent, les gros se bloquent ou fragmentent bizarrement, et le « aléatoire » devient une tendance.

Décision : Validez le MTU bout en bout. Pour les tunnels, souvenez‑vous qu’il y a un overhead. Si vous ne pouvez pas garantir les jumbo frames sur tout le chemin, ne les activez pas à moitié.

Task 12: PMTU test with “do not fragment” ping

cr0x@server:~$ ping -M do -s 8972 -c 3 10.10.0.1
PING 10.10.0.1 (10.10.0.1) 8972(9000) bytes of data.
From 10.10.0.12 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.10.0.12 icmp_seq=2 Frag needed and DF set (mtu = 1500)
From 10.10.0.12 icmp_seq=3 Frag needed and DF set (mtu = 1500)

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

Signification : Le chemin ne peut pas transporter des trames de 9000 octets. Ce n’est pas subtil. Votre MTU d’interface est supérieur à ce que le chemin supporte.

Décision : Corrigez le mismatch MTU. Soit réglez MTU à 1500 sur l’hôte, soit activez les jumbo frames de bout en bout (y compris bonds, bridges, sous‑interfaces VLAN et ports du commutateur).

Task 13: Check TCP retransmits and kernel network stats

cr0x@server:~$ nstat -az | egrep -i "TcpRetransSegs|TcpTimeouts|IpInDiscards|IpOutDiscards"
IpInDiscards                    120
IpOutDiscards                   0
TcpTimeouts                     18
TcpRetransSegs                  3490

Signification : Les retransmissions et timeouts confirment une vraie perte/blocage vécue par TCP, pas seulement des plaintes applicatives. Les discard IP suggèrent des pertes en couche supérieure.

Décision : Si les retransmissions montent pendant les incidents alors que le lien reste up, corrélez avec softnet drops, missed errors NIC et buffers de port du commutateur. Ensuite choisissez : tuning hôte ou remédiation réseau.

Task 14: Confirm if NetworkManager/systemd-networkd is bouncing the interface

cr0x@server:~$ systemctl status NetworkManager --no-pager
● NetworkManager.service - Network Manager
     Loaded: loaded (/usr/lib/systemd/system/NetworkManager.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-12-29 09:12:10 UTC; 3h 2min ago
       Docs: man:NetworkManager(8)
cr0x@server:~$ sudo journalctl -u NetworkManager --since "2 hours ago" | egrep -i "eno1|carrier|down|up|deactivat|activat"
Dec 29 10:41:12 server NetworkManager[1023]: <info>  [....] device (eno1): carrier: link connected
Dec 29 10:41:13 server NetworkManager[1023]: <info>  [....] device (eno1): state change: activated -> deactivating (reason 'carrier-changed')
Dec 29 10:41:14 server NetworkManager[1023]: <info>  [....] device (eno1): state change: deactivating -> activated (reason 'carrier-changed')

Signification : Le carrier change ; NM réagit. Cela reflète généralement un événement de lien réel, pas NM qui devient « aléatoire ».

Décision : Ne vous battez pas contre le network manager. Réglez l’instabilité du carrier (physique/commutateur) ou les réinitialisations de pilote qui déclenchent les changements de carrier.

Task 15: Validate PCIe health hints (AER errors can look like “random NIC problems”)

cr0x@server:~$ sudo journalctl -k --since "24 hours ago" | egrep -i "AER|pcieport|Corrected error|Uncorrected|DMAR|IOMMU" | head -n 30
[ 8120.998877] pcieport 0000:3a:00.0: AER: Corrected error received: 0000:3a:00.0
[ 8120.998900] pcieport 0000:3a:00.0: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)

Signification : Les erreurs PCIe corrigées peuvent précéder des incidents de périphérique ou des réinitialisations, surtout sous charge ou avec des slots/risers marginaux.

Décision : Si les logs AER corrèlent avec des réinitialisations NIC, arrêtez de débattre sur GRO et commencez à vérifier l’hôte physique : emplacement, risers, gestion d’alimentation PCIe BIOS, et firmware plateforme.

Offloads sans superstition : quand ils aident, quand ils nuisent

Les offloads ne sont pas maléfiques. Ce sont des fonctionnalités de performance conçues pour transférer du travail du CPU vers la NIC (ou pour amortir le travail dans le noyau). Ils sont aussi un bouc émissaire fréquent parce que les désactiver est facile et que les symptômes sont intermittents. Le fait qu’un toggle change le symptôme ne signifie pas que vous avez compris la cause.

Connaître ce que vous basculez

  • TX checksum offload : le noyau transmet un paquet avec checksum « à remplir » ; la NIC calcule le checksum. Les captures sur l’hôte peuvent montrer un « mauvais checksum » parce qu’il n’a pas encore été calculé.
  • TSO/GSO : de grands segments TCP créés par la pile et segmentés plus tard (NIC ou noyau). Excellents pour le débit ; peuvent amplifier la rafale.
  • GRO : coalescence des paquets reçus en SKBs plus gros avant de les passer à la pile. Économise du CPU ; peut modifier les caractéristiques de latence.
  • LRO : concept similaire mais piloté par la NIC ; peut interagir mal avec l’encapsulation et casser plus facilement la sémantique des paquets.
  • Offloads VLAN : la NIC gère les opérations de tag VLAN ; généralement ok, parfois problématique avec le bridging ou des comportements étranges de commutateur.

Voici l’approche adulte : traitez les offloads comme des variables d’expérience. Basculez-en un, mesurez les compteurs, mesurez les symptômes applicatifs, et décidez si vous avez trouvé un bug réel ou simplement déplacé le goulot.

Quand désactiver un offload est approprié

Désactivez un offload temporairement quand :

  • Vous avez des preuves de réinitialisations de pilote corrélées à une fonctionnalité (par ex. Tx hang avec TSO sous un trafic spécifique).
  • Vous déboguez des captures et avez besoin que les checksums sur l’hôte soient significatifs.
  • Vous traitez l’encapsulation/tunneling (VXLAN/Geneve) et soupçonnez un chemin offload cassé sur cette NIC/pilote.

Et gardez‑le désactivé seulement si vous ne pouvez pas mettre à jour pilote/firmware/noyau à temps et que le coût CPU est acceptable.

Quand désactiver les offloads est du cargo cult

Désactiver les offloads est du cargo cult quand :

  • Le problème est un lien down/up (les offloads ne font pas flapper votre câble).
  • Des erreurs CRC RX sont non nulles (le checksum offload ne crée pas d’erreurs CRC sur le câble).
  • Les softnet drops sont le vrai problème (désactiver les offloads augmente souvent le travail CPU et aggrave la situation).

Blague #1 : Désactiver tous les offloads, c’est comme enlever les piles du détecteur de fumée parce qu’il est bruyant. Le feu gagne toujours.

IRQs, RSS, ring buffers, et le piège des « drops sans erreurs »

L’un des schémas de déconnexion les plus courants sur les NIC rapides est : le lien est stable, pas d’erreurs CRC, le commutateur semble propre, mais les applications rapportent des timeouts. En coulisses, l’hôte laisse tomber des paquets parce qu’il ne peut pas servir les interruptions et vider les anneaux assez vite. Ce n’est pas théorique ; c’est ce qui arrive quand une NIC 10/25/40/100G rencontre un CPU occupé à faire littéralement autre chose.

Ce que signifient généralement « rx_missed_errors » et « rx_no_buffer »

Ces compteurs signifient typiquement que la NIC avait des trames à livrer mais n’a pas pu les mettre en mémoire hôte parce que l’anneau de réception était plein ou que les buffers n’étaient pas disponibles. Causes possibles :

  • Trop peu de descripteurs RX (taille d’anneau trop petite pour les rafales).
  • Modulation des interruptions trop agressive (les paquets s’entassent, puis débordent).
  • Épuisement CPU du ksoftirqd/contexte softirq.
  • Mauvaise affinité IRQ (toutes les files épinglées sur un CPU, souvent CPU0).
  • Inadéquation NUMA (interruptions NIC traitées sur un socket distant).

Tailles d’anneaux : un outil brutal mais efficace

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

Signification : Vous utilisez 512 descripteurs alors que la NIC supporte 4096. Ce n’est pas incorrect, mais ce n’est pas résilient aux rafales.

Décision : Si vous voyez des rafales/microbursts et des missed errors, augmentez les anneaux à quelque chose de raisonnable (par ex. 2048) et mesurez l’impact mémoire et la latence.

cr0x@server:~$ sudo ethtool -G eno1 rx 2048 tx 2048

Signification : Vous avez augmenté la capacité de buffering à la frontière de la NIC. Cela peut réduire les pertes pendant les rafales, au prix d’une latence tamponnée et d’un usage mémoire supérieur.

Décision : Si votre problème est des pertes dues à des microbursts, cela aide souvent rapidement. Si le problème est une surcharge soutenue, cela ne fait que retarder l’inévitable.

Interrupt moderation : le compromis latence/CPU que personne ne documente dans votre organisation

La coalescence des interruptions réduit le coût CPU en groupant les interruptions. Mais si vous coalescez trop, vous pouvez introduire des pics de latence et créer un débordement d’anneau pendant les rafales.

cr0x@server:~$ sudo ethtool -c eno1 | head -n 40
Coalesce parameters for eno1:
Adaptive RX: on  TX: on
rx-usecs: 50
rx-frames: 64
tx-usecs: 50
tx-frames: 64

Signification : La coalescence adaptative est activée, avec des seuils microsecondes/frames de base. Les modes adaptatifs peuvent être excellents, ou osciller sous certaines charges.

Décision : Si vous chassez des blocages brefs, envisagez de désactiver la coalescence adaptative temporairement et de définir des valeurs fixes conservatrices. Mesurez la latence de queue et les pertes. N’« optimisez » pas dans le noir.

IRQ affinity : quand le défaut c’est « l’espoir »

Ubuntu peut exécuter irqbalance qui tente de distribuer les interruptions. Parfois ça marche. Parfois votre charge est sensible et vous voulez un placement déterministe, surtout sur les systèmes NUMA.

cr0x@server:~$ systemctl status irqbalance --no-pager
● irqbalance.service - irqbalance daemon
     Loaded: loaded (/usr/lib/systemd/system/irqbalance.service; enabled; preset: enabled)
     Active: active (running) since Mon 2025-12-29 09:12:12 UTC; 3h 1min ago

Signification : irqbalance est actif. C’est bien, mais pas toujours optimal.

Décision : Si vous voyez une file chaude ou des interruptions NUMA distantes, envisagez d’épingler les IRQ NIC sur des CPUs locaux et d’exclure ces CPUs des voisins bruyants. C’est important sur les serveurs de stockage et les hyperviseurs.

Blague #2 : Le tuning IRQ, c’est comme l’aménagement de bureau : tout le monde convient que ça compte, et tout le monde déteste la réunion où on change ça.

Linux est souvent accusé parce que ses logs sont lisibles et les logs du commutateur sont derrière un ticket. Pourtant, la couche physique et le commutateur sont des coupables courants. Surtout quand la panne est intermittente.

Indicateurs physiques qui doivent clore le débat « c’est le noyau »

  • Erreurs CRC/alignement/symbole qui augmentent pendant les incidents.
  • Corrections FEC qui montent en flèche (commun sur les vitesses élevées ; une forte correction peut précéder des pertes).
  • Boucles d’autonégociation visibles comme des liens down/up répétés.
  • Renégociation de vitesse/duplex ou surprises « link is up 1Gbps ».

Côté hôte vous ne voyez pas toujours les détails FEC, mais suffisamment pour justifier une escalade.

EEE et gestion d’alimentation : la mort par défauts « verts »

Si vous observez des micro‑pannes périodiques et que tout le reste semble propre, vérifiez si Energy Efficient Ethernet (EEE) est activé. Le matériel mixte peut mal se comporter.

cr0x@server:~$ sudo ethtool --show-eee eno1
EEE Settings for eno1:
EEE status: enabled - active
Tx LPI: 1 (on)
Supported EEE link modes:  1000baseT/Full 10000baseT/Full
Advertised EEE link modes:  1000baseT/Full 10000baseT/Full
Link partner advertised EEE link modes:  1000baseT/Full 10000baseT/Full

Signification : EEE est actif. Ce n’est pas automatiquement mauvais, mais c’est une variable commune dans la latence intermittente et les courts blocages.

Décision : Si vous suspectez EEE, désactivez‑le aux deux extrémités pour une fenêtre de test et observez si les blocages disparaissent.

cr0x@server:~$ sudo ethtool --set-eee eno1 eee off

Bonding et LACP : fiable quand bien configuré, chaotique quand présumé

Les pannes de bonding ressemblent souvent à des déconnexions aléatoires parce que le hashing envoie certains flux sur un chemin cassé tandis que d’autres réussissent. Vous verrez « certains services instables » plutôt que « hôte down ».

cr0x@server:~$ cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v6.8.0-31-generic

Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer3+4 (1)
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0

Slave Interface: eno1
MII Status: up
Aggregator ID: 2
Actor Churn State: churned
Partner Churn State: churned

Slave Interface: eno2
MII Status: up
Aggregator ID: 1
Actor Churn State: churned
Partner Churn State: churned

Signification : Les états churned indiquent une instabilité dans la négociation LACP. Ce n’est pas un problème d’offload Linux ; c’est un problème du plan de contrôle d’agrégation de lien.

Décision : Impliquez l’équipe commutateur avec ces preuves. Vérifiez le mode LACP (active/passive), le trunking VLAN, et que les deux liens terminent le même groupe LACP. Confirmez aussi les timers et que le commutateur ne bloque pas silencieusement un membre à cause d’erreurs.

Trois mini-récits d’entreprise (anonymisés, douloureusement plausibles)

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Une entreprise de taille moyenne exploitait un cluster de stockage objet interne sur des serveurs Ubuntu. Le symptôme était « déconnexions aléatoires » entre nœuds passerelle et nœuds back-end. Ça se produisait surtout pendant les heures de bureau, ce qui rendait tout le monde soupçonneux de la « charge » mais personne n’avait le courage de la quantifier.

La première hypothèse était classique : « C’est une régression du noyau. » L’équipe était récemment passée à un noyau plus récent et à un pilote NIC plus récent, et le timing semblait coupable. Ils ont roll­backé deux hôtes. Le problème a persisté. Ils ont roll­backé deux autres. Toujours présent. Maintenant ils avaient une flotte mixte avec un comportement incohérent et pas de cause racine. La fiabilité ne s’est pas améliorée ; il est juste devenu plus difficile de raisonner.

Quand quelqu’un a finalement regardé les compteurs ethtool -S, ils ont remarqué que rx_crc_errors n’était pas zéro. C’était petit, mais il augmentait exactement pendant les plaintes de « déconnexion ». Cela a brisé la narrative. Les erreurs CRC ne viennent pas des sysctls. Les erreurs CRC viennent de la couche physique.

La cause réelle était douloureusement banale : un lot de câbles DAC marginal à 10G dans une configuration de rack spécifique avec des coudes serrés et des connecteurs stressés. Sous variation de température les erreurs montaient, LACP churnait, et certains flux étaient blackholés assez longtemps pour casser des sessions de stockage. La correction a été de remplacer les câbles et de réinstaller les optiques. Le rollback du noyau a été annulé plus tard, après que tout le monde ait arrêté de flipper.

La leçon n’était pas « vérifiez les câbles ». La leçon était : ne partez pas de la théorie la plus émotionnellement satisfaisante. Commencez par les compteurs qui peuvent la falsifier.

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

Une équipe SaaS avait un problème de latence sur une couche API, et quelqu’un a décidé que le taux d’interruptions NIC était « trop élevé ». Ils ont activé une coalescence d’interruptions agressive et l’ont réglée jusqu’à ce que les graphes CPU paraissent plus calmes. Ils se sont réjouis. L’utilisation CPU a chuté. Ils ont écrit un court billet interne sur leur « succès ».

Deux semaines plus tard, des clients ont signalé des freezes occasionnels de 1–2 secondes pendant les pics de trafic. Ça n’apparaissait pas dans la latence moyenne, seulement dans la latence de queue. Les retransmissions ont augmenté légèrement, mais pas assez pour déclencher les alertes existantes. Le service avait l’air sain dans la plupart des tableaux de bord, ce qui est précisément le refuge de la latence de queue : elle se cache dans les moyennes comme un pro.

Sur les hôtes affectés, rx_missed_errors a lentement augmenté. Les softnet drops ont explosé pendant les microbursts. La NIC n’était pas « trop interruptive ». Elle faisait son travail. Les nouveaux réglages de coalescence retardaient le traitement RX juste assez pour que les buffers d’anneau débordent pendant les brèves rafales. L’optimisation a marché pour les graphes CPU et a échoué pour les utilisateurs.

La correction a été de revenir à la coalescence adaptative avec des bornes conservatrices et d’augmenter modestement la taille des anneaux RX. Ils ont aussi ajouté du monitoring sur les softnet drops et les missed errors NIC, parce que « j’ai réduit les interruptions » n’est pas un SLO orienté utilisateur.

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

Une organisation liée à la finance exploitait des hyperviseurs KVM Ubuntu 24.04 hébergeant des charges critiques internes. Des rapports de déconnexion aléatoire sont venus de plusieurs locataires : brèves pertes de paquets, blocages TCP occasionnels, rien de cohérent. L’équipe réseau était prête à accuser le switching virtuel. L’équipe plateforme était prête à accuser les ToR. Tout le monde était prêt à accuser tout le monde.

Ce qui les a sauvés n’a pas été un génie. Cela a été de la discipline. Ils avaient une pratique permanente : chaque hôte envoyait des extraits de logs noyau, des stats NIC et des compteurs softnet vers un système central toutes les 30 secondes, et ils gardaient quelques jours d’historique haute résolution. Pas besoin de débogage héroïque. Les données existaient déjà.

Quand les incidents sont survenus, ils ont corrélé trois signaux : (1) des erreurs PCIe AER corrigées dans journalctl, (2) des messages NIC « Reset adapter », et (3) de courtes baisses de débit réseau invité. Le motif se répétait sur un sous‑ensemble d’hôtes—même modèle matériel, même révision BIOS.

Il s’agissait d’un problème de firmware plateforme interagissant avec la gestion d’alimentation PCIe. Dans certains états la NIC se comportait brièvement mal, se réinitialisait et se rétablissait. La correction a été une mise à jour de firmware fournisseur plus la désactivation d’un réglage PCIe ASPM spécifique dans le BIOS comme mitigation courte durée. Pas de toggling d’offload. Pas d’échange de câbles à minuit. Juste des preuves ennuyeuses et une fenêtre de changement.

Le meilleur : ils ont pu prouver que la correction fonctionnait parce que les mêmes signaux se sont tus. Pas de mails de clôture basés sur des impressions.

Erreurs courantes : symptôme → cause racine → correction

  • Symptôme : « Déconnexions réseau », et journalctl -k affiche NIC Link is Down/Up.
    Cause racine : Flap de lien physique (câble/DAC défectueux, optique, mismatch autoneg, erreurs port commutateur, bizarrerie EEE).
    Correction : Vérifiez ethtool -S pour CRC/symbol errors, désactivez EEE pour un test, échangez câble/optique, validez la config port commutateur.
  • Symptôme : Le lien reste up, mais vous voyez Detected Tx Unit Hang / Reset adapter.
    Cause racine : Bug pilote/NIC firmware, problèmes PCIe/AER, ou cas limite files/interruptions sous charge.
    Correction : Collectez le tuple pilote/firmware, corrélez avec les logs AER, mettez à jour le firmware, testez un noyau/HWE plus récent, ajustez coalescing/anneaux, envisagez un pilote fournisseur si disponible.
  • Symptôme : Pas de flap de lien, pas d’erreurs CRC, mais timeouts TCP et retransmissions en hausse.
    Cause racine : Pertes côté hôte (softnet drops, overflow anneau RX, CPU starved), ou microbursts en amont.
    Correction : Vérifiez /proc/net/softnet_stat, ethtool -S missed errors, ajustez anneaux/files/affinité IRQ, et validez le buffering du commutateur.
  • Symptôme : Les petits transferts fonctionnent, les gros plantent ; les pings réussissent ; SSH « parfois freeze ».
    Cause racine : Mismatch MTU ou trou noir PMTU (ICMP bloqué).
    Correction : Audit MTU bout en bout ; lancez ping -M do ; autorisez ICMP fragmentation-needed ; réglez le MTU correct sur tunnels et VLANs.
  • Symptôme : Seuls certains flux échouent, surtout derrière un bond ; les problèmes semblent « aléatoires » selon les clients.
    Cause racine : Le hashing LACP envoie certains flux sur un membre défectueux ; churn/mismatch partenaire.
    Correction : Inspectez /proc/net/bonding ; vérifiez le groupe LACP côté commutateur et le hashing ; contrôlez les erreurs par membre ; envisagez de retirer le membre défectueux jusqu’à réparation.
  • Symptôme : Une capture montre des « bad checksum » et tout le monde panique.
    Cause racine : Artefact de checksum offload dans le chemin de capture.
    Correction : Validez avec une capture on‑wire (SPAN/TAP) ou désactivez temporairement le TX checksum offload pour déboguer uniquement.
  • Symptôme : Désactiver GRO « corrige » quelque chose mais le CPU explose et le débit chute.
    Cause racine : Vous avez masqué un problème plus profond (bug du pilote ou surcharge) en changeant le comportement de batching.
    Correction : Traitez cela comme un indice diagnostic ; poursuivez avec pilote/firmware/noyau ou ajustez coalescing/anneaux ; gardez GRO off seulement comme mitigation documentée.

Listes de contrôle / plan étape par étape

Checklist A: Capturez des preuves pendant le prochain incident (15 minutes, sans supposition)

  1. Enregistrez la fenêtre temporelle des symptômes (début/fin). Si vous n’avez pas de fenêtre, vous n’avez pas d’incident.
  2. Collectez les messages noyau :
    cr0x@server:~$ sudo journalctl -k --since "30 minutes ago" > /tmp/kern.log
    

    Décision : Flap de lien vs reset vs rien de logué vous dit où aller ensuite.

  3. Snapshot des compteurs NIC avant et après une reproduction :
    cr0x@server:~$ sudo ethtool -S eno1 > /tmp/eno1.stats.before
    
    cr0x@server:~$ sleep 60; sudo ethtool -S eno1 > /tmp/eno1.stats.after
    

    Décision : CRC/symbol errors en hausse = physique ; missed/no_buffer en hausse = chemin de réception hôte.

  4. Snapshot softnet :
    cr0x@server:~$ cat /proc/net/softnet_stat > /tmp/softnet.before
    
    cr0x@server:~$ sleep 60; cat /proc/net/softnet_stat > /tmp/softnet.after
    

    Décision : Drops/time_squeeze en hausse signifie que le noyau ne suit pas.

  5. Vérifiez retransmissions/timeouts :
    cr0x@server:~$ nstat -az | egrep -i "TcpRetransSegs|TcpTimeouts"
    TcpTimeouts                     18
    TcpRetransSegs                  3490
    

    Décision : Si TCP le voit, c’est une perte/blocage réel, pas un bug applicatif.

Checklist B: Changements d’offload et tuning sans empirer

  1. Faites un changement à la fois. Non négociable.
  2. Avant de changer, enregistrez les réglages actuels :
    cr0x@server:~$ sudo ethtool -k eno1 > /tmp/eno1.offloads.before
    
    cr0x@server:~$ sudo ethtool -c eno1 > /tmp/eno1.coalesce.before
    
    cr0x@server:~$ sudo ethtool -g eno1 > /tmp/eno1.rings.before
    

    Décision : Vous pouvez maintenant annuler et comparer.

  3. Choisissez le plus petit changement pertinent (par ex. désactiver GRO, pas « tous les offloads »).
  4. Reproduisez sous charge similaire et comparez compteurs et symptômes.
  5. Si le changement aide, décidez s’il s’agit d’une mitigation ou d’une correction finale. Les mitigations doivent être documentées et avoir un plan de retrait.

Checklist C: Validation physique et commutateur que vous pouvez demander précisément

  1. Fournissez à l’équipe commutateur : timestamps, interface serveur, vitesse/duplex négociée, et si Linux a logué lien down/up.
  2. Demandez : compteurs d’erreur de port (CRC/FCS), stats FEC, historique de renégociation de lien, état LACP, et compteurs de buffer/drop.
  3. Planifiez un test d’échange : déplacez le câble/optique vers un port connu bon ou échangez les optiques entre un hôte bon et un hôte mauvais.
  4. Après échange, vérifiez si les erreurs suivent le composant ou restent avec le port.

FAQ

1) Pourquoi mon appli dit « déconnecté » alors que l’interface n’est jamais tombée ?

Parce que TCP peut expirer sans flap de lien. Perte de paquets, microbursts, overflow de ring RX, ou trous noirs PMTU peuvent bloquer les flux assez longtemps pour que l’app abandonne. Vérifiez les retransmissions (nstat), les softnet drops et les missed errors NIC.

2) Dois‑je désactiver GRO/TSO/checksum offloads pour corriger des pertes aléatoires ?

Pas comme premier geste. Si vous avez des flaps de lien ou des erreurs physiques, les offloads sont hors sujet. Si vous suspectez un bug d’offload, désactivez une fonctionnalité temporairement et prouvez l’effet avec compteurs et logs. Gardez le coût CPU en tête.

3) tcpdump montre des checksums invalides. La NIC corrompt‑elle les paquets ?

Souvent non. Avec checksum offload, le noyau remet les paquets à la NIC avant que le checksum soit calculé ; tcpdump peut observer les paquets « pré‑checksum ». Confirmez avec une capture on‑wire ou désactivez temporairement TX checksum offload pour déboguer.

4) Quelle est la façon la plus rapide de distinguer « câble/commutateur » vs « tuning hôte » ?

Les erreurs CRC/align/symbol et les messages explicites lien down/up sont vos indicateurs physiques rapides. Les missed errors, softnet drops et un lien stable pointent vers le chemin de réception hôte et le tuning CPU/IRQ/anneau.

5) Pourquoi je vois des pertes mais pas d’erreurs dans ip -s link ?

Les compteurs ip -s link n’exposent pas toujours les raisons de drop spécifiques au pilote NIC. Utilisez ethtool -S pour des compteurs détaillés et /proc/net/softnet_stat pour les drops noyau.

6) irqbalance peut‑il causer des déconnexions aléatoires ?

Il peut contribuer si les interruptions se retrouvent concentrées ou mal épinglées sur un système NUMA, surtout sous charge. Rarement la seule cause, mais il peut transformer « ok » en « flaky » quand la marge est faible. Vérifiez la distribution des files via /proc/interrupts.

7) J’utilise du bonding (LACP). Pourquoi seuls certains clients sont affectés ?

Le hashing. Certains flux tombent sur un membre défectueux tandis que d’autres sur un membre sain. Vérifiez /proc/net/bonding/bond0 pour churn et confirmez la configuration LACP côté commutateur et les erreurs par membre.

8) Comment rendre persistants les réglages ethtool après reboot sur Ubuntu 24.04 ?

Ne comptez pas sur des commandes manuelles. Utilisez une unité systemd, une règle udev, ou les hooks natifs de votre gestionnaire réseau pour appliquer ethtool -K, -G, -L et -C au moment de la mise en service de l’interface. La méthode exacte dépend de NetworkManager, systemd-networkd ou de la config générée par netplan.

9) Les mises à jour du noyau sur Ubuntu 24.04 provoquent‑elles couramment des instabilités NIC ?

Ça peut arriver, mais « couramment » est exagéré. Plus souvent, les upgrades changent le timing (interruptions, batching, defaults power management) et exposent une couche physique marginale ou un bug firmware. Traitez la mise à jour du noyau comme une corrélation, puis prouvez le mécanisme avec logs et compteurs.

10) Et si tout semble propre mais que les utilisateurs rapportent encore des blocages ?

Alors votre visibilité est insuffisante. Ajoutez des métriques haute résolution : softnet drops, missed errors NIC, retransmissions et pertes côté commutateur. Beaucoup de ces problèmes surviennent en rafales sub‑minute que des moyennes à 5 minutes effacent poliment.

Conclusion : prochaines étapes que vous pouvez déployer cette semaine

Les déconnexions aléatoires ne sont pas aléatoires. Elles surviennent dans l’écart entre vos hypothèses et vos preuves. Réduisez l’écart et le problème se pliera généralement.

  1. Instrumentez d’abord : commencez à collecter des extraits de journalctl -k, des compteurs ethtool -S et des snapshots de /proc/net/softnet_stat autour des incidents.
  2. Classifiez le mode de défaillance : flap de lien vs reset NIC vs drops hôte vs MTU/PMTU vs LACP/bridging.
  3. Faites un changement à la fois : tailles d’anneaux, nombre de queues, coalescing, ou un seul offload. Mesurez avant/après avec compteurs et retransmissions.
  4. Escaladez avec des preuves : si vous avez CRC/symbol errors ou churn LACP, présentez‑les à l’équipe commutateur avec timestamps. Vous ne « demandez pas au réseau de jeter un œil », vous présentez un dossier.
  5. Stabilisez à long terme : alignez mises à jour pilote/firmware avec les mises à jour noyau, et surveillez les compteurs qui prédisent réellement la douleur (missed errors, softnet drops, retransmissions, événements de lien).

Si vous ne faites qu’une chose : arrêtez de traiter les offloads comme un rituel. Traitez‑les comme une expérience. Le réseau vous respectera davantage. Votre pager aussi.

← Précédent
Pourquoi le bas du marché des GPU est plus important qu’on ne le croit
Suivant →
Docker « connection refused » entre services : corrigez les réseaux, pas les symptômes

Laisser un commentaire