Ajustement des paramètres du noyau Ubuntu 24.04 : les 5 sysctls qui comptent (et les 10 qui ne servent pas) (cas n°42)

Cet article vous a aidé ?

Vous avez reçu une alerte parce que la latence p99 a doublé, l’API est « correcte sur mon laptop », et quelqu’un dans un fil de discussion
colle une incantation sysctl -w datant de 2013. La tentation est d’ajuster le noyau comme s’il s’agissait d’une voiture de course.
En production, c’est plutôt comme régler un train de marchandise : les petits boutons ont de l’importance, les gros réglages peuvent vous faire dérailler, et la plupart des boutons sont du placebo.

Ubuntu 24.04 est livré avec un noyau moderne et des valeurs par défaut conservatrices qui conviennent généralement. Généralement.
L’astuce consiste à savoir quels cinq sysctls valent la peine d’être modifiés, quand ils importent, et comment prouver que vous avez aidé au lieu de simplement changer des chiffres.

Règles d’engagement : comment tuner sans se faire mal

Le tuning du noyau n’est pas un passe-temps. Traitez-le comme un changement en production : vous avez besoin d’une hypothèse, d’une métrique, d’un rollback,
et d’une définition claire de « mieux ». Sinon vous réarrangez les sysctls jusqu’à ce que l’incident prenne fin pour des raisons sans rapport.

1) Ne changer qu’une dimension à la fois

Si vous modifiez les buffers TCP, les seuils de pages sales et le dimensionnement du conntrack en un seul déploiement, vous avez créé un roman policier.
Les SRE ne sont pas payés pour lire des romans policiers à 03:00.

2) Privilégier des valeurs par défaut conscientes de la charge plutôt que le folklore

Les limites de votre système se trouvent le plus souvent ailleurs : saturation CPU, latence stockage, timeouts DNS, head-of-line blocking,
ou backpressure applicative. Les sysctls peuvent aider, mais seulement quand vous pouvez nommer le goulot d’étranglement.

3) Rendre les changements persistants de la bonne façon

