...

Server Bandwidth Shaping et Traffic Control Linux : optimisation expliquée

Je montre comment Mise en forme de la largeur de bande sur les serveurs et le contrôle du trafic sous Linux, de manière à réduire sensiblement la latence, la gigue et les pannes. Pour ce faire, j'utilise de manière ciblée des files d'attente prioritaires, des limites et des règles de qualité de service afin de protéger les flux critiques pour l'entreprise tels que la VoIP, les API ou les requêtes de boutique des charges de fond et des sauvegardes.

Points centraux

Les messages clés suivants m'aident à contrôler de manière ciblée la bande passante et le trafic sur les serveurs Linux et à les planifier durablement.

  • Définition des priorités des flux critiques en termes de temps réduit la latence et la gigue.
  • Limites de taux et le throttling évitent les bursts et les bourrages de mémoire tampon.
  • HTB/SFQ répartissent la largeur de bande de manière équitable et maintiennent les classes à un niveau constant.
  • Filtre QoS contrôler par IP, port, protocole ou balises.
  • Suivi via P95 et Alertes détecte les goulots d'étranglement à un stade précoce.

Je construis ces points progressivement, je mesure les effets en continu et j'adapte les classes et les taux à l'utilisation réelle.

Ce que signifie concrètement le Bandwidth Shaping

Lors du shaping, je régule le Flux de paquets activement, au lieu de se contenter de ralentir de manière réactive. Je maintiens des taux constants, donne la priorité au trafic en temps réel et interactif et lisse les salves de données irrégulières. Pour cela, je mise sur le Rate Limiting pour le trafic sortant et le Throttling pour le flux de données entrant. Cette séparation crée des responsabilités claires par direction et évite les mémoires tampons pleines. Pour les environnements d'hébergement, je fixe des limites supérieures définies par client ou par application afin d'éviter qu'un pic de charge ne ralentisse l'ensemble du système.

Contrôle du trafic sous Linux : outils et concepts

Sous Linux, je contrôle le trafic avec l'outil tc et les disciplines de mise en file d'attente du noyau (qdisc). Les blocs de construction typiques sont le qdisc racine, les classes et les filtres qui déterminent l'affectation des paquets aux priorités et aux limites. Je commence souvent avec HTB comme régulateur hiérarchique pour les débits garantis et maximaux. En complément, j'utilise SFQ pour une répartition équitable au sein d'une classe. Ainsi, je limite la bande passante à 90-95% du débit physiquement possible afin de conserver le Burst-Headroom et d'éviter les pics de latence.

Mise en forme de l'entrée (Ingress) : IFB au lieu de Policer

Pour le trafic entrant, je ne forme pas directement sur l'interface physique, mais j'utilise un IFB-(Intermediate Functional Block). Je reflète les paquets Ingress sur l'IFB et les y traite comme du trafic sortant - y compris la hiérarchie HTB, l'équité et les limites. C'est fin qu'un Policer pur, qui ne fait que rejeter durement et augmente souvent la gigue.

modprobe ifb numifbs=1
ip link add ifb0 type ifb
ip link set dev ifb0 up

# Activer l'ingress sur le PHY et le rediriger vers l'IFB
tc qdisc add dev eth0 handle ffff : ingress
tc filter add dev eth0 parent ffff : protocole ip u32 match u32 0 0 \
  action mirred egress redirect dev ifb0

# Shaping sur l'IFB comme pour Egress
tc qdisc add dev ifb0 root handle 2 : htb default 20
tc class add dev ifb0 parent 2 : classid 2:10 htb rate 40mbit ceil 60mbit
tc class add dev ifb0 parent 2 : classid 2:20 htb rate 20mbit ceil 40mbit
tc qdisc add dev ifb0 parent 2:10 handle 210 : fq_codel
tc qdisc add dev ifb0 parent 2:20 handle 220 : sfq

IFB me permet de contrôler les pics de téléchargement, par exemple lorsque les tâches de sauvegarde ou de miroir consomment beaucoup de bande passante. Dans la pratique, je dirige IFB vers des interfaces avec des débits fortement asymétriques (par exemple 1G/200M) ou lorsque des rafales entrantes menacent l'interactivité.

Comparaison entre HTB, TBF et SFQ

