Linux - Haute-disponibilité de Web Server sans load balancer
Alasta 20 Décembre 2014 linux Linux Pacemaker HA cli
Description : Voici comment mettre en place un HA de serveur Web sans load balancer.
Contexte :
Nous allons mettre en place une solution de HA Open Source entre 2 serveur Web sans solution de loadbalaning (Type HAPorxy, F5 LTM, Alteon, ...). Cette solution est basée sur Pacemaker.
Nous partirons du principe que nous avons deux machines Linux fonctionnelles (httpd1 et httpd2) sans iptables et SELinux, dans mon lab se sera deux CentOS 6.
Un point important, la résolution de nom, soit vous renseigner correctement le fichier /etc/hosts soit vous renseignez le DNS, dans ce lab j'ai utilisé /etc/hosts.
Schéma du lab :
Installation et configuration des serveurs Web :
Installation (sur les 2 serveurs) :
1 $ yum install -y httpd ImageMagick
Création d'une page web (sur les 2 serveurs) :
1 $ cd /var/www/html/
2
3 $ vi index.html
4 <html>
5 <head>
6 <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
7 <meta http-equiv="Pragma" content="no-cache" />
8 <meta http-equiv="Expires" content="0" />
9 <title>Page de Tests</title>
10 </head>
11 <body>
12 Page du serveur <b>XX</b>
13 <img src="image1.png">
14 <img src="image2.png">
15 <img src="image3.png">
16 <img src="image4.png">
17 </body>
18 </html>
Création des images :
Sur le httpd1
1 $ for i in 1 2 3 4; do convert -background red -fill black -size 165x70 -pointsize 24 -gravity center label:httpd1_img${i} image${i}.png; done
Sur le httpd2
1 $ for i in 1 2 3 4; do convert -background yellow -fill black -size 165x70 -pointsize 24 -gravity center label:httpd2_img${i} image${i}.png; done
Démarrage du service web (sur les 2 serveurs) :
1 $ service httpd start
Note : on ne configure pas les services au démarrage car c'est le cluster qui va le gérer.
Test de bon fonctionnement des Webs :
Serveur httpd1
Serveur httpd2
Partie Haute-Disponibilité :
Arrêt d'Apache (sur les 2 serveurs) :
Sur les 2 serveurs
1 $ service httpd stop
Installation des pacakges (sur les 2 serveurs) :
1 $ yum install -y pacemaker cman pcs ccs resource-agents
Configuration du cluster :
sur un serveur, ici httpd1 :
1 ! Déclaration du cluster
2 $ ccs -f /etc/cluster/cluster.conf --createcluster ClusterWeb
3 ! Déclaration des membres du cluster
4 $ ccs -f /etc/cluster/cluster.conf --addnode httpd1
5 Node httpd1 added.
6 $ ccs -f /etc/cluster/cluster.conf --addnode httpd2
7 Node httpd2 added.
8
9 ! On indique à CMAN (Cluster Management) comment dialoguer avec Pacemaker
10 $ ccs -f /etc/cluster/cluster.conf --addfencedev pcmk agent=fence_pcmk
11
12 $ ccs -f /etc/cluster/cluster.conf --addmethod pcmk-redirect httpd1
13 Method pcmk-redirect added to httpd1.
14
15 $ ccs -f /etc/cluster/cluster.conf --addmethod pcmk-redirect httpd2
16 Method pcmk-redirect added to httpd2.
17
18 $ ccs -f /etc/cluster/cluster.conf --addfenceinst pcmk httpd1 pcmk-redirect port=httpd1
19 $ ccs -f /etc/cluster/cluster.conf --addfenceinst pcmk httpd2 pcmk-redirect port=httpd2
20
21 ! Dupliquer la configuration du cluster sur l'autre membre
22 $scp /etc/cluster/cluster.conf root@192.168.5.14:/etc/cluster/
Sur les 2 serveurs :
Un point bloquant peut être le quorum : c’est le nombre minimum de nœuds en ligne pour être capable de valider une décision. Dans le cas d’un cluster avec Pacemaker, il faut que plus de la moitié des nœuds soit en ligne. Avec un cluster à deux nœuds, il n’y a plus de quorum dès qu’un nœud est perdu. Il va donc falloir demander à Pacemaker d’ignorer le quorum dans cette situation. Le fonctionnement par défaut quand le quorum n’est pas atteint est de couper toutes les ressources !
1 ! Désactivation du Quorum
2 $ echo "CMAN_QUORUM_TIMEOUT=0" >> /etc/sysconfig/cman
3
4 ! Gestion des services
5 $ service cman start
6 $ service pacemaker start
7 $ chkconfig --level 2345 cman on
8 $ chkconfig --level 2345 pacemaker on
sur un serveur, ici httpd1 :
Stonith ou “Shoot The Other Node In The Head” . C’est une méthode d’isolation d’un nœud (fencing) qui pour une raison ou une autre ne répond plus. L’idée est d’éviter à tout prix le fameux split-brain qui peut amener tous vos nœuds à fournir le même service (ou à ne plus le fournir du tout). Le nœud jugé hors service sera donc, en général, redémarré ou arrêté électriquement (via IPMI par exemple). Nous n'en avons pas besoins dans notre lab.
1 $ pcs property set stonith-enabled=false
2 $ pcs property set no-quorum-policy=ignore
3 $ pcs resource defaults migration-threshold=1
Vérifier l'état du cluster (sur les 2 serveurs) :
1 $ pcs status
2 Cluster name: ClusterWeb
3 Last updated: Mon Dec 22 22:07:51 2014
4 Last change: Mon Dec 22 22:06:18 2014
5 Stack: cman
6 Current DC: httpd2 - partition with quorum
7 Version: 1.1.11-97629de
8 2 Nodes configured
9 0 Resources configured
10
11
12 Online: [ httpd1 httpd2 ]
13
14 Full list of resources:
Configuration Apache pour check de status (sur les 2 serveurs) :
1 ! Ajouter la configuration du server-status
2 $ vi /etc/httpd/conf/httpd.conf
3 <Location /server-status>
4 SetHandler server-status
5 Order deny,allow
6 Deny from all
7 Allow from 127.0.0.1
8 </Location>
Déclaration des ressources (sur 1 des serveurs):
1 ! Déclaration de la ressource avec son @IP, interval de check
2 $ pcs resource create IPClusterWeb ocf:heartbeat:IPaddr2 ip=192.168.5.150 cidr_netmask=32 op monitor interval=10s
3
4 ! On a une préférence que le serveur httpd1 soit "maitre"
5 $ pcs constraint location IPClusterWeb prefers httpd1=INFINITY
6
7 ! Déclaration de la ressoure Apache (service)
8 pcs resource create WebSite ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://localhost/server-status" op monitor interval=1min
Vérifier l'état du cluster (sur 1 des serveurs) :
1 $ pcs status
2 Cluster name: ClusterWeb
3 Last updated: Mon Dec 22 22:19:53 2014
4 Last change: Mon Dec 22 22:18:39 2014
5 Stack: cman
6 Current DC: httpd2 - partition with quorum
7 Version: 1.1.11-97629de
8 2 Nodes configured
9 2 Resources configured
10
11
12 Online: [ httpd1 httpd2 ]
13
14 Full list of resources:
15
16 IPClusterWeb (ocf::heartbeat:IPaddr2): Started httpd1
17 WebSite (ocf::heartbeat:apache): Started httpd2
C'est bien, mais L'IP du cluster n'est pas sur le même serveur que la ressource Web ...
Affiner la configuration (sur 1 des serveurs) :
1 ! On ajoute une contrainte qui indique que les ressources IP et Web sont sur le même serveur
2 $ pcs constraint colocation add IPClusterWeb WebSite INFINITY
3
4 ! La ressource IP serra vu Up seulement quand la ressource Web serra Up
5 $ pcs constraint order IPClusterWeb then WebSite
6 Adding IPClusterWeb WebSite (kind: Mandatory) (Options: first-action=start then-action=start)
7
8 ! Vérification
9 $ pcs status
10 Cluster name: ClusterWeb
11 Last updated: Mon Dec 22 22:25:12 2014
12 Last change: Mon Dec 22 22:24:11 2014
13 Stack: cman
14 Current DC: httpd2 - partition with quorum
15 Version: 1.1.11-97629de
16 2 Nodes configured
17 2 Resources configured
18
19
20 Online: [ httpd1 httpd2 ]
21
22 Full list of resources:
23
24 IPClusterWeb (ocf::heartbeat:IPaddr2): Started httpd1
25 WebSite (ocf::heartbeat:apache): Started httpd1
La commande de status du service Apache indique qu'il est seulement démarré sur le serveurs "maitre".
1 $ service httpd status
Aller à l'URL http://192.168.5.150 dans un navigateur (fonctionnement nominal) :
Cas de bascule
On éteint le serveur httpd1
1 $ pcs status
2 Cluster name: ClusterWeb
3 Last updated: Mon Dec 22 22:54:02 2014
4 Last change: Mon Dec 22 22:49:47 2014
5 Stack: cman
6 Current DC: httpd2 - partition WITHOUT quorum
7 Version: 1.1.11-97629de
8 2 Nodes configured
9 2 Resources configured
10
11
12 Node httpd1: OFFLINE (standby)
13 Online: [ httpd2 ]
14
15 Full list of resources:
16
17 IPClusterWeb (ocf::heartbeat:IPaddr2): Started httpd2
18 WebSite (ocf::heartbeat:apache): Started httpd2
Redémmarrage de httpd1
1 $ pcs status
2 Cluster name: ClusterWeb
3 Last updated: Mon Dec 22 22:57:04 2014
4 Last change: Mon Dec 22 22:49:47 2014
5 Stack: cman
6 Current DC: httpd2 - partition with quorum
7 Version: 1.1.11-97629de
8 2 Nodes configured
9 2 Resources configured
10
11
12 Online: [ httpd1 httpd2 ]
13
14 Full list of resources:
15
16 IPClusterWeb (ocf::heartbeat:IPaddr2): Started httpd1
17 WebSite (ocf::heartbeat:apache): Started httpd1
En stoppant juste le service Apache sur httpd1 la bascule n'est pas aussi franche, il y a une bonne dizaine de secondes pour que cela soit effectif.
1 $ pcs status
2 Cluster name: ClusterWeb
3 Last updated: Mon Dec 22 23:00:06 2014
4 Last change: Mon Dec 22 22:49:47 2014
5 Stack: cman
6 Current DC: httpd2 - partition with quorum
7 Version: 1.1.11-97629de
8 2 Nodes configured
9 2 Resources configured
10
11
12 Online: [ httpd1 httpd2 ]
13
14 Full list of resources:
15
16 IPClusterWeb (ocf::heartbeat:IPaddr2): Started httpd2
17 WebSite (ocf::heartbeat:apache): Started httpd2
18
19 Failed actions:
20 WebSite_monitor_60000 on httpd1 'not running' (7): call=13, status=complete, last-rc-change='Mon Dec 22 22:58:47 2014', queued=0ms, exec=0ms
Il faut faire un cleanup pour repasser sur httpd1, vu que c'est l'admin qui à stopper le service alors que c'est le cluster qui gère normalement les services.
1 $ crm_resource --resource WebSite --cleanup
=> Idem dans le cas du kill des process Apache !
Commandes :
1 ! Status du cluster
2 $ pcs status
3
4 ! Stop le Cluster
5 $ pcs cluster stop
6
7 ! Start du Cluster
8 $ pcs cluster start
9
10 ! Mise en pause d'un serveur
11 $ pcs cluster standby httpd1
12 $ pcs status
13 Cluster name: ClusterWeb
14 Last updated: Mon Dec 22 22:47:37 2014
15 Last change: Mon Dec 22 22:47:33 2014
16 Stack: cman
17 Current DC: httpd2 - partition with quorum
18 Version: 1.1.11-97629de
19 2 Nodes configured
20 2 Resources configured
21
22
23 Node httpd1: standby
24 Online: [ httpd2 ]
25
26 Full list of resources:
27
28 IPClusterWeb (ocf::heartbeat:IPaddr2): Started httpd2
29 WebSite (ocf::heartbeat:apache): Started httpd2
30 ! bascule OK
31
32 ! Remise en ligne du serveur
33 $ pcs cluster unstandby httpd1
34
35
36 ! Affichage de la configuration
37 $ pcs config
38
39 ! Affichage de la configuration en XML
40 $ pcs cluster cib
41
42 ! Sauvegarde de la configuration XML dans un fichier
43 $ pcs cluster cib fichier-backup-de-configuration
44
45 ! Restauration de configuration
46 $ pcs cluster cib-push fichier-backup-de-configuration
47
48 ! Affichage des ressources
49 $ pcs resource
50 ou
51 $ crm_resource --list
52 IPClusterWeb (ocf::heartbeat:IPaddr2): Started
53 WebSite (ocf::heartbeat:apache): Started
54
55 ! Propriété du cluster
56 $ pcs property
57 Cluster Properties:
58 cluster-infrastructure: cman
59 dc-version: 1.1.11-97629de
60 last-lrm-refresh: 1419344527
61 no-quorum-policy: ignore
62 stonith-enabled: false
63
64
65 ! Affichage des contrainte
66 $ # pcs constraint
67 Location Constraints:
68 Resource: IPClusterWeb
69 Enabled on: httpd2 (score:100)
70 Enabled on: httpd1 (score:INFINITY)
71 Resource: WebSite
72 Enabled on: httpd1 (score:INFINITY)
73 Enabled on: httpd2 (score:INFINITY)
74 Ordering Constraints:
75 start IPClusterWeb then start WebSite (kind:Mandatory)
76 Colocation Constraints:
77 IPClusterWeb with WebSite (score:INFINITY)
78
79
80 ! Nettoyer les actions failed pour que le cluster bascule dans sa situation nominale
81 $ crm_resource --resource WebSite --cleanup
82
83 ! Affichage des ressources "standard"
84 $ pcs resource standards
85
86 ! Affichage des ressources "providers"
87 $ pcs resource providers
88
89 ! Affichage des ressources "agents"
90 $ pcs resource agents
91
92 ! Spécifique à un agent
93 $ pcs resource agents ocf:heartbeat
94
95 ! Vérification syntaxique de la configuration
96 $ crm_verify -L
97 ou
98 $ pcs cluster verify
99
100 ! Node sur lequel on se trouve
101 $ crm_node -n
102 httpd1
103
104
105 ! Liste des nodes
106 $ crm_node -l
107 httpd1 httpd2
108
109 ! Déplacement de ressource (dans mon lab il ne fonctionne que sur les ressources n'ayant pas de contrainte)
110 $ pcs resource move MaRessourceWeb httpd2
111
112 ! Supprimer la configuration du cluster locale du node (attention les fichiers de configuration sont supprimés) et services arrêtés.
113 $ pcs cluster destroy