Base de connaissances

Paramètres du noyau pour beaucoup de connexions ouvertes

Les valeurs sysctl et les limites systemd qui comptent quand une machine détient des dizaines de milliers de sockets, et celles copiées de vieux articles de blog qui ne font rien.

Mesurer d'abord

ss -s
cat /proc/sys/fs/file-nr
nstat -az TcpExtListenOverflows TcpExtListenDrops

ListenOverflows qui grimpe signifie que la file d'attente d'acceptation est pleine et que le noyau jette les poignées de main terminées. C'est un problème précis avec un correctif précis. La plupart des autres symptômes ne sont pas résolus par sysctl du tout, et régler une machine qui n'est pas sous pression ne fait que déplacer l'échec final vers un endroit plus difficile à trouver.

Les réglages qui méritent leur place

# /etc/sysctl.d/90-connections.conf
fs.file-max = 2097152
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 32768
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_mtu_probing = 1
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
sysctl --system
sysctl net.ipv4.tcp_congestion_control

Ce que chacun fait :

  • somaxconn plafonne la file d'attente d'acceptation, et votre application doit encore la demander. Dans nginx, c'est listen ... backlog=65535 ; dans la plupart des langages, c'est le deuxième argument de listen().
  • ip_local_port_range compte côté client. Un proxy ouvrant des connexions sortantes vers une seule destination épuise les ports éphémères à environ vingt-huit mille avec la plage par défaut.
  • tcp_tw_reuse permet au noyau de réutiliser les sockets TIMEWAIT pour de nouvelles connexions sortantes. Sans danger. Son cousin `tcptw_recycle` a été retiré de Linux en 4.12, et tout guide qui le recommende encore a été écrit avant 2017.
  • fq avec bbr est une vraie amélioration sur les chemins longs ou avec pertes, et un lavage sur les chemins courts et propres. Les deux sont dans les noyaux standard.

Suivi de connexion

Un pare-feu avec état donne à chaque connexion une entrée conntrack, et la table a un plafond. L'atteindre fait tomber les paquets et écrit nf_conntrack: table full dans le journal du noyau.

sysctl net.netfilter.nf_conntrack_max net.netfilter.nf_conntrack_count

Augmentez-le si vous avez la mémoire — chaque entrée coûte quelques centaines d'octets :

net.netfilter.nf_conntrack_max = 1048576

Là où la charge de travail est un service public sans état, la meilleure réponse est de ne pas le suivre :

table inet raw {
  chain prerouting {
    type filter hook prerouting priority raw;
    tcp dport 443 notrack
  }
}

Les limites que systemd ignore

/etc/security/limits.conf s'applique aux connexions via PAM. Il n'a aucun effet sur un service démarré par systemd, c'est pourquoi augmenter nofile là et redémarrer nginx ne change strictement rien. Définissez-le sur l'unité :

mkdir -p /etc/systemd/system/nginx.service.d
cat > /etc/systemd/system/nginx.service.d/limits.conf <<EOF
[Service]
LimitNOFILE=1048576
EOF
systemctl daemon-reload
systemctl restart nginx

Vérifiez avec le service en cours plutôt qu'avec le fichier que vous venez d'écrire :

systemctl show nginx -p LimitNOFILE

Trois choses à ne pas faire

  • Ne collez pas un fichier sysctl de cinquante lignes depuis un forum. La moitié vise un noyau qui n'a pas été distribué depuis dix ans, et une ligne cassera silencieusement la découverte de MTU de chemin.
  • N'augmentez pas tcp_rmem et tcp_wmem sans un long chemin gras pour le justifier. Sur un chemin d'une milliseconde, des tampons plus grands achètent de la latence et de la pression mémoire.
  • Ne désactivez pas tcp_timestamps. Vous perdez l'estimation du temps de parcours et PAWS, et vous gagnez une rumeur sur les performances.

Mesurez à nouveau après chaque changement, un changement à la fois, et gardez le fichier dans le contrôle de version pour que la personne suivante puisse voir ce que vous avez fait et pourquoi.

Prêt quand vous l'êtes

Choisissez une ville. Choisissez une taille. Payez en crypto.

Aucun formulaire sur votre identité, pas d'attente d'approbation humaine, pas d'appel téléphonique pour vérifier quoi que ce soit. La facture est réglée et les identifiants arrivent dans votre boîte mail.