Pour bien choisir qdisc je regarde les objectifs d'application : Garanties, comportement en rafale et équité. HTB propose des classes hiérarchiques avec des taux fixes et maximaux, TBF limite strictement par bucket de jetons, SFQ répartit les chances par des flux. Combinés, ils forment dans la pratique une structure solide : HTB couvre et garantit, SFQ empêche la domination de certaines connexions, TBF maîtrise les bursts persistants. Le tableau suivant résume les caractéristiques principales pour des scénarios de serveur typiques. Cela me permet de décider plus rapidement quelle discipline a du sens à quel endroit.

qdisc/fonction Objectif Points forts Utilisation typique
HTB Hiérarchie et contrôle des taux Taux garanti, plafond, héritage Mandants, classes de service, profils QoS
TBF Strict Couvercles Simple, très déterministe Uplink-Cap, limites dures pour les applications
SFQ Équité par flux Faible overhead, bonne distribution Téléchargements, P2P, nombreuses sessions
FQ_CoDel AQM contre le bufferbloat Faible latence, désarmement de la file d'attente Routeurs Edge, liens critiques en termes de latence

Pour les accès dont les RTT varient considérablement, j'utilise FQ_CoDel ou - selon le noyau - CAKE comme solution polyvalente. Dans la pratique du serveur, je reste cependant avec HTB+SFQ/FQ_CoDel, parce que je combine ainsi proprement les garanties, l'emprunt et la répartition équitable dans une hiérarchie.

Pratique : règles tc pour les serveurs typiques

Je commence par une simple HTB-et les assigner ensuite par filtre. Un qdisc racine avec une classe par défaut capture les paquets non classés, les classes prioritaires reçoivent des taux garantis. Ensuite, j'affine les filtres : HTTP/S à la classe A, réplication de la base de données à la classe B, sauvegardes à la classe C. Ainsi, les requêtes de la boutique restent rapides, tandis que les sauvegardes utilisent les restes. Pour les bases et le vocabulaire, je vous renvoie à cette introduction à Gestion de la bande passante, Il s'agit d'un document qui rend la démarche tangible.

tc qdisc add dev eth0 root handle 1 : htb default 20
tc class add dev eth0 parent 1 : classid 1:10 htb rate 50mbit ceil 70mbit
tc class add dev eth0 parent 1 : classid 1:20 htb rate 20mbit ceil 50mbit
tc class add dev eth0 parent 1 : classid 1:30 htb rate 10mbit ceil 30mbit
tc qdisc add dev eth0 parent 1:10 handle 110 : sfq
tc qdisc add dev eth0 parent 1:20 handle 120 : sfq
tc qdisc add dev eth0 parent 1:30 handle 130 : sfq
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 443 0xffff flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip dport 3306 0xffff flowid 1:20
tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 match ip sport 22 0xffff flowid 1:30

Classification avec DSCP et Marks (compatible IPv4/IPv6)

Pour que les filtres fonctionnent indépendamment de la version d'IP et de la NAT, je marque les paquets au début et je les mappe ensuite via fwmark dans des classes. Cela me permet d'économiser des correspondances u32 complexes et de garder des règles légères. J'utilise également DSCP pour la sémantique de bout en bout, par exemple pour la VoIP ou l'interactivité.

# Exemple avec nftables : donner la priorité à TLS, ralentir les sauvegardes
nft add table inet mangle
nft add chain inet mangle prerouting { type filter hook prerouting priority -150 ; }
nft add rule inet mangle prerouting tcp dport 443 meta mark set 10
nft add rule inet mangle prerouting tcp dport 22 meta mark set 30
nft add rule inet mangle prerouting tcp dport 873 meta mark set 40 # rsync/Backups

# Mapping dans les classes HTB (fonctionnent de la même manière pour IPv4/IPv6)
tc filter add dev eth0 parent 1:0 prio 1 handle 10 fw flowid 1:10
tc filter add dev eth0 parent 1:0 prio 2 handle 30 fw flowid 1:30
tc filter add dev eth0 parent 1:0 prio 3 handle 40 fw flowid 1:20

Important : je place les DSCP/marques le plus possible au bord (entrée de la machine ou avant), afin que les décisions ultérieures soient prises rapidement et que tc ait moins de travail sous charge.

Stratégies de QoS pour l'hébergement : équité et limites

Dans les configurations multi-locataires, je sécurise Équité via des garanties fixes par client et des caps par application. Je marque les paquets par DSCP ou par ports et je les attribue à des classes appropriées. Les téléchargements et les sauvegardes peuvent remplir la capacité, tandis que les sessions interactives sont exécutées en priorité. De cette manière, les services pertinents pour le SLA restent prioritaires sans exclure les autres locataires. Je résume les scénarios pratiques et la logique de priorisation dans cet aperçu. Priorisation du trafic qui correspond bien aux règles de tc.