Ubuntu 24.04 charge les sysctls depuis /etc/sysctl.conf et /etc/sysctl.d/*.conf.
Mettez vos modifications dans un fichier dédié comme /etc/sysctl.d/99-local-tuning.conf et documentez le pourquoi.
Ne vous contentez pas de « lancer sysctl -w » sur un serveur pet et d’appeler ça terminé.

4) Comprendre le rayon d’impact

Certains sysctls sont par-namespace, d’autres sont globaux. Les conteneurs peuvent compliquer la situation.
Si vous tochez l’hôte, vous pouvez changer le comportement pour tous les pods, VM ou services qui utilisent ce noyau.

5) Ne pas tuner autour d’un manque de capacité

Vous ne pouvez pas sysctl-votre chemin hors d’une carte réseau sous-dimensionnée, d’un array disque saturé, ou d’une base qui fait des scans complets.
Le tuning sert à réduire la friction. Pas à violer la physique.

Une citation pour rester honnête : L’espoir n’est pas une stratégie. — idée paraphrasée souvent attribuée aux responsables opérations.
En tuning du noyau, « l’espoir » ressemble à « mettons-le à 1 000 000 et on verra ».

Faits et histoire qui expliquent les valeurs par défaut d’aujourd’hui

  • L’interface « sysctl » prédate les conteneurs Linux. Beaucoup de boutons ont été conçus pour des machines mono-locataires ; des hôtes multi-tenant peuvent transformer le « sûr » en « voisin bruyant ».
  • La mise à l’échelle de la fenêtre TCP (RFC 1323) a rendu le dimensionnement des buffers pertinent. Avant cela, les liens à grand produit bande passante/latence ne pouvaient pas être remplis efficacement quoi que vous fassiez.
  • Linux est passé de « tout tuner » à « autotuner la plupart des choses ». Les noyaux modernes dimensionnent dynamiquement de nombreux buffers TCP, donc les vieilles recettes statiques ne font souvent rien.
  • Le modèle d’écriture différée (« dirty page ») a été ajusté pendant des décennies. Les knobs existent parce que bufferiser les écritures peut améliorer le débit, mais trop de buffer provoque des pics de latence spectaculaires.
  • vm.swappiness est devenu célèbre en partie parce que les laptops swappaient à l’époque du desktop Linux. Les serveurs ont hérité du folklore, même quand ça ne convenait pas.
  • Conntrack n’était pas « par défaut » aux débuts. Le firewalling stateful et le NAT ont fait du suivi de connexions une préoccupation centrale pour de nombreuses flottes.
  • Les ports éphémères se heurtaient plus souvent dans les clients à haut QPS. La plage de ports et le comportement TIME-WAIT sont devenus des sujets opérationnels dès l’apparition des meshes de service et des retries agressifs.
  • L’épuisement des descripteurs de fichiers a toujours été une des 10 premières causes d’incident. Pas parce que Linux est fragile, mais parce que les logiciels savent être créatifs pour fuir des sockets en cas de panne partielle.

Blague #1 : Le tuning du noyau, c’est comme assaisonner une soupe : vous pouvez toujours ajouter du sel, mais vous ne pouvez pas l’enlever une fois que les clients hurlent.

Playbook de diagnostic rapide (premier/deuxième/tiers)

Avant de toucher aux sysctls, trouvez le goulot d’étranglement. Voici l’échelle de triage la plus rapide que j’ai utilisée sur des flottes Ubuntu :
elle réduit la liste de suspects en quelques minutes.

Premier : est-ce le CPU, la pression mémoire, ou la file de threads exécutables ?

  • Vérifiez la charge versus l’utilisation CPU : une charge élevée avec une faible utilisation CPU signifie souvent I/O wait ou contention sur des verrous.
  • Vérifiez les fautes majeures et le swapping : si vous paginez, vous avez d’abord un problème de mémoire.
  • Vérifiez la longueur de la run queue : si elle dépasse constamment le nombre de cœurs CPU, vous êtes CPU-bound ou limité par l’ordonnanceur.

Second : est-ce la latence stockage ou des stalls de writeback ?

  • Cherchez une forte attente disque, saturation, et des pics de flush/writeback.
  • Cherchez la croissance des pages dirty et des sync storms soudaines (particulièrement sur bases, pics de logs, ou clients NFS).

Troisième : est-ce l’ordonnancement réseau, les drops, ou le suivi de connexions ?

  • Vérifiez les retransmissions et les drops (ils transforment le débit en tristesse).
  • Vérifiez le débordement du backlog de sockets et les drops de la file d’écoute.
  • Vérifiez le nombre de conntrack vs le max et les erreurs « insert failed ».

Si vous suivez cet ordre, vous éviterez l’erreur classique : tuner les buffers TCP alors que le vrai problème est un NVMe bridé ou un CPU saturé par le chiffrement.

Les 5 sysctls qui comptent (la plupart du temps)

Ce sont les leviers qui, selon mon expérience, font bouger des métriques en production sur Ubuntu 24.04 quand il y a un goulot bien identifié.
Ce ne sont pas des miracles. Ce sont des leviers que vous actionnez quand les mesures disent que vous devriez.

1) fs.file-max — plafond système des handles de fichiers

Si vous exécutez des services avec beaucoup de connexions (proxies, brokers, frontaux HTTP chargés),
les handles de fichiers sont de l’oxygène. Quand vous en manquez, ça ne se dégrade pas progressivement ; ça échoue d’une manière qui ressemble à des erreurs de connexion « aléatoires ».

Les valeurs par défaut d’Ubuntu conviennent souvent pour des charges modérées, mais de grandes flottes et des nœuds à forte connexion peuvent atteindre le plafond.
Aussi : la limite du noyau n’est que la moitié de l’histoire ; les limites par processus (ulimit -n) et les limites systemd d’unité mordent souvent en premier.

Quand la changer

  • Erreurs comme « Too many open files » dans les logs.
  • Balanceurs/proxies avec des dizaines de milliers de sockets concurrentes par processus.
  • Systèmes à forte rotation avec beaucoup de watchers (inotify) ou de connexions de courte durée.

Comment la régler en sécurité

Augmentez-la à une valeur que vous pouvez justifier, pas « infinie ». Surveillez l’utilisation des handles et gardez une marge.
Le noyau a besoin de mémoire pour les structures de fichiers ; sur des machines petites, des valeurs énormes sont inutiles.

2) net.core.somaxconn — plafond du backlog d’écoute

Ceci limite combien de connexions peuvent être en file d’attente pour acceptation sur une socket écoutante (avec des nuances : le backlog passé à listen()
et le comportement du noyau comptent aussi). Si vous avez du trafic en rafales et une boucle d’accept qui ne suit pas momentanément,
un backlog bas transforme les rafales en SYN drops ou connexions refusées.

Quand la changer

  • Des pics courts provoquent des échecs de connexion alors que le CPU n’est pas saturé.
  • Reverse proxies et API gateways avec ingress bursty.
  • Services faisant des handshakes TLS coûteux et qui ne peuvent pas accepter assez vite pendant les orages.

Comment la régler en sécurité

Montez à 4096 ou 8192 pour des frontaux chargés, puis vérifiez que vous avez réduit les drops de listen.
Des backlogs plus grands peuvent masquer la lenteur applicative ; ne l’utilisez pas comme sédatif.

3) net.ipv4.ip_local_port_range — ports éphémères pour les clients

Cela importe pour les systèmes qui initient beaucoup de connexions sortantes : clients API, sidecars service mesh,
gateways NAT, scrapers, et tout ce qui fait des retries agressifs. Si vous manquez de ports éphémères, vous obtenez des échecs de connect(),
et l’application interprète souvent cela comme « le distant est mort », ajoutant des retries et empirant la situation.

Quand la changer

  • Haut QPS sortant avec connexions de courte durée.
  • Nœuds NAT ou proxy où de nombreux clients internes partagent l’egress.
  • Accumulation TIME-WAIT importante et impossibilité de passer rapidement au réemploi de connexions.

Comment la régler en sécurité

Élargissez la plage (par exemple à 10240 60999 ou similaire) en évitant les ports réservés.
Ensuite vérifiez l’utilisation des ports et confirmez que vous ne masquez pas un mauvais réemploi de connexions.

4) vm.swappiness — préférence de politique de swapping

C’est le bouton que tout le monde touche en premier, et c’est souvent une erreur. Mais il compte dans un cas serveur très courant :
quand vous avez beaucoup de RAM, mais que le noyau décide de swapper des pages peu utilisées, et que des services sensibles à la latence
les fautent ensuite au pire moment.

Sur beaucoup de charges serveur modernes, une swappiness plus basse (souvent 1 à 10) réduit les fautes majeures imprévues,
à condition d’avoir suffisamment de mémoire et de ne pas utiliser le swap comme extension de capacité.

Quand la changer

  • Des pics de latence corrèlent avec des fautes majeures ou des swap-ins.
  • Vous avez le swap activé « au cas où », et vous voulez qu’il reste dernier recours, pas un comportement courant.
  • Nœuds de base de données où le cache est important et où le thrashing de swap est mortel.

Comment la régler en sécurité

Ne la mettez pas à 0 par réflexe. Utilisez une valeur basse et surveillez le comportement de reclaim.
Si vous manquez de mémoire, la swappiness n’est pas votre vraie solution—augmentez la capacité ou réduisez la charge.

5) vm.dirty_ratio et vm.dirty_background_ratio — buffering d’écriture et répartition de la douleur

Oui, ce sont deux sysctls, mais c’est une seule décision. Ils gouvernent combien de données « dirty » (modifiées, non encore écrites) le noyau permettra
avant de forcer le writeback, et quand le writeback en arrière-plan doit démarrer.

Les ratios par défaut peuvent convenir sur des nœuds à usage général. Sur des systèmes à écriture intensive, ils peuvent créer un comportement « calme pendant un moment, puis tout se fige » :
les buffers se remplissent, puis le noyau force une pression de writeback presque synchrone sur des threads malheureux. La latence passe de lisse à en dents de scie.

Quand les changer

  • Charges d’écriture lourdes avec des falaises périodiques de latence.
  • Nœuds d’agrégation de logs, pipelines d’ingestion, workers CI écrivant des artefacts.
  • Systèmes avec des rafales rapides (en mémoire) mais un stockage de fond plus lent (bloc réseau, disques rotatifs, RAID surchargé).

Comment les régler en sécurité

Pour beaucoup de serveurs, abaisser les ratios (ou utiliser les équivalents en octets) lisse le writeback et réduit la latence de queue.
Mais trop bas et vous bridez inutilement le débit. C’est un réglage que vous devez valider avec de vraies métriques : dirty bytes, writeback,
latence stockage et p99 applicative.

Les 10 sysctls qui ne servent pas (la plupart du temps)

Voici les boutons qui apparaissent dans des billets de blog, des gists « durcir Linux », ou des cultes du cargo performance.
Ils ne sont pas inutiles dans toutes les circonstances. Ils sont juste rarement la chose qui corrige votre problème sur Ubuntu 24.04.
Touchez-les seulement quand vous pouvez expliquer le mode d’échec et comment vous mesurerez l’amélioration.

1) net.ipv4.tcp_tw_reuse — folklore TIME-WAIT

Le réemploi des sockets TIME-WAIT était une « solution » courante à la pression des ports éphémères. Les piles réseau modernes et le comportement réel du NAT/horodatage
rendent ce levier risqué. Le réemploi côté application (keep-alives, pooling) est la solution d’adulte.

2) net.ipv4.tcp_fin_timeout — semble utile, ne l’est généralement pas

Régler le timeout FIN corrige rarement l’épuisement des ports car c’est le TIME-WAIT, pas le FIN-WAIT, qui représente la majorité.
Si vous êtes submergé par des sockets à demi-fermés, demandez pourquoi les pairs ne ferment pas proprement.

3) net.ipv4.tcp_syncookies — pas un tweak de performance

C’est un mécanisme de défense contre les SYN floods, pas un booster de débit.
Réglez-le selon votre posture de sécurité, pas parce que vous l’avez vu dans une liste de tuning.

4) net.ipv4.tcp_sack — ne le basculez pas à la légère

Désactiver SACK a été suggéré durant des périodes de vulnérabilité spécifiques. Dans la vie normale, SACK améliore la récupération de perte.
Le désactiver peut nuire aux performances sur des réseaux imparfaits et est rarement justifié pour des serveurs génériques.

5) net.core.netdev_max_backlog — le piège « agrandis la file »

Si les paquets s’accumulent parce que le CPU ne peut pas vider la file, l’agrandir peut augmenter latence et jitter.
Parfois il faut cela pour absorber des rafales ; souvent il faut du CPU, de l’affinité IRQ, du RPS/RFS, ou simplement moins de paquets.

6) net.ipv4.tcp_mtu_probing — un contournement, pas une baseline

Le probing MTU peut aider sur des chemins avec PMTUD cassé. Si vous ne diagnostiquez pas des trous noirs, ne faites pas deviner les MTU à votre pile en permanence.

7) kernel.pid_max — rarement votre goulot

Si vous épuisez les PID, quelque chose d’autre est profondément cassé : fork bombs, superviseurs en boucle, ou churn extrême de processus.
Corrigez le churn ; n’augmentez pas juste le plafond.

8) vm.vfs_cache_pressure — le bouton « cache » mal interprété

Sur les noyaux modernes, la relation entre page cache, inode/dentry cache, et reclaim est plus nuancée que ce seul chiffre.
Si vous le touchez sans mesurer le reclaim et les taux de hit du cache, vous devinez.

9) kernel.randomize_va_space — bouton sécurité, pas performance

La randomisation d’espace d’adressage affecte la difficulté d’exploitation d’un bug. Ce n’est pas votre problème de latence, et le désactiver pour la perf est généralement injustifiable.

10) vm.overcommit_memory — mal compris et mal appliqué

Le comportement d’overcommit importe pour certaines charges d’allocation massives, mais le changer « pour la perf » est une façon classique de transformer un pic de mémoire récupérable
en échecs d’allocation immédiats. Utilisez-le quand vous comprenez les patterns d’allocation et la gestion d’échec de l’application.

Blague #2 : Mettre des sysctls aléatoires depuis Internet, c’est comme accepter une demande de changement en production qui dit « divers ajustements » ; la seule certitude est des réunions futures.

Tâches pratiques : commandes, signification, décisions (12+)

Ce sont des tâches réelles que j’exécute sur des serveurs Ubuntu avant et après des changements sysctl.
Chaque tâche inclut : commande, ce que la sortie signifie, et la décision à prendre à partir de là.
Exécutez-les avec un utilisateur ayant les privilèges appropriés.

Tâche 1 : Voir quels sysctls sont réellement définis (et d’où)

cr0x@server:~$ sudo systemd-analyze cat-config systemd-sysctl.service
# /usr/lib/systemd/system/systemd-sysctl.service
...
# /usr/lib/sysctl.d/00-system.conf
net.ipv4.ip_forward = 0
...
# /etc/sysctl.d/99-local-tuning.conf
vm.swappiness = 10

Signification : Cela montre quels fichiers sysctl sont appliqués et dans quel ordre de priorité.
Décision : Si vous ne trouvez pas d’où vient une valeur, ne la changez pas encore. Réparez d’abord l’hygiène de configuration.

Tâche 2 : Vérifier les valeurs courantes pour les « cinq qui comptent »

cr0x@server:~$ sysctl fs.file-max net.core.somaxconn net.ipv4.ip_local_port_range vm.swappiness vm.dirty_ratio vm.dirty_background_ratio
fs.file-max = 9223372036854775807
net.core.somaxconn = 4096
net.ipv4.ip_local_port_range = 32768	60999
vm.swappiness = 60
vm.dirty_ratio = 20
vm.dirty_background_ratio = 10

Signification : Vous avez une base. Note : certaines distributions définissent des fs.file-max très grands ; les limites par processus importent toujours.
Décision : Si swappiness est à 60 sur un nœud sensible à la latence avec swap activé, c’est un candidat—après avoir confirmé que vous swappez réellement.

Tâche 3 : Valider la pression sur les descripteurs de fichiers au niveau système

cr0x@server:~$ cat /proc/sys/fs/file-nr
12032	0	9223372036854775807

Signification : Le premier nombre est les handles de fichiers alloués ; le troisième est le maximum.
Décision : Si l’alloué approche le max (ou si vous voyez des échecs d’allocation), augmentez fs.file-max et auditez les processus pour fuites.

Tâche 4 : Valider les limites de descripteurs par processus (systemd gagne souvent)

cr0x@server:~$ systemctl show nginx --property=LimitNOFILE
LimitNOFILE=1024

Signification : Votre service ne peut ouvrir que 1024 fichiers/sockets, indépendamment de fs.file-max.
Décision : Si c’est un frontend chargé, augmentez LimitNOFILE dans l’override d’unité ; le sysctl seul ne vous sauvera pas.

Tâche 5 : Vérifier les drops de file d’écoute et les signaux de backlog SYN

cr0x@server:~$ netstat -s | sed -n '/listen queue/,/TCPBacklogDrop/p'
    120 times the listen queue of a socket overflowed
    120 SYNs to LISTEN sockets dropped

Signification : Le noyau a eu des connexions arrivant plus vite que l’application ne pouvait les accepter.
Décision : Envisagez d’augmenter net.core.somaxconn et aussi de profiler la boucle d’accept / TLS / la saturation des workers.

Tâche 6 : Voir combien de ports éphémères sont réellement utilisés

cr0x@server:~$ ss -s
Total: 32156 (kernel 0)
TCP:   27540 (estab 1320, closed 24511, orphaned 12, synrecv 0, timewait 23890/0), ports 0
Transport Total     IP        IPv6
RAW       0         0         0
UDP       316       280       36
TCP       3029      2510      519
INET      3345      3070      275
FRAG      0         0         0

Signification : Un grand nombre de TIME-WAIT indique du churn ; cela peut aussi indiquer l’absence de keep-alives/pooling.
Décision : Si le churn sortant est élevé et que des échecs de connexion se produisent, élargissez ip_local_port_range et priorisez le réemploi des connexions.

Tâche 7 : Confirmer que vous swappez (ne pas deviner)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:            62Gi        41Gi       2.1Gi       1.2Gi        19Gi        18Gi
Swap:          8.0Gi       1.6Gi       6.4Gi

Signification : Le swap est utilisé. Ce n’est pas toujours mal, mais c’est suspect sur des nœuds sensibles à la latence.
Décision : Si le swap est utilisé et que vous voyez des fautes majeures pendant des pics de latence, baissez vm.swappiness et/ou ajoutez de la mémoire.

Tâche 8 : Mesurer l’activité de swap dans le temps

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0 1677720 2200000 120000 18400000   0   4     2   120  900 2400 12  6 78  4  0
 1  0 1677720 2195000 120000 18420000   0   0     0    80  850 2300 11  5 80  4  0
 3  1 1677720 2100000 120000 18500000  40  12   200   600 1200 4000 18  8 60 14  0

Signification : si/so (swap in/out) en pic corrèle avec la douleur de latence.
Décision : Si des swap-ins se produisent sous charge, baissez la swappiness et corrigez la pression mémoire. Si le swap est stable et faible, ça peut être inoffensif.

Tâche 9 : Inspecter le comportement dirty/writeback

cr0x@server:~$ egrep 'Dirty|Writeback|MemAvailable' /proc/meminfo
MemAvailable:   18342172 kB
Dirty:           914832 kB
Writeback:        26304 kB

Signification : Les données dirty sont actuellement ~900MB. Ça peut être acceptable ou alarmant selon la RAM et la charge.
Décision : Si Dirty croît jusqu’à plusieurs Gio et que les pics de latence s’alignent avec des flush storms, ajustez les dirty ratios (ou octets) pour lisser le writeback.

Tâche 10 : Corréler la latence I/O rapidement

cr0x@server:~$ iostat -xz 1 3
Linux 6.8.0-xx-generic (server) 	12/30/2025 	_x86_64_	(16 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.40    0.00    5.80   18.20    0.00   63.60

Device            r/s     rkB/s   rrqm/s  %rrqm  r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm  w_await wareq-sz  aqu-sz  %util
nvme0n1          40.0   1024.0     0.0   0.00    2.10    25.6     900.0   32000.0    10.0   1.10   45.00    35.6   41.2   98.0

Signification : Un w_await élevé, un aqu-sz élevé et une utilisation proche de 100% indiquent que le périphérique est saturé.
Décision : Ne « tunez pas le noyau » en premier. Corrigez le débit/latence du stockage ou réduisez la pression d’écriture ; le tuning dirty ne fera que redistribuer la douleur.

Tâche 11 : Vérifier la saturation du conntrack (mode panne classique NAT/gateway)

cr0x@server:~$ sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
net.netfilter.nf_conntrack_count = 252144
net.netfilter.nf_conntrack_max = 262144

Signification : Vous êtes à 4% du max conntrack. C’est une lumière rouge clignotante.
Décision : Si c’est un nœud firewall/NAT/load balancer stateful, augmentez nf_conntrack_max et assurez-vous d’avoir de la mémoire disponible. Auditez aussi le churn de connexions.

Tâche 12 : Vérifier les drops conntrack dans les logs du noyau

cr0x@server:~$ sudo dmesg -T | tail -n 8
[Mon Dec 30 10:14:02 2025] nf_conntrack: table full, dropping packet
[Mon Dec 30 10:14:02 2025] nf_conntrack: table full, dropping packet

Signification : Des paquets sont droppés parce que conntrack est plein. Les utilisateurs subiront des timeouts et des retries.
Décision : Augmentez la capacité conntrack et réduisez le churn. Ce n’est pas un « peut-être » ; c’est un goulot confirmé.

Tâche 13 : Vérifier les retransmissions TCP et les drops (ne blâmez pas les sysctls pour un lien mauvais)

cr0x@server:~$ netstat -s | sed -n '/Tcp:/,/Ip:/p'
Tcp:
    923849 active connection openings
    12 failed connection attempts
    210938 segments retransmitted
    41 resets sent

Signification : Les retransmissions indiquent perte de paquets, congestion ou mauvais ordonnancement.
Décision : Si les retransmits augmentent avec des problèmes de perf, investiguez le chemin réseau, les drops NIC, les qdisc et la congestion—pas des sysctls TCP au hasard.

Tâche 14 : Appliquer un changement sysctl temporairement (pour validation seulement)

cr0x@server:~$ sudo sysctl -w net.core.somaxconn=8192
net.core.somaxconn = 8192

Signification : Le changement est appliqué immédiatement, pas persistant au reboot.
Décision : Utilisez cela pour une validation A/B pendant une fenêtre d’incident, puis rendez-le persistant proprement si ça a aidé.

Tâche 15 : Rendre les changements persistants et les recharger

cr0x@server:~$ sudo tee /etc/sysctl.d/99-local-tuning.conf >/dev/null <<'EOF'
net.core.somaxconn = 8192
vm.swappiness = 10
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
EOF
cr0x@server:~$ sudo sysctl --system
* Applying /etc/sysctl.d/99-local-tuning.conf ...
net.core.somaxconn = 8192
vm.swappiness = 10
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10

Signification : Les valeurs sont maintenant persistantes et appliquées dans le bon ordre.
Décision : Enregistrez le ticket de changement, les métriques avant/après, et le plan de rollback (supprimer le fichier ou revenir aux valeurs).

Trois mini-récits d’entreprise issus du terrain

Mini-récit #1 : L’incident causé par une mauvaise hypothèse (édition conntrack)

Une entreprise de taille moyenne exploitait un ensemble de nœuds « edge » : HAProxy, NAT, et un peu de routage L7. L’équipe supposait que les nœuds étaient sans état parce que
« ce n’est que du forwarding ». Cette hypothèse était confortable, populaire, et fausse.

Une intégration partenaire a été lancée. Le trafic n’a pas seulement augmenté ; il est devenu plus piqué. Une tempête de retries a frappé après un bref hic upstream, transformant une courbe propre
en porcupine. Les nœuds edge ont commencé à timeouter sur les nouvelles connexions. Rien d’évident dans les graphes CPU. La mémoire semblait stable. Le stockage était hors sujet.

Quelqu’un a augmenté net.core.somaxconn. Un autre a blâmé TLS. L’indice réel était dans le log noyau : conntrack table full, dropping packets.
Ces nœuds faisaient du NAT, donc l’état conntrack n’était pas optionnel ; c’était le produit.

La correction fut ennuyeuse : augmenter net.netfilter.nf_conntrack_max et le dimensionner selon la mémoire disponible, puis réduire le churn en améliorant le réemploi des connexions client
et en ajoutant des coupe-circuits pour empêcher les retries de devenir de l’automutilation. Ensuite, l’équipe a mis à jour ses docs d’architecture : « stateful edge ».
Cette seule phrase a évité de futures réunions « mais c’est sans état ».

Mini-récit #2 : L’optimisation qui a mal tourné (dirty ratios et l’illusion de vitesse)

Une autre organisation avait un pipeline de logs avec un buffer disque local. Sous forte ingestion, le buffer prenait parfois du retard. Un ingénieur a remarqué
que les disques n’étaient « pas occupés » la plupart du temps et a voulu batcher les écritures pour le débit. Il a augmenté significativement vm.dirty_ratio,
en s’attendant à moins de flush et à une meilleure efficacité disque.

Le débit semblait excellent—pendant un moment. Puis l’on-call a commencé à voir des stalls de plusieurs secondes dans le service d’ingestion.
Pas un ralentissement doux. Des arrêts complets. Les alertes downstream ont déclenché parce que l’ingestion devenait bursty, ce qui rendait l’indexation bursty, ce qui rendait les requêtes bursty.
C’était comme regarder un petit tremblement déclencher une chaîne d’étagères qui tombent.

Le noyau avait été autorisé à accumuler un énorme tas de pages dirty. Quand la pression de writeback a finalement démarré, le système a payé la dette d’un coup.
Certains threads qui devaient allouer de la mémoire ou écrire des métadonnées se sont retrouvés bloqués derrière la tempête de writeback. Le graphe « disque pas occupé » était un mensonge :
il était inactif jusqu’à ce qu’il ne le soit plus, puis il était à 100% avec un await élevé.

Le rollback a stabilisé la latence immédiatement. La correction à long terme fut plus nuancée : ratios modérés (ou seuils en octets),
meilleur batching côté application là où il peut être contrôlé, et plus de bande passante disque. Le post-mortem a retenu la leçon nette :
le buffering noyau peut lisser ; il peut aussi cacher un risque jusqu’à ce qu’il explose.

Mini-récit #3 : La pratique ennuyeuse mais correcte qui a sauvé la mise (limites et observabilité)

Une équipe de services financiers exploitait une API à fort trafic avec des SLO stricts. Leur posture de tuning était presque agaçante dans sa discipline :
chaque changement sysctl nécessitait une hypothèse, un lien vers un dashboard, et une procédure de rollback. Ils gardaient un petit fichier versionné dans
/etc/sysctl.d/ avec des commentaires expliquant chaque déviation des valeurs par défaut.

Un après-midi, un déploiement a introduit une fuite subtile de sockets sur un chemin d’erreur spécifique. Les descripteurs de fichiers ont augmenté lentement.
Sur une équipe moins disciplinée, le premier symptôme aurait été une panne et une réaction frénétique « augmenter les limites ! ».

Au lieu de cela, ils avaient deux garde-fous. Premier : un dashboard suivant /proc/sys/fs/file-nr et les comptes FD ouverts par processus.
Second : une marge raisonnable dans LimitNOFILE et le file-max du noyau, si bien que la fuite avait le temps d’être détectée et rollbackée avant une panne dure.

Ils ont quand même dû corriger le bug. Mais le travail « ennuyeux »—sysctls documentés, bases mesurées, et limites dimensionnées pour la réalité—a transformé un incident potentiel
en un rollback de routine. C’est tout le jeu.

Erreurs courantes : symptôme → cause racine → correctif

1) « Timeouts de connexion aléatoires lors de pics de trafic »

Symptôme : Les clients voient des échecs de connexion intermittents pendant les rafales ; le CPU n’est pas saturé.

Cause racine : Débordement du backlog d’écoute (somaxconn trop bas) ou boucle d’accept trop lente.

Correctif : Augmenter net.core.somaxconn à 4096–8192 et confirmer avec les compteurs de file d’écoute de netstat -s ; profiler accept/TLS et la saturation des workers.

2) « Tout se fige pendant des secondes, puis reprend »

Symptôme : Stalls périodiques ; utilisation disque monte à 100% ; p99 devient en dents de scie.

Cause racine : Accumulation de pages dirty et tempêtes de writeback (dirty ratios trop élevés pour le périphérique).

Correctif : Baisser vm.dirty_background_ratio et vm.dirty_ratio (ou utiliser des limites en octets), puis confirmer une réduction de l’oscillation Dirty/Writeback et une amélioration de l’I/O await.

3) « Appels sortants échouent sous charge avec EADDRNOTAVAIL »

Symptôme : Erreurs de connexion côté client, souvent pendant des retries ou des rafales.

Cause racine : Épuisement des ports éphémères ou TIME-WAIT excessif dû au churn de connexions.

Correctif : Élargir net.ipv4.ip_local_port_range, réduire le churn via keep-alives/pooling, et surveiller les TIME-WAIT avec ss -s.

4) « nf_conntrack: table full » et timeouts côté utilisateur

Symptôme : Logs noyau montrent des drops conntrack ; nœuds NAT/firewall timeoutent.

Cause racine : nf_conntrack_max trop bas pour le churn et la concurrence.

Correctif : Augmenter net.netfilter.nf_conntrack_max, assurer de la mémoire disponible, et réduire le churn (timeouts d’inactivité, réemploi des connexions, éviter les tempêtes de retries).

5) « On a mis swappiness à 1 et ça reste lent »

Symptôme : Les problèmes de latence persistent ; la mémoire est serrée ; le swap peut encore être utilisé.

Cause racine : Vous êtes réellement en contrainte mémoire ; swappiness n’est pas une capacité. Aussi, la charge peut être I/O bound ou CPU bound.

Correctif : Mesurez les fautes majeures et les swap-ins ; si la pression mémoire est réelle, ajoutez de la RAM ou réduisez l’utilisation mémoire. Ensuite, ajustez swappiness comme politique, pas comme secours.

6) « On a augmenté tous les buffers TCP et c’était pire »

Symptôme : La latence a augmenté ; l’utilisation mémoire a grimpé ; pas de gain de débit.

Cause racine : Les buffers ont augmenté l’ordonnancement et la pression mémoire ; le goulot n’était pas la taille de la fenêtre TCP.

Correctif : Revenir sur les changements de buffers, valider les retransmits/drops, vérifier le CPU et le queueing NIC ; ne tuner qu’avec un vrai problème de BDP.

7) « Trop de fichiers ouverts » malgré un fs.file-max énorme

Symptôme : Erreurs applicatives montrant l’épuisement des FD ; fs.file-max du noyau semble massif.

Cause racine : Les limites par processus (systemd LimitNOFILE) sont basses.

Correctif : Augmenter le LimitNOFILE de l’unité et vérifier avec systemctl show et /proc/<pid>/limits.

Listes de contrôle / plan pas à pas

Checklist A : Workflow sûr de tuning sysctl (production)

  1. Écrire l’hypothèse : « Nous perdons des connexions entrantes à cause d’un débordement de backlog ; augmenter somaxconn réduira les drops et améliorera p99 connect. »
  2. Choisir 2–3 métriques : un signal noyau (ex. débordement de file d’écoute), un symptôme utilisateur (latence p99), une métrique ressource (CPU, mémoire, I/O await).
  3. Capturer la baseline : exécuter les tâches pertinentes ci‑dessus ; sauvegarder les sorties avec horodatage.
  4. Appliquer le changement temporairement : sysctl -w pendant une fenêtre contrôlée, ou sur un nœud canari.
  5. Observer : le signal noyau s’est-il amélioré, et la métrique utilisateur s’est‑elle améliorée sans dégâts collatéraux ?
  6. Rendre persistant : écrire dans /etc/sysctl.d/99-local-tuning.conf, puis sysctl --system.
  7. Documenter : ce qui a changé, pourquoi, et à quoi ressemble le rollback.
  8. Revalider après reboot : confirmer que la valeur persiste et que le comportement est inchangé.

Checklist B : Profil minimal « cinq sysctls » pour rôles serveurs courants

Ingress HTTP chargé / reverse proxy

  • net.core.somaxconn : envisager 4096–8192 si vous voyez un overflow d’écoute.
  • fs.file-max : assurer une marge ; augmenter aussi LimitNOFILE d’unité.
  • net.ipv4.ip_local_port_range : surtout pertinent si le nœud agit aussi comme client sortant intensif.
  • vm.swappiness : baisser si les swap-ins causent des pics de latence.
  • vm.dirty_* : seulement si la journalisation locale/buffering cause des stalls.

Nœud base de données (sensible à la latence, écriture lourde)

  • vm.swappiness : souvent 1–10, mais seulement après avoir confirmé l’impact du swapping.
  • vm.dirty_ratio/vm.dirty_background_ratio : tuner pour éviter les cliffs de writeback ; mesurer I/O await et dirty/writeback.
  • fs.file-max : assurer la marge ; les DB peuvent utiliser beaucoup de fichiers et sockets.
  • net.core.somaxconn : rarement limitant sauf si le serveur sert aussi des rafales TCP frontales.
  • ip_local_port_range : surtout non pertinent sauf si la DB initie beaucoup de connexions sortantes.

Gateway NAT / firewall / nœud Kubernetes à fort egress

  • net.netfilter.nf_conntrack_max : pas dans la liste des « cinq » ci‑dessus, mais pour ce rôle c’est du top-tier. Dimensionnez-le délibérément.
  • ip_local_port_range : pertinent pour clients à connexion intensive ou modèles d’egress partagés.
  • fs.file-max : pertinent pour proxies et agents.

Checklist C : Plan de rollback qui marche vraiment

  1. Garder une copie des valeurs avant changement : sysctl -a est verbeux ; enregistrez au moins les clés que vous touchez.
  2. Pour les changements persistants, revertissez le fichier dans /etc/sysctl.d/, puis exécutez sysctl --system.
  3. Si vous devez rollback instantanément, utilisez sysctl -w key=value pour les quelques clés touchées, puis revertissez le fichier après l’incident.
  4. Confirmez avec sysctl key que le rollback a été appliqué.

FAQ

1) Dois-je tuner des sysctls sur Ubuntu 24.04 du tout ?

Uniquement quand vous avez un goulot mesuré et un mode d’échec clair. Les valeurs par défaut conviennent pour un usage général, pas pour chaque cas d’edge à haute charge.

2) Pourquoi ne pas appliquer un « profil performance sysctl » trouvé sur Internet ?

Parce que c’est généralement un mélange de conseils obsolètes, de bascules de sécurité, et d’ajustements spécifiques à une charge présentés comme vérités universelles.
Vous ne fixerez rien et vous compliquerez le débogage.

3) Est-ce que vm.swappiness=1 est toujours le meilleur choix pour des serveurs ?

Non. C’est souvent une bonne politique pour des nœuds sensibles à la latence avec swap activé en dernier recours, mais cela ne résout pas les manques de mémoire.
Si vous swappez sous charge soutenue, ajoutez de la mémoire ou réduisez la charge.

4) Quelle est la vraie relation entre fs.file-max et ulimit -n ?

fs.file-max est un plafond global noyau sur les handles de fichiers. ulimit -n (et systemd LimitNOFILE) limite les fichiers ouverts par processus.
Vous pouvez avoir un plafond système massif et échouer parce qu’un service est plafonné à 1024.

5) J’ai augmenté net.core.somaxconn. Pourquoi je vois encore des drops de connexion ?

Parce que le backlog n’est pas la seule file : la boucle d’accept de votre application peut être lente, le comportement du backlog SYN compte, et la saturation CPU/IRQ peut dropper les paquets plus en amont.
Mesurez où se produit le drop et si le processus accepte effectivement vite.

6) Dois-je tuner les buffers TCP rmem/wmem sur Ubuntu 24.04 ?

Seulement si vous avez prouvé un problème de bandwidth-delay product (liens haute latence et haute bande passante où le débit est limité par la fenêtre)
et que l’autotuning n’est pas suffisant. Sinon vous risquez d’augmenter l’utilisation mémoire et la latence de queue.

7) Le tuning de vm.dirty_ratio est-il sûr ?

C’est sûr quand vous validez : surveillez Dirty/Writeback, I/O await et la latence tail applicative.
C’est dangereux quand vous montez les ratios pour poursuivre le débit ; cela peut fabriquer des stalls de writeback.

8) Comment rendre persistant les changements sysctl « à la manière d’Ubuntu 24.04 » ?

Mettez-les dans /etc/sysctl.d/99-local-tuning.conf (ou similaire), puis exécutez sysctl --system.
Évitez les changements ad-hoc manuels qui disparaissent au reboot.

9) Les conteneurs ignorent-ils les sysctls de l’hôte ?

Certains sysctls sont namespaced et peuvent être définis par conteneur ; d’autres sont globaux au noyau hôte.
En pratique : le tuning côté hôte peut affecter toutes les charges. Traitez-le comme un changement d’infrastructure partagé.

10) Si je ne peux changer qu’une chose pendant un incident, quel est le pari le plus sûr ?

Ça dépend, mais la manœuvre opérationnelle la plus sûre n’est souvent pas un sysctl : réduire la charge (shed traffic), ajouter de la capacité, ou rollbacker un release.
Pour les sysctls, augmenter somaxconn ou élargir la plage de ports peut être peu risqué si vous avez des preuves correspondantes.

Étapes suivantes que vous pouvez réellement faire aujourd’hui

Si vous voulez un tuning noyau qui améliore la fiabilité au lieu de produire du folklore, faites cette séquence :

  1. Choisissez un rôle de nœud (ingress, base de données, NAT, worker). Ne tunez pas « la flotte » au feeling.
  2. Exécutez la section tâches et sauvegardez les sorties comme baseline.
  3. Identifiez le goulot dominant en utilisant le playbook de diagnostic rapide—CPU, mémoire, disque ou réseau.
  4. Changez seulement un des cinq sysctls qui correspond au goulot, et seulement si vous avez des signaux confirmants.
  5. Rendez-le persistant via sysctl.d et documentez la raison dans des commentaires, pas en connaissance tribale.
  6. Re-vérifiez après un reboot et un cycle de trafic. Si vous ne pouvez pas démontrer d’amélioration, revenez en arrière et passez à autre chose.

Le meilleur tuning est celui que vous pouvez expliquer six mois plus tard sans vous excuser. Le deuxième meilleur est celui que vous n’avez pas eu besoin de faire parce que vous avez dimensionné correctement le système.

← Précédent
Montée en chauffe d’un domaine e‑mail : plan pratique pour éviter les signalements instantanés comme spam
Suivant →
MySQL vs MariaDB sur VPS 2 Go : profils de réglage qui ne plantent pas

Laisser un commentaire