Je me gratte la tête depuis quelques jours, essayant de trouver une solution au problème suivant:
Dans notre centre de données, nous avons un F5 fonctionnant sur du matériel BigIP qui agit comme un point d'entrée unique pour les demandes HTTPS des machines clientes dans divers bureaux à travers le pays. F5 met fin à TLS puis transfère toutes les demandes à deux équilibreurs de charge Traefik, qui acheminent la distribution des demandes vers les différentes instances de service (les nœuds Traefik s'exécutent dans Docker sur Red Hat Enterprise, mais je pense que cela n'est pas pertinent pour mon problème). Du point de vue du débit, du processeur et de la mémoire, ces trois composants réseau sont plus que capables de gérer la quantité de demandes et de trafic avec une grande capacité à revendre.
Cependant, nous avons remarqué des retards fréquents de 1000 ms dans les requêtes HTTP (S) que les clients effectuent, en particulier pendant les périodes de charge élevée. Nous avons suivi le problème jusqu'à la cause racine suivante:
De toute évidence, ces retards de 1000 ms sont absolument inacceptables. Nous avons donc envisagé les solutions suivantes jusqu'à présent:
Je vais jeter # 1 parce que c'est juste un pansement. Des retards se produisent encore, un peu moins notables. Le n ° 3 n'aurait aucun effet de toute façon, le n ° 4 rendrait très probablement le système non fonctionnel. Cela laisse # 2 et # 5.
Mais d'après ce que j'ai appris après avoir lu des dizaines de messages et d'articles techniques, les deux réduiront finalement les risques de ces "collisions". Parce que, ce qui empêche finalement le côté émetteur, F5, de choisir (pseudo) aléatoirement une combinaison de port éphémère, IP source et port cible qui existe toujours dans l'état TIME_WAIT sur l'hôte Traefik cible, quelle que soit la longueur du paramètre fin_timeout (qui devrait rester dans la plage de plusieurs secondes de toute façon)? Nous ne ferions que réduire la possibilité de collisions, pas l'éliminer.
Après toutes mes recherches et à l'époque des applications web gigantesques, cela m'étonne vraiment que ce problème ne soit plus discuté sur le web (et les solutions disponibles). J'apprécierais vraiment vos pensées et vos idées pour savoir s'il existe une meilleure solution, plus systématique dans TCP terrain qui conduira à la survenue de collisions près de zéro. Je pense dans le sens d'un TCP configuration qui permettra à l'hôte Traefik d'accepter immédiatement une nouvelle connexion malgré une ancienne connexion en état TIME_WAIT. Mais pour l'instant, pas de chance pour le trouver.
Pensées et points aléatoires:
Update: Per The Star Experiment , le net.ipv4. Le paramètre tcp_fin_timeout n'affecte PAS l'état TIME_WAIT, uniquement l'état FIN_WAIT_2. Et par Samir Jafferali , sur les systèmes Linux (y compris notre Red Hat Linux), la période TIME_WAIT est codée en dur dans le code source et ne peut pas être configurée. Sur BSD selon la source, il est configurable mais je ne l'ai pas vérifié.
Dans notre centre de données, nous avons un F5 fonctionnant sur du matériel BigIP qui agit comme nique point d'entrée pour les requêtes HTTPS à partir des ordinateurs clients dans nos différents bureaux à travers le pays .
Si ce point unique (front-end) reste unique lorsqu'il transmet les connexions au back-end, pourquoi vous posez-vous des questions sur le hoquet? Surtout si l'intensité des connexions est "peut-être 100+ par seconde".
Votre configuration consiste à presser un ensemble avec une cardinalité plus élevée dans un autre avec une cardinalité nettement inférieure.
en fin de compte seulement réduire les risques de ces "collisions"
Ceci est mis dans la base du fonctionnement des réseaux à commutation de paquets. Disons qu'au niveau Ethernet, il y a aussi des collisions. L'aléatoire est inévitable et TCP/IP s'en occupe. Le protocole IP lui-même n'a pas été construit en pensant aux réseaux locaux (mais fonctionne toujours très bien là aussi).
Donc oui "Ajouter plus d'adresses IP source et/ou faire écouter Traefik sur plusieurs ports" est une façon assez raisonnable de suivre.
Bien que je pense également que l'ajout d'autres adresses IP est la voie la plus simple, avez-vous envisagé d'explorer la réutilisation des connexions TCP entre le F5 et les nœuds Traefik au lieu d'en créer une nouvelle par demande externe?
Je ne sais pas comment F5 prend en charge cela, mais c'est peut-être aussi simple que de passer à http2 entre le F5 et les nœuds Traefik. Voir https://developers.google.com/web/fundamentals/performance/http2#one_connection_per_Origin
Il s'avère que était une solution très simple à ce problème après tout, que nous avons découvert après avoir travaillé avec le fournisseur Traefik pendant un certain temps. Il s'avère également que le fait que nous exécutons Traefik dans Docker le fait importe. Le problème et la solution sont très spécifiques à notre configuration, mais je veux toujours le documenter ici au cas où d'autres rencontreraient la même chose. Néanmoins, cela n'induit pas pas les autres recommandations, plus générales, car les collisions d'ID d'instance sont un vrai problème.
En bref: toutes les instances de Traefik sont configurées en tant que conteneurs contraints par l'hôte (c'est-à-dire liés à des hôtes spécifiques) exécutés dans un cluster Docker Swarm. Les instances de Traefik doivent exposer un port au niveau de l'hôte afin qu'elles deviennent accessibles à partir du F5, qui n'est évidemment pas un participant Docker Swarm. Ces ports exposés avaient été configurés en mode d'entrée , ce qui était non seulement inutile (pas besoin d'acheminer le trafic via le réseau d'entrée Docker Swarm) mais était également le cause pour les paquets SYN abandonnés/ignorés. Une fois que nous avons commuté le mode de port sur Host , les retards ont disparu.
Avant:
ports:
- target: 8080
published: 8080
protocol: tcp
mode: ingress
Après:
ports:
- target: 8080
published: 8080
protocol: tcp
mode: Host