Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Haute disponibilité sous Linux
  3. Exposition et répartition
Extrait - Haute disponibilité sous Linux De l'infrastructure à l'orchestration de services (Heartbeat, Docker, Ansible, Kubernetes...) (2e édition)
Extraits du livre
Haute disponibilité sous Linux De l'infrastructure à l'orchestration de services (Heartbeat, Docker, Ansible, Kubernetes...) (2e édition) Revenir à la page d'achat du livre

Exposition et répartition

Exposer ses services

1. Problématique

Dans le chapitre Les containers, nous avons vu comment créer des images réutilisables de notre application eni-todo et comment, grâce aux containers, les déployer sur un ou plusieurs serveurs. Mais nous n’avons pas encore vu comment y accéder depuis un point d’entrée unique. Il faut résoudre plusieurs problèmes.

Tout d’abord, chaque container, une fois démarré, dispose de sa propre adresse IP sur un réseau local à la machine et non routé, c’est-à-dire non accessible depuis un autre point du réseau. Il faut trouver une méthode pour que l’application s’exécutant de manière isolée puisse être accessible via, par exemple, l’adresse IP du serveur.

Ensuite, le service applicatif eni-todo est maintenant réparti sur deux serveurs, au moins, afin de garantir sa disponibilité en cas de perte d’une des machines. Or, il faut un point d’accès unique : une adresse, qui renverra les requêtes sur un serveur ou l’autre, mais qui devra aussi être capable de détecter l’indisponibilité de l’application sur un ou plusieurs serveurs pour renvoyer le trafic vers ceux encore actifs.

Si le service doit être exposé sur Internet, il faut pouvoir lui associer une adresse IP publique....

Reverse proxy

1. Pourquoi utiliser un reverse proxy ?

Chaque container démarré sur le serveur dispose de sa propre adresse IP. Cette adresse peut être obtenue simplement avec la commande docker et le nom ou l’identifiant du container :

$ docker container ps 
CONTAINER ID   IMAGE     COMMAND      CREATED    STATUS    PORTS     NAMES 
296364ae3c93   registry.diehard.net:5000/tomcat-eni-todo:v24.04-eni-
todo-tomcat-mariadb-env   "catalina.sh run"   16 minutes ago   Up  
16 minutes   0.0.0.0:8080->8080/tcp   tomcat-production-eni-todo_1_v24.04- 
eni-todo-tomcat-mariadb-env 
$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' 296364ae3c93 
172.17.0.2 

Depuis le serveur lui-même, il est possible de vérifier que le service tournant dans le container fonctionne, avec une simple requête curl :

$ curl -I http://172.17.0.2:8080/eni-todo/ 
HTTP/1.1 200 
Set-Cookie: JSESSIONID=5EFB90378D2336F11E2FFF6348BD6510; Path=/eni- 
todo; HttpOnly 
Content-Type: text/html;charset=UTF-8 
Content-Language: en 
Content-Length: 3333 
Date: Sat, 16 Mar 2024 12:45:40 GMT 

Pour le moment, tenter la même chose depuis l’adresse IP du serveur fonctionne aussi, car nous avons associé le port 8080 du serveur à celui du container que nous avons démarré. Empêcher un accès direct à l’application est une mauvaise idée. Démarrer plusieurs applications utilisant le port 8080 est impossible : plusieurs applications ne peuvent écouter directement sur une même paire IP:Port.

$ curl -I http://192.168.56.30:8080/eni-todo/ 
HTTP/1.1 200 
$ nc -l -s 192.168.56.30 -p 8080 
nc: Address already in use 

On peut aussi démarrer le container en utilisant le réseau de l’hôte, c’est-à-dire du serveur. Dans ce cas, le container utilise les adresses et les ports du serveur, il n’y a plus d’isolation du réseau. Mais là encore, deux containers ne peuvent pas utiliser le même port de l’hôte.

$ docker run --network=host ... 

Nous pourrions envisager d’autres solutions, bas niveau, avec Netfilter, du NAT (Network Address Translation), mais nous retomberions sur les mêmes...

Répartition de charge

1. Présentation

Maintenant que les services conteneurisés sont accessibles depuis l’adresse IP d’un hôte, il nous faut exposer l’ensemble de ces services, et donc des hôtes, à l’ensemble des clients, que ce soit sur le réseau d’entreprise (l’intranet) ou un réseau public (Internet). Les tests précédents ne concernaient qu’un seul hôte. Or, le service sera déployé sur au moins deux hôtes. Nous n’allons pas exposer directement un serveur applicatif sur Internet. Les services étant répartis sur plusieurs serveurs, un processus de décision est nécessaire afin de répartir la charge sur l’ensemble des services.

Un load balancer, ou répartiteur de charge, a pour but de répartir les connexions des clients sur plusieurs serveurs ou services, selon des critères de décision. Le répartiteur a, normalement, au moins deux interfaces réseau : une accessible depuis le réseau qui expose l’adresse IP aux clients, et une autre sur un sous-réseau interne dédié, par lequel il accède aux hôtes (on peut n’avoir qu’une seule interface si l’IP exposée est dans le même sous-réseau que les serveurs). 

Le répartiteur de charge a pour premier rôle celui...

Solution de répartition de charge

1. Choix des produits