Persistance et automatisation

Mes politiques de QoS survivent aux redémarrages et aux redémarrages d'interface. J'enregistre les commandes tc sous forme de script idempotent et je les intègre dans systemd ou netplan/networkd. Pour les périphériques avec des noms dynamiques (par exemple veth/tap), j'utilise des règles udev ou des modèles systemd.

# /usr/local/sbin/tc-setup.sh (construire idempotent)
#!/bin/sh
tc qdisc replace dev eth0 root handle 1 : htb default 20
# ... plus de classes/filtres ici

# systemd unit : /etc/systemd/system/tc-setup.service
[Unit]
Description=Configuration du contrôle du trafic
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/tc-setup.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Je déploie les modifications de manière contrôlée : d'abord sur le staging, puis de manière limitée dans le temps sur le système de production (tc replace au lieu de add), accompagné de métriques et d'un bouton de retour en arrière.

Monitoring, P95 et dépannage sans frustration

Je mesure les effets en continu, au lieu de me concentrer sur les résultats. Sens du ventre de quitter le réseau. Les latences P95, les longueurs de file d'attente et les pertes de paquets montrent si les règles sont efficaces ou trop strictes. Des outils comme iftop, vnStat et Netdata rendent les pics de charge visibles, les journaux de tc et iptables montrent l'affectation. Si une gigue apparaît, je réduis légèrement les valeurs Ceil et je vérifie CoDel/FQ_CoDel comme mesure AQM. En cas de goulots d'étranglement, j'adapte progressivement les poids des classes et je respecte les fenêtres de mesure après chaque modification.

Méthodologie de test : simulation de charge et vérification

Je simule des scénarios réalistes : un flux continu (iperf3), en parallèle de courtes interactions (petites requêtes HTTP) et des bursts périodiques (sauvegarde/rsync). Ensuite, je vérifie si les flux interactifs maintiennent constamment une faible latence et si les bursts sont proprement lissés.

# Tester le sens inverse (téléchargement/intrusion)
iperf3 -c  -R -t 60

# Lire les statistiques de shaping
tc -s qdisc show dev eth0
tc -s class show dev eth0

# Vérifier la distribution de la gigue/RTT
ping -i 0.2 -c 100  | awk '/time=/{print $7}'

Si des classes ont besoin de borrows en permanence, j'augmente légèrement les taux garantis. Si les drops s'accumulent dans les files d'attente AQM, je vérifie la taille des tampons et si les limites sont fixées de manière trop agressive.

Réglage des performances : 90-95 % couvercle, lissage des rafales, MTU

Je limite le taux de dépenses à 90-95% de la vitesse de liaison, afin d'éviter le blocage de la mémoire tampon et de laisser agir l'AQM. Je lisse les bursts avec des paramètres de token bucket (rate, burst/latency) afin que les pics de courte durée ne remplissent pas des files d'attente entières. Je contrôle le MTU afin de réduire la fragmentation et d'éviter les problèmes de MTU de chemin. Pour les charges de travail très fluctuantes, je définis des valeurs Ceil généreuses, mais des taux garantis conservateurs. Cette configuration maintient le trafic prioritaire à un niveau rapide, tandis que les processus d'arrière-plan continuent à fonctionner de manière neutre.

Décharges matérielles, multi-files et IRQ tuning

Pour un shaping précis sur des liens rapides, je connais l'interaction avec les NIC-Offloads. TSO/GSO/GRO accélèrent certes, mais peuvent dégrader la granularité fine à des débits cibles très faibles. Pour les liens sensibles, je désactive TSO/GSO à titre d'essai et mesure la latence/le gain de CPU en contrepartie. Sur les cartes réseau multi-utilisateurs, je mets en place un mq-Je répartis la charge CPU avec RPS/XPS et IRQ-Pinning, afin que le travail de QoS ne s'affame pas sur un CPU.

# Tester sélectivement les offloads (prudent en production)
ethtool -K eth0 tso off gso off gro off

# Mise en place de la multi-queue
tc qdisc add dev eth0 root handle 1 : mq
tc qdisc add dev eth0 parent 1:1 handle 10 : htb default 20
tc qdisc add dev eth0 parent 1:2 handle 20 : htb default 20
# ... continuer par file d'attente et définir les classes/filtres comme d'habitude

