LINUX:Pacemaker - Routers LAN-Internet en Failover

De WIKI sur Linux (ADB)
Aller à la navigation Aller à la recherche

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).

LINUX:Failover2G.pdf

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é