LINUX:Pacemaker - Routers LAN-Internet en Failover
→ retour au menu de la Haute disponibilité
But
Ce second exemple place deux routers en Failover afin de diminuer le risque de coupures. Ces routers relierons notre LAN privé à Internet. Nous n'aborderons pas le mur de feu ou firewall qui doit comprendre le NAT et le PAT. A vous de le concevoir.
Principe
On dispose de deux ordinateurs Linux configurés en mode routers. On va utiliser le logiciel Pacemaker qui les regroupent en cluster. Il sera utilisé en Failover. Ces routers font l'interface entre un LAN privé et Internet. Particularité, notre ISP nous procure un subnet de 6 adresses publiques. Il en utilise une pour son router à lui (81.246.173.46) et nous laisse les 5 autres (81.246.173.41 à 81.246.173.45).
A la base les interfaces réseaux "eth2" se trouvant du côté d'Internet, n'ont pas d'adressage IP. Une seule de nos machines du cluster acheminera le trafic, l'autre sera en attente. La machine active accueillera les 5 adresses IP publiques virtuelles (en rouge sur le schéma) sur son interface réseau "eth2"; l'autre machine n'aura pas d'adressage IP sur cet interface "eth2" pour une question d'économie d'adresses IP publiques. Du côté des interfaces réseaux "eth1" situées sur notre LAN privé, la machine active recevra une adresse IP privée virtuelle (192.168.1.73) (en rouge sur le schéma).
Qui dit router, dit routage. A la base ces machines n'ont pas de routage par défaut. Donc comme la machine active a pour tâche d'envoyer le trafic vers internet (eth2), elle devra avoir une route par défaut vers le router de notre ISP (81.246.173.46) (en rouge sur le schéma). Pour les machines situées sur notre LAN, c'est l'adresse virtuelle privée qui servira de route par défaut (192.168.1.73). Or notre machine passive n'a pas d'adresse IP publique. Elle n'a un accès que du côté privé; on doit donc ajouter une route vers l'adresse privée virtuelle (192.168.1.73) sur côté LAN privé (eth1).
Un des routers aura des fonctions de router en concentrant les ressources configurées dans Pacemaker tandis que l'autre sera en attente. Quand le premier router sera indisponible, par exemple suite à un problème matériel ou plus simplement lors d'une mise à jour de version, le second reprendra la tâche de router en récupérant les ressources de Pacemaker.
Nous voyons d'après cette description que les ressources de Pacemaker ne seront pas concentrées sur la machine active. Une ressource sera sur la machine passive: la route privée. Nous ne donnerons pas la préférence à une machine plutôt qu'à l'autre; donc si après une coupure d'une des machines, l'autre ayant repris à son compte, le trafic, dès que la situation redevient à la normale, les ressources resteront à leur place; elles ne émigreront pas à nouveau. Sur le schéma, on présente une des deux situations; il est réversible.
Les adresses IP réelles privées ne seront utilisées que pour une administration locale, par exemple, pour mettre à jour l'OS. Pour les notions de routage, voyez l'article concernant le Routage statique.
Prérequis
Configuration de base
En premier, la Configuration de base de Pacemaker doit être effectuée.
Adressage et routage de base
Suivez l'adressage IP en noir. Seuls les interfaces réseaux privés "eth1" reçoivent une adressage IP privé. Les interfaces réseaux publiques "eth2" n'en reçoivent pas. Il est très important de ne pas mettre de routage par défaut; c'est Pacemaker qui le fera. Une machine ne peut en avoir qu'une. Par contre, si vous avez plusieurs LANs privés, il faudra prévoir des tables de routage statique.
Activation du routage
En second, il faut activer le routage sur les deux routers en ajoutant un fichier, par exemple "router.conf", dans le répertoire "/etc/sysctl.d". Ce fichier doit contenir la ligne:
net.ipv4.ip_forward = 1
On active cette configuration soit en redémarrant la machine, soit avec la commande suivante:
sysctl -p /etc/sysctl.d/router.conf
Fichier "hosts"
Sur chaque machine du cluster, on ajoute un nom aux différentes adresses réseaux. On le fait en local dans le fichier "/etc/hosts" suivant le schéma ci-dessus. Son contenu devient:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.1.71 fo1.home.dom 192.168.1.72 fo2.home.dom 192.168.1.73 cluster.home.dom # serveur mail 192.168.1.110 servermail.home.dom home.dom
Configuration
Script
On effectue la suite des commandes suivantes à partir d'une des machines du cluster. On peut les mettre dans un script.
#!/bin/bash pcs resource create ClusterIPext1 ocf:heartbeat:IPaddr2 ip=81.246.173.41 cidr_netmask=29 nic=eth2 iflabel=ethext1 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext2 ocf:heartbeat:IPaddr2 ip=81.246.173.42 cidr_netmask=29 nic=eth2 iflabel=ethext2 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext3 ocf:heartbeat:IPaddr2 ip=81.246.173.43 cidr_netmask=29 nic=eth2 iflabel=ethext3 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext4 ocf:heartbeat:IPaddr2 ip=81.246.173.44 cidr_netmask=29 nic=eth2 iflabel=ethext4 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext5 ocf:heartbeat:IPaddr2 ip=81.246.173.45 cidr_netmask=29 nic=eth2 iflabel=ethext5 lvs_support=true op monitor interval=30s pcs resource create ClusterDefaultRoutem ocf:heartbeat:Route destination="default" gateway=81.246.173.46 device=eth2 family=ip4 pcs resource create ClusterIPintm ocf:heartbeat:IPaddr2 ip=192.168.1.73 cidr_netmask=24 nic=eth1 iflabel=ethintm lvs_support=true op monitor interval=30s pcs resource create Clustermailto ocf:heartbeat:MailTo email=root@home.dom subject="FailOver_Home" op monitor interval=30s pcs resource group add GroupeApplm ClusterIPintm ClusterIPext1 ClusterIPext2 ClusterIPext3 ClusterIPext4 ClusterIPext5 ClusterDefaultRoutem Clustermailto pcs constraint colocation add ClusterIPext1 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext2 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext3 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext4 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext5 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterDefaultRoutem with ClusterIPintm score=INFINITY pcs constraint colocation add Clustermailto with ClusterIPintm score=INFINITY pcs resource create ClusterDefaultRoutes ocf:heartbeat:Route destination="default" gateway=192.168.1.73 device=eth1 family=ip4 --force --wait=20 pcs resource group add GroupeAppls ClusterDefaultRoutes pcs constraint colocation add ClusterDefaultRoutes with ClusterIPintm score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext1 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext2 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext3 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext4 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext5 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterDefaultRoutem score=-INFINITY pcs constraint order GroupeApplm then start GroupeAppls
Ces commandes ne sont à exécuter qu'à partir d'une seule machine du cluster.
Ajout des ressources des adresses IP publiques virtuelles
Les lignes suivantes:
pcs resource create ClusterIPext1 ocf:heartbeat:IPaddr2 ip=81.246.173.41 cidr_netmask=29 nic=eth2 iflabel=ethext1 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext2 ocf:heartbeat:IPaddr2 ip=81.246.173.42 cidr_netmask=29 nic=eth2 iflabel=ethext2 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext3 ocf:heartbeat:IPaddr2 ip=81.246.173.43 cidr_netmask=29 nic=eth2 iflabel=ethext3 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext4 ocf:heartbeat:IPaddr2 ip=81.246.173.44 cidr_netmask=29 nic=eth2 iflabel=ethext4 lvs_support=true op monitor interval=30s pcs resource create ClusterIPext5 ocf:heartbeat:IPaddr2 ip=81.246.173.45 cidr_netmask=29 nic=eth2 iflabel=ethext5 lvs_support=true op monitor interval=30s
vont créer cinq ressources, nommées "ClusterIPextX" qui vont activer cinq adresses virtuelles publiques respectivement de "81.246.173.41/29" à "81.246.173.45/29" grâce à la fonction "ocf:heartbeat:IPaddr2". Elles seront placées sur l'interface réseau "eth2". Des noms virtuels sont aussi donnés: "ethextX".
Ajout de la ressource d'un route par défaut vers le router de l'ISP
La ligne suivante:
pcs resource create ClusterDefaultRoutem ocf:heartbeat:Route destination="default" gateway=81.246.173.46 device=eth2 family=ip4
va créer une ressource, nommée "ClusterDefaultRoutem", qui va ajouter une route par défaut vers le router de l'ISP à l'adresse IP publique "81.246.173.46/29" sur l'interface réseau "eth2" grâce à la fonction "ocf:heartbeat:Route".
Ajout de la ressource de l'adresse IP privée virtuelle
La ligne suivante:
pcs resource create ClusterIPintm ocf:heartbeat:IPaddr2 ip=192.168.1.73 cidr_netmask=24 nic=eth1 iflabel=ethintm lvs_support=true op monitor interval=30s
va créer une ressource, nommée "ClusterIPintm" qui va activer une adresse virtuelle privée "192.168.1.73/24" grâce à la fonction "ocf:heartbeat:IPaddr2". Elle sera placée sur l'interface réseau "eth1". Un nom virtuel est aussi donné: "ethintm".
Ressource de notification par mail
La ligne suivante:
pcs resource create ClusterMailTo ocf:heartbeat:MailTo email=root subject="FailOver_Home" op monitor interval=30s
crée une ressource nommée "ClusterMailTo" grâce à la fonction "ocf:heartbeat:MailTo". A tout changement d'état un mail sera envoyé à l'utilisateur "root" dont le sujet débutera avec les mots "FailOver_Home".
Regroupement des ressources de la machine active
La ligne suivante:
pcs resource group add GroupeApplm ClusterIPintm ClusterIPext1 ClusterIPext2 ClusterIPext3 ClusterIPext4 ClusterIPext5 ClusterDefaultRoutem Clustermailto
crée un goupe nommé "GroupeApplm" qui rassemble toutes les ressources qui vont se trouver sur la machine active.
Localisation commune sur la machine active
Les lignes suivantes:
pcs constraint colocation add ClusterIPext1 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext2 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext3 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext4 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterIPext5 with ClusterIPintm score=INFINITY pcs constraint colocation add ClusterDefaultRoutem with ClusterIPintm score=INFINITY pcs constraint colocation add Clustermailto with ClusterIPintm score=INFINITY
précisent que ces huit ressources seront sur la machine active.
Ajout de la ressource d'un route par défaut privée
La ligne suivante:
pcs resource create ClusterDefaultRoutes ocf:heartbeat:Route destination="default" gateway=192.168.1.73 device=eth1 family=ip4 --force --wait=20
va créer une ressource, nommée "ClusterDefaultRoutes", qui va ajouter la route par défaut privée qui se placera sur la machine passive à l'adresse IP privée virtuelle "192.168.1.73/24" sur l'interface réseau "eth1" grâce à la fonction "ocf:heartbeat:Route". Mais comme le système ne permet que l'ajout d'une seule route par défaut, il faut le forcer ("--force").
Regroupement de la ressource de la machine passive
La ligne suivante:
pcs resource group add GroupeAppls ClusterDefaultRoutes
, par symétrie, crée un goupe nommé "GroupeAppls" qui reprend la ressource qui va se trouver sur la machine passive: "ClusterDefaultRoutes".
Localisation de la route privée sur la machine passive
Les lignes suivantes:
pcs constraint colocation add ClusterDefaultRoutes with ClusterIPintm score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext1 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext2 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext3 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext4 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterIPext5 score=-INFINITY pcs constraint colocation add ClusterDefaultRoutes with ClusterDefaultRoutem score=-INFINITY
précisent que les huit ressources de la machine active ne peuvent être localisées sur la même machine que la route privée ("score=-INFINITY") grâce au signe "-". Ceci permet de situer les deux routes par défaut sur les machines différentes. Elle sera donc sur la machine passive.
Ordre de démarrage
La ligne suivante:
pcs constraint order GroupeApplm then start GroupeAppls
définit l'ordre de démarrage de ces deux groupes; les ressources du groupe "GroupeApplm" seront démarrées avant la ressource du groupe "GroupeAppls".
Notons que ces groupes pouvaient être évités mais leur présence aide à la lisibilité.
Statut
La commande suivante:
crm_mon -1
donne:
Status of pacemakerd: 'Pacemaker is running' (last updated 2023-02-09 16:54:00 +01:00) Cluster Summary: * Stack: corosync * Current DC: fo1.home.dom (version 2.1.5-3.fc37-a3f44794f94) - partition with quorum * Last updated: Thu Feb 9 16:54:00 2023 * Last change: Thu Feb 9 13:15:20 2023 by root via cibadmin on fo1.home.dom * 2 nodes configured * 9 resource instances configured Node List: * Online: [ fo1.home.dom fo2.home.dom ] Active Resources: * Resource Group: GroupeApplm: * ClusterIPintm (ocf::heartbeat:IPaddr2): Started fo1.home.dom * ClusterIPext1 (ocf::heartbeat:IPaddr2): Started fo1.home.dom * ClusterIPext2 (ocf::heartbeat:IPaddr2): Started fo1.home.dom * ClusterIPext3 (ocf::heartbeat:IPaddr2): Started fo1.home.dom * ClusterIPext4 (ocf::heartbeat:IPaddr2): Started fo1.home.dom * ClusterIPext5 (ocf::heartbeat:IPaddr2): Started fo1.home.dom * ClusterDefaultRoutem (ocf::heartbeat:Route): Started fo1.home.dom * Clustermailto (ocf::heartbeat:MailTo): Started fo1.home.dom * Resource Group: GroupeAppls: * ClusterDefaultRoutes (ocf::heartbeat:Route): Started fo2.home.dom
On remarque que la route privée est la seule ressource se trouvant sur la machine passive "fo2.home.dom". Les deux groupes aident à la lisibilité.
Voici la situation de l'adressage réseau sur la machine "fo1.home.dom", qui a les ressources, avec la commande:
ifconfig
qui donne:
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.71 netmask 255.255.255.0 broadcast 192.168.1.255 ether 00:1c:c0:92:a2:08 txqueuelen 1000 (Ethernet) RX packets 106036 bytes 15883463 (15.1 MiB) RX errors 0 dropped 7 overruns 0 frame 0 TX packets 134766 bytes 21209427 (20.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 20 memory 0xd3300000-d3320000 eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 00:1b:21:3b:b6:ea txqueuelen 1000 (Ethernet) RX packets 885 bytes 281910 (275.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 415 bytes 24900 (24.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth1:ethintm: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.73 netmask 255.255.255.0 broadcast 192.168.1.255 ether 00:1c:c0:92:a2:08 txqueuelen 1000 (Ethernet) device interrupt 20 memory 0xd3300000-d3320000 eth2:ethext1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 81.246.173.41 netmask 255.255.255.248 broadcast 0.0.0.0 ether 00:1b:21:3b:b6:ea txqueuelen 1000 (Ethernet) eth2:ethext2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 81.246.173.42 netmask 255.255.255.248 broadcast 0.0.0.0 ether 00:1b:21:3b:b6:ea txqueuelen 1000 (Ethernet) eth2:ethext3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 81.246.173.43 netmask 255.255.255.248 broadcast 0.0.0.0 ether 00:1b:21:3b:b6:ea txqueuelen 1000 (Ethernet) eth2:ethext4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 81.246.173.44 netmask 255.255.255.248 broadcast 0.0.0.0 ether 00:1b:21:3b:b6:ea txqueuelen 1000 (Ethernet) eth2:ethext5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 81.246.173.45 netmask 255.255.255.248 broadcast 0.0.0.0 ether 00:1b:21:3b:b6:ea txqueuelen 1000 (Ethernet) lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Boucle locale) RX packets 831 bytes 227120 (221.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 831 bytes 227120 (221.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Les adresses virtuelles s'y trouvent.
Et cette même commande sur la machine "fo2.home.dom":
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.72 netmask 255.255.255.0 broadcast 192.168.1.255 ether 00:1b:21:3b:b0:77 txqueuelen 1000 (Ethernet) RX packets 143939 bytes 21208206 (20.2 MiB) RX errors 0 dropped 7 overruns 0 frame 0 TX packets 97308 bytes 14964148 (14.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 00:1c:c0:2a:c4:25 txqueuelen 1000 (Ethernet) RX packets 432 bytes 27648 (27.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 3055 bytes 486144 (474.7 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 20 memory 0xe0380000-e03a0000 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Boucle locale) RX packets 560 bytes 194600 (190.0 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 560 bytes 194600 (190.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
L'adressage reste inchangé. L'interface réseau "eth2" n'a pas d'adresse IP.
Maintenant regardons les routes sur la machine "fo1.home.dom" avec la commande:
route -n
donne:
Destination Passerelle Genmask Indic Metric Ref Use Iface 0.0.0.0 81.246.173.46 0.0.0.0 UG 0 0 0 eth2 81.246.173.40 0.0.0.0 255.255.255.248 U 0 0 0 eth2 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 eth1
Et sur la machine "fo2.home.dom":
Table de routage IP du noyau Destination Passerelle Genmask Indic Metric Ref Use Iface 0.0.0.0 192.168.1.73 0.0.0.0 UG 0 0 0 eth1 192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 eth1
Remarquons que l'interface réseau "eth2" n'est pas repris car non configuré.
→ retour au menu de la Haute disponibilité