Avec txqueuelen, Avec la taille des tampons circulaires et l'affinité de l'IRQ, je continue à réduire la latence. L'objectif est d'obtenir un chemin de file d'attente stable et court qui ne bascule pas sous la charge.

Sécurité et segmentation : Shaping avec pare-feu et VLAN

Je combine la QoS avec Segmentation, Ainsi, les réseaux critiques conservent leurs propres capacités. Je définis mes propres files d'attente par VLAN ou interface, les pare-feu marquent déjà l'entrée dans le serveur. Ainsi, tc doit prendre moins de décisions sous charge, car les paquets sont classés très tôt. Les sauvegardes du Storage-VLAN restent sur leur trajectoire, tandis que le Frontend-HTTP ne meurt pas de faim. La séparation permet en outre de raccourcir les analyses d'erreurs, car les flux peuvent être attribués de manière plus claire.

Virtualisation et conteneurs : où je forme

Dans les configurations KVM/virtio, je préfère former des EdgeLes garanties sont fixées sur l'interface du pont (br0), sur la liaison montante physique (eth0) ou de manière ciblée par invité sur son interface vnet. J'aime bien mettre en œuvre des garanties pro-tenant sur vnetX, des caps globaux sur la liaison montante. Dans Kubernetes, tc est praticable sur les pairs veth ou les uplinks de nœuds ; j'attribue les marquages tôt par CNI/iptables/nftables afin que l'attribution reste déterministe. Pour SR-IOV ou DPDK, je veille à ce que les chemins de données passent encore par tc - sinon je forme avant ou j'utilise des limiteurs de débit propres à la carte réseau.

Coûts et avantages : L'efficacité plutôt que la mise à niveau du matériel

Avec de l'eau propre modelage j'exploite mieux les lignes existantes et j'économise souvent des mises à niveau coûteuses. La réduction des pertes de paquets et de la latence améliore directement l'expérience utilisateur. Dans les environnements d'hébergement, cela est doublement payant, car des limites équitables empêchent les escalades entre les clients. Dans la pratique, je constate que des taux stables augmentent le débit, car les retransmissions diminuent. Ces effets se traduisent au final par des SLA plus clairs et moins de cas de support.

Pièges fréquents et vérifications rapides

  • Unités inappropriées : Je vérifie si mbit et kbit sont correctement écrites et que les burst/latency correspondent au MTU.
  • Inversion des priorités : trop de classes de haute priorité sans véritable limite entraînent la starification des Defaults. Je respecte strictement les limites supérieures.
  • NAT/IPv6 négligé : Les filtres de port ne fonctionnent pas comme prévu après NAT/IPv6. Je sélectionne tôt (fwmark) et ensuite je mappe en classes.
  • Ceil plus petit que Rate : une faute de frappe fréquente qui bloque l'emprunt. Je valide chaque classe avec tc -s classe.
  • Ingress uniquement poli : le dropping dur génère de la gigue. Avec IFB, je forme de manière plus fine et plus juste.
  • Les décharges faussent les mesures : Je documente l'état de délestage à chaque test et compare des pommes avec des pommes.

Perspectives d'avenir : Réservation basée sur l'IA et politiques adaptatives

J'utilise des tendances comme Prévisions sur la base de la charge historique, afin d'adapter dynamiquement les classes juste avant les heures de pointe. Les modèles d'apprentissage réservent la bande passante pour les phases de VoIP ou de check-out avant que les files d'attente ne s'allongent. Dans les réseaux hybrides entre le cloud et sur site, j'ai recours à des plafonds temporaires et à des budgets en rafale qui changent les politiques selon un calendrier. Cela réduit les interventions opérationnelles et maintient la prévisibilité des services, même en cas d'événements spéciaux. J'ai réuni ici des connaissances de base plus approfondies sur le scaling et les limites : Gestion du trafic et limites d'hébergement.

Résumé & liste de contrôle

Je mets d'abord en place une claire Hiérarchie avec HTB, j'accorde des garanties et je maintiens Ceil légèrement en dessous de Link-Speed. Ensuite, je classe par services, protocoles ou DSCP et je vérifie la latence, la gigue et les valeurs P95. Avec SFQ ou FQ_CoDel, je veille à une répartition équitable et à des files d'attente courtes. Le monitoring accompagne chaque modification afin que je puisse décider des effets au lieu de les deviner. Ainsi, le Bandwidth Shaping n'est pas un acte unique, mais une boucle de régulation légère qui permet de maintenir un trafic serveur sûr et prévisible.

Derniers articles