On a besoin, a minima, de trois produits pour mettre en place cette architecture. Le répartiteur de charge lui-même doit prendre en charge la connexion d’un client à un service et la renvoyer vers un hôte (l’hôte se chargeant, via son reverse proxy, de la renvoyer vers un container). S’agissant de gérer plusieurs types de protocoles et des règles en fonction de ces protocoles (mutualisation des adresses et routage en fonction des noms d’hôtes), ceci exclut d’office une solution basée uniquement sur les couches 3 et 4 du modèle OSI (Open Systems Interconnection). Ce qui signifie que pour son rôle de répartiteur, Keepalived ne peut pas être retenu. Nous utiliserons la meilleure solution actuelle : HAProxy.

Les adresses IP des services peuvent être configurées manuellement sur les interfaces idoines. Mais comment les faire basculer simplement d’un répartiteur à un autre ? C’est là que le protocole VRRP (Virtual Router Redundancy Protocol) montre toute sa puissance. Nous utiliserons le module associé de Keepalived, qui nous servira à gérer un routeur virtuel composé d’au moins deux routeurs physiques, et qui prendra en charge la haute disponibilité des adresses IP.

L’exposition d’une adresse IP sur Internet est différente d’une exposition sur un réseau privé. L’adresse doit être annoncée aux différents routeurs via des protocoles spécialisés comme OSPF et BGP. Ces protocoles peuvent être configurés à l’aide de FRRouting.

2. HAProxy

a. Présentation

HAProxy est un logiciel libre initialement développé par Willy Tarreau, dont la première version date de 2001 et qui fournit un service de répartition de charge (load balancing) et de proxy en haute disponibilité. Il gère les protocoles HTTP (niveau 7) et TCP (niveau 4). Il est écrit en C, très performant, peu gourmand en ressources (mémoire et processeur) et tient très bien la charge. Il est utilisé par de très nombreux sites, dont certains l’annoncent publiquement : GitHub, Reddit, Slack, Twitter, Tumblr, Bitbucket, GoDaddy...

Exposition Internet

Si tout est relativement simple sur un réseau interne, où une adresse IP est unique sur un sous-réseau donné, c’est totalement différent quand il s’agit d’une IP exposée sur Internet : c’est une IP publique.

Sur un réseau privé, il y a globalement trois blocs d’adresses utilisables à volonté et comme bon nous semble et qui ne sont pas routables sur Internet. Par exemple, en IPv4, les blocs les plus connus sont issus des anciennes classes :

  • 10.0.0.0/8

  • 172.16.0.0/12

  • 192.168.0.0/16

Il y a aussi quelques autres blocs pour des usages spécifiques (bouclage/loopback, multicast, broadcast, tests, 6to4, etc.). Vous trouverez la liste de ces blocs d’adresses réservées dans le RFC 6890 à cet endroit : https://www.rfc-editor.org/info/rfc6890

En dehors de tous ces blocs réservés, toutes les adresses sont publiques et utilisables sur Internet. Cela ne signifie pas que nous pouvons juste choisir une IP aléatoirement si elle semble libre et l’utiliser. Les adresses sont payantes et des organismes sont chargés de gérer leur usage. L’IANA (Internet Assigned Numbers Authority) distribue des blocs aux RIR (registres internet régionaux) : RIPE-NCC pour l’Europe, APNIC pour l’Asie-Pacifique, ARIN pour l’Amérique du Nord, LACNIC pour l’Amérique centrale et du Sud, et AfriNIC pour l’Afrique.

Chaque RIR vend des blocs d’adresses à qui souhaite en acheter, libre aux acheteurs de les utiliser comme ils le souhaitent. Notre fournisseur d’accès par exemple peut nous fournir une IP fixe, IPv4 ou IPv6...

Solution d’exposition Internet avec FRRouting

L’Ops ou le DevOps n’ont pas pour rôle (en théorie tout au moins) de configurer eux-mêmes tout le routage BGP ou OSPF, mais ils sont chargés d’annoncer ses routes et IP (publiques dans ce cas) aux autres routeurs de l’infrastructure, qui sont en principe déjà en place. Ils doivent cependant connaître les équipements auxquels annoncer ces routes.

Nous allons faire ici le choix d’annoncer nos adresses IP publiques via le protocole OSPF. Les routeurs avec lesquels nous communiquerons devront accepter d’exposer les informations reçues sur Internet via le protocole BGP.

Il est possible de configurer Linux comme un routeur acceptant l’ensemble de ces protocoles. La suite de logiciels de routage FRRouting implémente OSPF, RIP, BGP, IS-IS et d’autres encore, en IPv4 et IPv6. C’est OSPF qui nous intéresse ici.

1. Implémentation

Dans cette section, la simplicité est de mise pour une meilleure compréhension.

Les répartiteurs de charge sont basés sur VRRP (Keepalived). Ils vont porter les adresses IP publiques sur une interface réseau dédiée et directement exposée, et donc accessible, sur Internet. Cela signifie que nous allons directement configurer une ou plusieurs IP publiques sur cette interface, comme s’il s’agissait d’IP quelconques, et donc ces adresses seront visibles avec une commande ip addr show.

D’autres méthodes sont possibles comme configurer les adresses sur l’interface de loopback, modifier les tables ARP et la configuration dynamique du noyau pour accepter des paquets IP non configurés sur les interfaces. On peut aussi utiliser FRRouting pour configurer les interfaces.

Mais comme nous avons utilisé la configuration VRRP pour la haute disponibilité de nos VIP, nous allons faire de même pour configurer nos adresses IP publiques. FRRouting a pour rôle d’annoncer ces adresses aux autres routeurs, leur donnant ainsi la route pour y accéder depuis Internet.

Nos répartiteurs de charge se voient donc ajouter une troisième couche, OSPF, pour annoncer les IP publiques qu’ils portent sur Internet, celles qui ont été configurées comme VIP sur les routeurs maîtres VRRP.

2. Installation...