ajout de contenu

This commit is contained in:
Jérémy Lecour 2022-09-20 22:10:42 +02:00 committed by Jérémy Lecour
parent f0a225682b
commit 1193dbd0b1

View file

@ -2,41 +2,56 @@
Le but de cette présentation est de montrer comment on peut utiliser HAProxy et Varnish ensemble pour accélérer et fiabiliser des sites et applications web.
Nous allons commencer par les principes généraux et plonger petit à petit dans les détails.
Nous allons commencer par les principes généraux et plonger petit-à-petit dans les détails.
## Pourquoi HAProxy et Varnish ?
Il s'agit de 2 logiciels libres, performants et matures.
Ils ne sont pas les seuls dans leur catégorie, mais ils sont ceux que nous connaissons et apprécions le plus.
Ils sont facilement disponibles sur de nombreuses plateformes. Ils sont très bien documentés et soutenus par des vastes communautés.
Ils disposent aussi de possibilité de support professionnel pour les besoins les plus exigeants.
Ils disposent aussi de possibilités de support professionnel pour les besoins les plus exigeants.
HAProxy va servir de 1er serveur web pour le client HTTP. Il va faire la terminaison TLS, décider si la requête doit être acceptée ou rejetée, transmettre à Varnish s'il est disponible et si on veut faire du cache, et enfin il va transmettre la requête au serveur (singulier) ou serveurs (pluriel) web finaux.
### HAProxy
HAProxy va donc servir de 1er serveur web pour le client HTTP.
Il va faire la terminaison SSL/TLS, décider si la requête doit être acceptée ou rejetée et enfin il va transmettre la requête au serveur (singulier) ou serveurs (pluriel) web finaux.
Il sert donc de proxy, avec des capacités de répartiteur de charge et de tolérance de panne.
Pour rappeler très succinctement les principes de base de HAProxy, on peut mentionner les _frontend_, les _backend_ et le traitement intermédiaire.
Un frontend est un point d'écoute, en TCP ou HTTP, sur un ou plusieurs couples `IP:PORT`, avec une configuration particulière pour les logs, les timeouts, les options, les protocoles supportés.
Il peut y avoir plusieurs frontend, pour avoir des configurations et traitements différents selon les besoins ; par exemple un frontend pour un site web et un autre pour une API dédiée aux applications tierces.
Grace à une analyse et une compréhension complète des protocoles — TCP, mais surtout HTTP — HAProxy peut altérer la requête ou la réponse, décider de la transmettre à telle ou telle entité… Tout ça se fait de manière très optimisée.
Un backend ets un point de sortie du trafic. Il doit y en avoir un pour chaque groupe de serveurs pouvant prendre un erequête en charge. S'il y a un seul serveur dans un backend, il traitera toutes les requêtes. S'il y en a plusieurs, ils se répartiront les requêtes, selon l'algorithme de répartition choisi. C'est là qu'on commence à parler de répartition de charge et de tolérance de panne.
### Varnish
Varnish va servir à mettre en cache le résultat de certaines requêtes pour ne pas avoir à solliciter le serveur applicatif final. Il va appliquer des règles plus ou moins complexes pour décider s'il met en cache,s'il sert depuis le cache…
Je connais mieux HAProxy que Varnish, donc pour cette fois je vais donner plus de détails sur HAProxy.
Varnish propose par défaut un fonctionnement courant et relativement conventionnel qui nécessite généralement peu de configuration.
Les étapes clés du traitement dune requête-réponse HTTP sont gérées par des fonctions dédiées, quil est possible de personnaliser et d'empiler/composer pour modifier le comportement.
Varnish expose toute la requête et la réponse aux fonctions afin de décider sil faut modifier le contenu (ajouter/supprimer/modifier des en-têtes), servir une réponse depuis le cache ou la transmettre au serveur, mettre en cache ou pas la réponse dun serveur…
Varnish stockant toutes les données de cache en mémoire, il est aussi important de décider selon quel algorithme décider ce qui doit être détruit lorsque la capacité maximale est atteinte…
## Comment combiner HAProxy et Varnish
HAProxy fonctionne selon le principe de « frontend/backend ».
Nous avons donc choisir de mettre ces 2 logiciels ensemble, de manière coordonnée, pour un résultat performant et riche en fonctionnalités.
Un « frontend » est un point d'entrée HTTP (ou TCP) sur un ou plusieurs couples « IP:PORT ».
Comme dit précédemment, HAProxy utilise des _frontend_ comme point d'entrée te des backends commepoint de sortie.
En mode HTTP il permet d'analyser tous les éléments de la requête pour prendre des décisions.
Il passe ensuite la requête à un « backend » qui définit la façon dont on parle à l'élément suivant dans la chaîne. Le plus souvent il s'agit d'un ou plusieurs serveurs d'application. On y gère les éventuelles règles de répartition de charge ou de bascule en cas d'incident, les mécanismes de surveillance de disponibilité…
Dans notre cas, pour l'exemple typique, c'est à Varnish que HAProxy va passer la requête.
Dans notre cas, après avoir pris en charge la requête du client HTTP, HAProxy va la transmettre à Varnish,via un backend spécifique.
Nous avons choisi de placer HAProxy et Varnish sur le même serveur, et de les faire communiquer par socket, mais c'est un détail et rien n'empêche de les mettre sur des serveurs différents.
Une fois la requête transmise à Varnish, il va également l'analyser pour décider s'il peut servir une réponse depuis le cache ou s'il doit la faire passer. Et s'il l'a fait passer, lors du retour il va décider s'il peut la mettre en cache.
Dans le cas le plus courant d'utilisation de Varnish, lorsqu'il dit faire passer une requête, il le fait directement au serveur d'application. Nous avons choisi de faire un peu différemment et de ne pas gérer dans Varnish la partie load-balancing et tolérance de panne, car elle est gérée de manière plus complète par HAProxy, et c'est ce que nous maitrisons le mieux.
Dans le cas le plus courant d'utilisation de Varnish, lorsqu'il doit faire passer une requête, il le fait directement au serveur d'application (lui-aussi appelle ça un _backend_). Nous avons choisi de faire un peu différemment et de ne pas gérer dans Varnish la partie load-balancing et tolérance de panne, car elle est gérée de manière plus complète par HAProxy, et c'est ce que nous maitrisons le mieux.
Varnish va donc renvoyer la requête à HAProxy, le même que celui qui a traité la requête entrante.
Mais pour ne pas tomber dans une boucle, et pour ne pas refaire certaines analyses déjà faites au début, nous faisons entrer la requête par un autre « frontend ». Celui-ci sera plus simple et aura comme principale responsabilité de choisir le « backend » final à utiliser pour la requête. Si vous gérer des sites ou applications qui sont réparties sur des groupes de serveurs différents, il faut avoir autant de « backen » que de groupes de serveur.
Mais pour ne pas tomber dans une boucle, et pour ne pas refaire certaines analyses déjà faites au début, nous faisons entrer la requête par un autre _frontend_. Celui-ci sera plus simple et aura comme principale responsabilité de choisir le _backend_ final à utiliser pour la requête. Si vous gérez des sites ou applications qui sont réparties sur des groupes de serveurs différents, il faut avoir autant de _backend_ que de groupes de serveurs.
Au final on passe donc la requête aux serveurs web qui vont effectivement traiter la requête.
@ -44,17 +59,33 @@ La réponse fera le chemin inverse, en revenant à HAProxy, puis Varnish (qui d
Chaîne :
1. HAProxy frontend « external » (général)
2. HAProxy backend « varnish »
1. HAProxy _frontend_ « external » (général)
2. HAProxy _backend_ « varnish »
3. Varnish
4. HAProxy frontend « internal » (général)
5. HAProxy backend « site X » (par site)
4. HAProxy _frontend_ « internal » (général)
5. HAProxy _backend_ « site X » (par site)
6. Web-server
## Multi-sites
Même en faisant passer tout le trafic entrant (http/https) par un seul _frontend_,il est tout à fait possible d'avoir des serveurs finaux spécifiques pour chaque site, ainsi que des traitements intérmédiaires specifiques aussi.
Il n'y a pas dans HAProxy de logique ressemblant aux `VirtualHost` de Apache ou Nginx, mais on peut utiliser des primitives conditionnelles plus bas-niveau pour cela.
On crée (au moins) une ACL pour détecter si l'hôte demandée est lié à tel ou tel site, et plus oin on utilise ces ACL pour conditionnement un comportement.
```
frontend external
acl example_com_domains hdr(host) -i example.com
acl foo_bar_domains hdr(host) -i foo-bar.com foo-bar.org
[…]
use_backend example_com if example_com_domains
use_backend foo_bar if foo_bar_domains
```
## Fallback if Varnish is DOWN
Dans la configuration de HAProxy, nous avons créé un backend Varnish, avec un seul serveur final.
Dans la configuration de HAProxy, nous avons créé un _backend_ « varnish », avec un seul serveur final.
```
backend varnish