La gestion des clusters applicatifs sous Linux
Un cluster pourquoi faire?
La mise en place d’un cluster applicatif répond à un besoin de haute disponibilité et/ou d’équilibrage de charge pour servir un grand nombre de demandes simultanées.
Pour répondre à ces besoins, il existe de multiples solutions possibles dont voici quelques exemples :
- DNS round robin : Cette méthode est la plus simple à mettre en œuvre mais elle ne répond pas à la problématique de haute disponibilité. Si l’un des serveurs ne répond plus, le DNS continuera de délivrer des requêtes sur son adresse IP.
- Cluster physique : Une ferme de serveurs physiques hébergeant des machines virtuelles peut répondre aux 2 besoins. SI l’un des serveurs physiques ne répond plus, la ferme redistribuera les machines virtuelles sur les autres serveurs et le service sera toujours rendu. Le point négatif de ce genre de solution, c’est qu’il ne prend pas en charge la défaillance du service, mais seulement la défaillance du serveur hébergeant la machine virtuelle.
- Cluster applicatif : Le cluster applicatif répond au 2 besoins et il peut se déployer sur une ferme de serveurs, ou sur des serveurs physiques non clusterisés.
Éventail de solution de clustering applicatif
Dans l’éventail des solutions de clustering applicatif, nous allons nous limiter à la solution Pacemaker/Corosync. Cette solution est disponible sur plusieurs distributions Linux, le produit est open source (GPL v2 & LGPL v2) et permet de gérer le basculement.
Parmi les autres solutions existantes, on peut citer :
- Veritas Cluster server: solution payante mais multi plateforme
- Cluster Windows NLB: Solution disponible uniquement sous Windows
- Elastic Load Balancing: Solution uniquement disponible sur un environnement EC2
- Keepalived: Solution disponible sous Linux et open source (GPL v2)
- HeartBeat: Solution disponible sous Linux, peut être associé à Pacemaker en tant que gestionnaire de cluster
- OpenSVC: Disponible sous Linux et open source (GPL v2)
Présentation de Pacemaker et Corosync
Pacemaker est un gestionnaire de cluster qui peut être associé à Corosync ou à HeartBeat. Pacemaker propose une interface de gestion du cluster et permet de définir, démarrer ou arrêter les ressources. Il propose aussi une IHM de gestion du cluster.
Corosync est la couche de communication du cluster. C’est Corosync qui se chargera de transmettre l’état des nœuds et d’exécuter les opérations transmises par Pacemaker.
L’avantage de cette solution est qu’elle gère nativement un grand nombre d’applications que l’on peut trouver sur un serveur Linux. L’installation de pacemaker permettra d’utiliser ces agents de ressources permettant ainsi de gérer :
- apache
- nginx
- Oracle
- PostgreSQL
- slapd
- et bien d’autres encore…
Au besoin, on pourra développer son propre agent de ressources, ou modifier un agent existant.
Configuration en mode actif/actif
On peut configurer le cluster pacemaker en actif/passif ou même avec seulement 2 nœuds, vous trouverez ici une description des autres possibilités de configuration pour un cluster pacemaker.
Pour la configuration suivante de pacemaker, nous allons configurer un cluster de 3 serveurs frontaux apache. Dans cette configuration, les serveurs sont en disponibilité actif/actif, c’est à dire que tous les nœuds du cluster répondront aux requêtes, et que la perte d’1 ou 2 serveurs ne perturbera pas le service rendu.
Pour la configuration suivante, nous avons 3 VM Centos version 7.5 configurées avec une IP statique sur un sous réseau /24. Le service NTP est activé pour s’assurer que les différents nœuds sont synchronisés sur la même horloge.
Dans notre cas, nous n’avons pas de serveur DNS, il faut donc inscrire tous les nœuds et l’adresse VIP dans le fichier hosts des chacun des nœuds :
1 2 3 4 5 |
sudo vi /etc/hosts 192.168.1.100 vip 192.168.1.101 node1 192.168.1.102 node2 192.168.1.103 node3 |
Nous installons ensuite les paquets pacemaker et pcs :
1 |
sudo yum install pacemaker pcs httpd -y |
Puis on configure apache en changeant la page par défaut, on indique le numéro du nœud pour permettre plus tard de savoir quel nœud nous répondra :
1 2 3 4 5 |
sudo systemctl enable httpd sudo systemctl start httpd sudo sed -i 's/Testing 123/Node 1/g' /usr/share/httpd/noindex/index.html sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --reload |
On configure le démon pcs pour démarrer automatiquement, et on règle ensuite le mot de passe du compte hacluster (créé automatiquement pendant l’installation du paquet pacemaker). Il faudra impérativement positionner le même mot de passe pour tous les nœuds :
1 2 3 4 5 6 |
sudo systemctl enable pcsd sudo systemctl enable corosync sudo systemctl enable pacemaker sudo systemctl start pcsd sudo passwd hacluster sudo firewall-cmd --permanent --add-service=high-availability |
Après avoir réalisé les actions précédentes sur les 3 nœuds, nous allons commencer la configuration de notre cluster. Les commandes suivantes sont à jouer sur un seul des nœuds. Il faudra compléter le champ username avec le nom du compte hacluster et le password, avec celui renseigné sur tous les nœuds :
1 2 3 4 5 6 7 |
sudo pcs cluster auth node1 node2 node3 Username: hacluster Password: node1: Authorized node3: Authorized node2: Authorized |
Les 3 nœuds apparaissent bien dans le résultat de la commande, donc notre cluster est maintenant créé. Tous les nœuds communiquent et les configurations que nous ferons par la suite seront dupliquées sur tous les nœuds.
Création du cluster
Nous allons donc créer une configuration qui sera répliquée sur les nœuds du cluster :
1 |
sudo pcs cluster setup --name blogTech node1 node2 node3 |
Le résultat de la commande doit être le suivant :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Destroying cluster on nodes: node1, node2, node3... node2: Stopping Cluster (pacemaker)... node1: Stopping Cluster (pacemaker)... node3: Stopping Cluster (pacemaker)... node3: Successfully destroyed cluster node1: Successfully destroyed cluster node2: Successfully destroyed cluster Sending 'pacemaker_remote authkey' to 'node1', 'node2', 'node3' node1: successful distribution of the file 'pacemaker_remote authkey' node2: successful distribution of the file 'pacemaker_remote authkey' node3: successful distribution of the file 'pacemaker_remote authkey' Sending cluster config files to the nodes... node1: Succeeded node2: Succeeded node3: Succeeded Synchronizing pcsd certificates on nodes node1, node2, node3... node1: Success node3: Success node2: Success Restarting pcsd on the nodes in order to reload the certificates... node1: Success node3: Success node2: Success |
Notre cluster est maintenant correctement configuré. La configuration de corosync a été générée puis appliquée sur tous les nœuds. Nous pouvons donc démarrer le cluster :
1 |
sudo pcs cluster start --all |
Ensuite, nous vérifions l’état du cluster avec la commande :
1 |
sudo pcs status |
Le résultat de la commande doit indiquer que tous les nœuds sont en ligne, et que les démons sont actifs et activés :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Cluster name: blogTech WARNING: no stonith devices and stonith-enabled is not false Stack: corosync Current DC: node3 (version 1.1.18-11.el7_5.3-2b07d5c5a9) - partition with quorum Last updated: Thu Aug 30 19:17:20 2018 Last change: Thu Aug 30 19:10:02 2018 by hacluster via crmd on node3 3 nodes configured 0 resources configured Online: [ node1 node2 node3 ] No resources Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled |
Ajout des ressources
Créons maintenant notre première ressource, une adresse VIP :
1 |
sudo pcs resource create Cluster_blogTechVIP ocf:heartbeat:IPaddr2 ip=192.168.1.100 cidr_netmask=24 op monitor interval=20s clone |
Créons ensuite notre ressource apache :
1 |
sudo pcs resource create blogTechWeb ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://127.0.0.1/server-status" op monitor interval=20s |
Nous pouvons ensuite vérifier l’état de notre cluster et des ressources que nous venons de créer :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
sudo pcs status Cluster name: blogTech WARNING: no stonith devices and stonith-enabled is not false Stack: corosync Current DC: node2 (version 1.1.18-11.el7_5.3-2b07d5c5a9) - partition with quorum Last updated: Fri Aug 31 09:36:17 2018 Last change: Fri Aug 31 09:35:41 2018 by root via cibadmin on node1 3 nodes configured 6 resources configured Online: [ node1 node2 node3 ] Full list of resources: Clone Set: Cluster_blogTechVIP-clone [Cluster_blogTechVIP] Stopped: [ node1 node2 node3 ] Clone Set: blogTechWeb-clone [blogTechWeb] Stopped: [ node1 node2 node3 ] Daemon Status: corosync: active/disabled pacemaker: active/disabled pcsd: active/enabled |
Le résultat nous montre que le cluster est toujours actif. Les ressources sont bien clonées sur tous les nœuds mais elles sont arrêtées.
Les ressources ne démarrent pas à cause du paramétrage du stonith. Ce paramètre permet de configurer le cluster en ajoutant un équipement hors du cluster, qui agit comme témoin. Dans le cas de défaillance d’un nœud, cet équipement permettra de faire la différence entre un nœud qui ne fonctionne plus et une coupure réseau entre les nœuds. Cette documentation présente les différents paramètres de stonith.
Dans notre cas, nous n’allons pas choisir d’équipement externe, et donc la commande suivante permet de désactiver le stontih :
1 |
pcs property set stonith-enabled=false |
On peut voir que la ressource IP démarre correctement sur tous les nœuds, mais la ressource apache, elle, ne démarre pas correctement :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
Cluster name: blogTech Stack: corosync Current DC: node3 (version 1.1.18-11.el7_5.3-2b07d5c5a9) - partition with quorum Last updated: Fri Aug 31 10:12:46 2018 Last change: Fri Aug 31 10:09:00 2018 by hacluster via crmd on node2 3 nodes configured 6 resources configured Online: [ node1 node2 node3 ] Full list of resources: Clone Set: Cluster_blogTechVIP-clone [Cluster_blogTechVIP] Started: [ node1 node2 node3 ] Clone Set: blogTechWeb-clone [blogTechWeb] Started: [ node1 ] Stopped: [ node2 node3 ] Failed Actions: * blogTechWeb_start_0 on node2 'unknown error' (1): call=33, status=Timed Out, exitreason='', last-rc-change='Fri Aug 31 10:09:01 2018', queued=0ms, exec=40003ms * blogTechWeb_start_0 on node3 'unknown error' (1): call=32, status=Timed Out, exitreason='', last-rc-change='Fri Aug 31 10:09:01 2018', queued=0ms, exec=40004ms Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled |
En fait, pacemaker doit pouvoir démarrer et arrêter lui même le process, il faut donc désactiver le démarrage automatique d’apache et arrêter le process sur tous les nœuds du cluster :
1 2 |
sudo systemctl disable httpd sudo systemctl stop httpd |
En vérifiant de nouveau les ressources, nous pouvons voir que toutes les ressources sont correctement démarrées sur tous les nœuds :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
sudo pcs status Cluster name: blogTech Stack: corosync Current DC: node3 (version 1.1.18-11.el7_5.3-2b07d5c5a9) - partition with quorum Last updated: Fri Aug 31 10:13:23 2018 Last change: Fri Aug 31 10:13:20 2018 by hacluster via crmd on node2 3 nodes configured 6 resources configured Online: [ node1 node2 node3 ] Full list of resources: Clone Set: Cluster_blogTechVIP-clone [Cluster_blogTechVIP] Started: [ node1 node2 node3 ] Clone Set: blogTechWeb-clone [blogTechWeb] Started: [ node1 node2 node3 ] Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled |
A partir de maintenant, notre cluster est monté et toutes les ressources sont actives, nous pouvons commencer une série de tests sur le cluster.
Load-balancing
On peut voir que l’adresse VIP est correctement montée sur tous les noeuds :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 08:00:27:3f:97:4c brd ff:ff:ff:ff:ff:ff inet 192.168.1.101/24 brd 192.168.1.255 scope global noprefixroute enp0s3 valid_lft forever preferred_lft forever inet 192.168.1.100/24 brd 192.168.1.255 scope global secondary enp0s3 valid_lft forever preferred_lft forever inet6 fe80::570c:68d:6e12:6e76/64 scope link noprefixroute valid_lft forever preferred_lft forever |
Ensuite nous pouvons voir quel nœud répond, en lançant la commande à partir d’une vm ne faisant pas partie du cluster, et en interrogeant l’adresse VIP :
Le test nous montre que chacun des nœuds réponds tour à tour. L’équilibrage des charges est donc bien en place. Il dépend directement de la création de la ressource IPAdrr2, en spécifiant la primitive clone, cette ressource a été répartie sur les 3 nœuds. Pacemaker a automatiquement créé une règle iptables permettant de réaliser un équilibrage entre tous les nœuds en round robin :
1 2 3 |
sudo iptables -L INPUT -n | grep CLUSTERIP CLUSTERIP all -- 0.0.0.0/0 192.168.1.100 CLUSTERIP hashmode=sourceip-sourceport clustermac=D1:D8:5A:CC:CC:21 total_nodes=3 local_node=1 hash_init=0 |
Le hashmode par défaut est sourceip-sourceport, ce qui implique que le hash sera calculé sur l’adresse du client ainsi que sur son port source. C’est pourquoi à partir de la même machine, on va accéder à tous les nœuds de façon cyclique. les différents paramétrages possible du hashmode sont :
- sourceip
- sourceip-sourceport
- sourceip-sourceport-destport
Failover
Pour le test suivant, on ouvre une fenêtre Firefox en autorefresh sur l’ordinateur hébergeant les VM. Dans cette configuration, le sourceport ne change pas, on reste donc systématiquement sur le même nœud.
En forçant un reboot du nœud, on peut voir que c’est le nœud 1 qui nous répond, pendant le temps de reboot du nœud 3 :
Interface Web
Pacemaker et corosync proposent aussi la gestion du cluster, au travers d’une interface web qui est installée nativement. Elle est accessible en se connectant sur le port 2224, sur l’adresse du cluster. Il faudra ensuite se logger avec le compte provisionné lors de la création du cluster.
Au travers de cette interface, nous pourrons réaliser les mêmes actes de maintenance que ceux proposés par l’interface en ligne de commande :
Conclusion
Avec une configuration relativement aisée, on peut mettre en place un cluster stable qui répondra aux problématiques de haute disponibilité. Dans notre cas, on constate que le failover est automatisé par pacemaker et que l’équilibrage de charge est également assuré.
Pacemaker dispose d’autres fonctionnalités permettant d’assurer l’exploitation du cluster, comme une mise en maintenance d’un nœud, l’ajout ou le retrait d’un noeud, la gestion des ressources, etc.