2

AWS : Configurer un cluster PostgreSQL HD avec Corosync/Pacemaker sur des EC2 Amazon

twitterlinkedinmail

Hello

après ces quelques mois d’absence liés à ces contraintes sanitaires, nous voici de retour pour un nouveau sujet AWS PostgreSQL.
Nous avons récemment mis en place un cluster Haute Disponibilité chez un de nos clients en utilisant la solution PgPool-II.

Ce produit a la particularité de gérer de nombreux services, dont le pooling de connexions, mais aussi la haute disponibilité avec bascule d’IP virtuelle.

Mais notre sujet du jour est de savoir comment configurer la solution Corosync / Pacemaker pour effecteur un “PostgreSQL Failover Automatic” sur des EC2 Amazon.

De nombreux articles existent sur Internet pour la mise en place de ces fameux outils que sont Corosync et Pacemaker, bien connus du monde Unix.
Ces derniers étant largement utilisés pour la gestion d’un serveur Web Apache ou Tomcat ou d’un serveur d’application, par exemple.

Le SGBDR PostgreSQL est compatible avec cette solution de haute disponibilité, cela en fait un serveur de bases de données hautement disponible avec bascule rapide et automatique.

 

Mais qu’en est-il de la gestion d’un PostgreSQL HD dans le cadre de l’utilisation de VM AWS EC2 ?

 

Rappelons que pour qu’une bascule via “fencing”, soit transparente, il est largement recommandé d’installer une IP Virtuelle qui se déclarera sur le noeud ou l’instance PostgreSQL est “primaire”. La solution Corosync / Pacemaker se chargera de basculer automatiquement les ressources associés, notamment PostgreSQL, et ainsi éviter un “split brain” (2 instances actives en même temps).

 

Le cluster Haute disponibilité.

Dans notre exemple, nous partons avec 2 VM EC2 Amazon de type CentOS 7 installées sur un subnet privé.
Ces VM ne sont donc pas accessibles via Internet, ce qui est recommandé par les bonnes pratiques en matière de sécurité dans le cadre d’une architecture AWS  pour un cluster de bases de données.

L’idée est d’avoir ce schéma de connexions pour la mise en place de notre cluster

 

 

Dans ce schéma, les IPs sont données à titre d’exemple.
Tout au long de cette présentation, nous travaillerons avec 2 VMs Amazon ayant les caractéristiques suivantes :

  • 1 VM portant le nom ip-172-44-2-226 avec l’IP privée 172.44.2.226
  • 1 VM portant le nom ip-172-44-2-143 avec l’IP privée 172.44.2.143
  • 1 IP virtuelle déclarée avec la valeur 172.44.2.144

 

Les prérequis 

PostgreSQL12 Streaming Replication

Nous avons installés un cluster PostgreSQL version 12.4, avec la mise en place de la Streaming Replication.
N’hésitez pas à consulter cet article pour connaitre les étapes à suivre pour une mise en oeuvre.

Configuration ssh

Créer les clés SSH pour root et pour postgres afin que les 2 serveurs n’aient pas à saisir de password pour se connecter.
Ceci est à réaliser sur les 2 VMs EC2

# cd ~/.ssh
# ssh-keygen -t rsa -f id_rsa
# ssh-copy-id -i id_rsa.pub root@172.44.2.143
# ssh-copy-id -i id_rsa.pub root@172.44.2.226

postgres $ cd ~/.ssh
postgres $ ssh-keygen -t rsa -f id_rsa
postgres $ ssh-copy-id -i id_rsa.pub postgres@172.44.2.143
postgres $ ssh-copy-id -i id_rsa.pub postgres@172.44.2.226

 

Configuration AWS

Service IAM

Comme nous sommes sur des instances EC2 Amazon, nous devrons mettre à jour nos stratégies pour que nos VM puissent exécuter des opérations sur les instances (arrêt, redémarrage, changer une IP …). Nous verrons par la suite, en quoi consistent ces opérations.
Dans la mesure du possible, et afin que vos instances EC2 respectent les fondamentaux en terme de sécurité, il faudra vous créer un rôle IAM que vous affecterez à vos 2 instances EC2.

Dans ce rôle, il faudra définir une nouvelle stratégie, dans laquelle, chaque instance pourra effectuer les actions suivantes :

  • démarrer une instance
  • arrêter une instance
  • reboot d’une instance
  • affecter/désaffecter une nouvelle IP secondaire
  • lire les caractéristiques d’un instance.

Cette stratégie pourra comporter le document JSON suivant pour notre exemple :

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:RebootInstances",
                "ec2:DescribeInstances",
                "ec2:DetachNetworkInterface",
                "ec2:StartInstances",
                "ec2:RunInstances",
                "ec2:AssignPrivateIpAddresses",
                "ec2:UnassignPrivateIpAddresses",
                "ec2:AssociateAddress",
                "ec2:StopInstances"
            ],
            "Resource": "*"
        }
    ]
}

Installer AWS CLI sur les EC2 

Comme le cluster aura besoin d’agir directement par lignes de commandes sur les instances EC2 Amazon, il nous faudra l’outil AWS CLI sur les 2 VM.
Nous pourrons l’installer grâce aux commandes suivantes :

# curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
# unzip awscliv2.zip
# cd aws
# ./install
# aws --version

Notez que l’outil awscli est installé dans /usr/local/bin. Nous aurons besoin de connaitre ce “PATH” pour la suite.
Une fois correctement configuré, lancez un “aws configure”. Puis interroger les caractéristiques de votre instance pour valider la communication

Par exemple, ici, connaitre le nom AWS de notre adaptateur réseau de notre instance AWS.

# Instance_ID=`/usr/bin/curl --silent http://169.254.169.254/latest/meta-data/instance-id`
# aws ec2 describe-instances --instance-ids $Instance_ID --region eu-west-3 | grep NetworkInterfaceId | awk -F '"' '{print $4}'
eni-0e2b4ab8b3f9bc1fc

Nos informations nous sont bien remontées, nous pouvons alors débuter l’installation du cluster.

 

Installation des composants du cluster

Chacune des actions suivantes devra être effectuée sur les 2 serveurs. Utiliser le compte root pour l’installation des packages avec yum (Centos/Red Hat).

# yum install -y pacemaker resource-agents pcs fence-agents-all

Cela installera Corosync et Pacemaker ainsi que l’outil PCS qui sera très utile pour l’administration de notre cluster PGHD.
Par la suite il faudra installer le package lié directement à PostgreSQL Failover Automatic

# yum install -y resource-agents-paf

et surtout, le package utilisé dans le cadre d’un cluster sur des EC2 Amazon

# yum install -y resource-agents-aws

L’installation de Corosync et Pacemaker a également créé un nouveau compte système nommé “hacluster”. Celui ci est utilisé afin que tous les membres du cluster puissent communiquer ensemble.
Il faudra lui définir un password.

# password hacluster

 

Nous utiliserons l’outil PCS lancé via le daemon pcsd pour créer, configurer et administrer le cluster.
Celui ci se chargera de modifier les fichiers de conf de Corosync, Pacemaker, mais aussi les ordres envoyés à AWS notamment pour le fencing.

Nous pourrons ainsi désactiver le démarrage automatique des autres services, et ne laisser que pcsd actif lors du reboot de la VM EC2.

# systemctl disable postgresql-12.service
# systemctl disable corosync
# systemctl disable pacemaker
# systemctl enable pcsd.service
# systemctl start pcsd.service

Configuration du cluster

Notre cluster est maintenant installé, mais il n’est pas configuré.
La commande “pcs status” permet de vérifier l’état de celui ci et des ressources qui lui sont rattachés.

S’assurer que le daemon pcsd est bien démarré

# systemctl status pcsd.service
● pcsd.service - PCS GUI and remote configuration interface
Loaded: loaded (/usr/lib/systemd/system/pcsd.service; enabled; vendor preset: disabled)
Active: active (running) since Thu 2020-09-03 12:15:33 UTC; 2h 45min ago
Docs: man:pcsd(8)
man:pcs(8)
Main PID: 1129 (pcsd)
CGroup: /system.slice/pcsd.service
├─ 1129 /usr/bin/ruby /usr/lib/pcsd/pcsd
├─13362 /usr/bin/python2 -Es /usr/sbin/pcs cluster stop --pacemaker --force
└─13365 /bin/systemctl stop pacemaker

 

Création du cluster

 

Vérifier tout d’abord que les 2 VM communiquent bien ensemble via les clés SSH mises en place.

# pcs cluster auth ip-172-44-2-226 ip-172-44-2-143 -u hacluster
Password: 
ip-172-44-2-226: Authorized
ip-172-44-2-143: Authorized

Nous sommes prêts à configurer le cluster

# pcs cluster setup --name cluster_pghd12 ip-172-44-2-226 ip-172-44-2-143
Destroying cluster on nodes: ip-172-44-2-226, ip-172-44-2-143...
ip-172-44-2-226: Stopping Cluster (pacemaker)...
ip-172-44-2-143: Stopping Cluster (pacemaker)...
ip-172-44-2-226: Successfully destroyed cluster
ip-172-44-2-143: Successfully destroyed cluster

Sending 'pacemaker_remote authkey' to 'ip-172-44-2-226', 'ip-172-44-2-143'
ip-172-44-2-226: successful distribution of the file 'pacemaker_remote authkey'
ip-172-44-2-143: successful distribution of the file 'pacemaker_remote authkey'
Sending cluster config files to the nodes...
ip-172-44-2-226: Succeeded
ip-172-44-2-143: Succeeded

Synchronizing pcsd certificates on nodes ip-172-44-2-226, ip-172-44-2-143...
ip-172-44-2-226: Success
ip-172-44-2-143: Success
Restarting pcsd on the nodes in order to reload the certificates...
ip-172-44-2-226: Success
ip-172-44-2-143: Success

Redémarrer le cluster complet

# pcs cluster start --all
ip-172-44-2-226: Starting Cluster...
ip-172-44-2-143: Starting Cluster...

 

Configurer le fencing

La partie la plus critique pour un cluster est la partie fencing. Cette opération consiste a évincer un nœud qui serait déclaré en échec.
Ceci est effectué afin d’éviter le “split brain”, dans le cas d’un serveur de bases de données, cela pourrait être très problématique si une méthode de fencing n’est pas en place, car cela signifie que les 2 instances pourraient  se désynchroniser et être vues comme autonomes.

La méthode de fencing, forte mais radicale, est STONITH (Shoot The Other Node In The Head), le nœud déclaré en échec est tout simplement redémarré.

Tout d’abord, repérer l’id des 2 instance EC2 via la commande à lancer sur les 2 VMs :

# curl --silent http://169.254.169.254/latest/meta-data/instance-id

Une fois celles ci trouvées, lancer la création du fencing :

# pcs cluster cib cluster1.xml

# pcs stonith create clusterfence fence_aws region=eu-west-3 \
  pcmk_host_map="ip-172-44-2-226:i-0a72fb68be681f101;ip-172-44-2-143:i-0c6a7c72efad7e65e" \
  power_timeout=240 pcmk_reboot_timeout=480 pcmk_reboot_retries=3
# pcs cluster cib-push cluster1.xml

Le fencing sera actif uniquement pour ces 2 instances EC2. La configuration a été inscrite dans le fichier XML du cluster.

# pcs status
Cluster name: cluster_pghd12
Stack: corosync
Current DC: ip-172-44-2-143 (version 1.1.21-4.el7-f14e36fd43) - partition with quorum
Last updated: Thu Sep 3 11:53:24 2020
Last change: Thu Sep 3 10:04:28 2020 by root via crm_resource on ip-172-44-2-226

2 nodes configured
1 resource configured

Online: [ ip-172-44-2-143 ip-172-44-2-226 ]

Full list of resources:

clusterfence (stonith:fence_aws): Started ip-172-44-2-143

Daemon Status:
corosync: active/enabled
pacemaker: active/enabled
pcsd: active/enabled

 

Création des ressources cluster

Il s’agira de créer 4 ressources utilisées pour la prise en charge de PostgreSQL Automatic Failover

  • pgsqld pour la partie propriétés de l’instance PostgreSQL, les informations sur les binaires, le PGDATA, le port et la configuration
  • pgsql-ha qui est la ressource qui se charge de surveiller le processus pgsqld , organise le failover si besoin et son placement en tant que maître/esclave.
  • pgsql-master-ip qui est la ressource qui se charge de monter l’IP virtuelle sur le noeud local ou PostgreSQL doit être primaire
  • pgsql-awsvip qui fera la transmission de l’information coté AWS et affectera l’IP Virtuelle en tant que IP secondaire à l’instance EC2 qui porte l’instance PostgreSQL primaire.

Les créations s’effectueront dans l’ordre suivant :

# pcs cluster cib cluster1.xml
# pcs resource create pgsqld ocf:heartbeat:pgsqlms \
bindir=/usr/pgsql-12/bin pgdata=/data/postgres/12 op start timeout=60s \
op stop timeout=60s \
op promote timeout=30s \
op demote timeout=120s \
op monitor interval=15s timeout=10s role="Master" \
op monitor interval=16s timeout=10s role="Slave" \
op notify timeout=60s

A noter que depuis la version 12 de PostgreSQL, il n’est plus nécessaire de configurer le paramètre “recovery_template”, car il n’y a plus besoin de fichier “recovery.conf”. Les informations seront directement lues dans le fichier “postgresql.auto.conf”.
Seul le paramètre “application_name” devra apparaître avec le nom dns, ou l’IP du serveur sur lequel l’instance tourne.

Exemple pour le serveur ip-172-44-2-143

   $ cat postgresql.auto.conf
   primary_conninfo = 'user=repli passfile=/var/lib/pgsql/.pgpass host=172.44.2.226 port=5432 application_name=ip-172-44-2-143'
   recovery_target_timeline='latest'
   restore_command='scp 172.44.2.226:/data/postgres/archives/%f %p'

Une fois les informations concernant l’instance PostgreSQL créés, nous créerons la ressource haute disponibilité.

# pcs resource master pgsql-ha pgsqld notify=true

 

Puis la partie Virtuelle IP noeud local et instance AWS. Nous affecterons ces 2 ressources dans un même groupe nommé “aws-group”.

# pcs resource create pgsql-master-ip ocf:heartbeat:IPaddr2 ip=172.44.2.144 nic=eth0:1 cidr_netmask=24 op monitor interval=10s

# pcs resource create pgsql_awsvip ocf:heartbeat:awsvip awscli=/usr/local/bin/aws secondary_private_ip=172.44.2.144 --group aws-group

# pcs resource group add aws-group pgsql-master-ip

 

Afin de configurer les dépendances entre ces ressources, nous devrons nous appuyer sur les paramètres “colocation” et “order”.
La VIP doit dépendre du démarrage du nœud primaire.

# pcs constraint colocation add pgsql-master-ip with master pgsql-ha INFINITY
# pcs constraint colocation add pgsql_awsvip with master pgsql-ha INFINITY

 

Ordre de démarrage en cas de “promote” de l’instance.

# pcs constraint order promote pgsql-ha then start pgsql-master-ip symmetrical=false kind=Mandatory
# pcs constraint order promote pgsql-ha then start pgsql_awsvip symmetrical=false kind=Mandatory

 

Ordre d’arrêt en cas de passage en mode standby.

# pcs constraint order demote pgsql-ha then stop pgsql-master-ip symmetrical=false kind=Mandatory
# pcs constraint order demote pgsql-ha then stop pgsql_awsvip symmetrical=false kind=Mandatory
# pcs cluster cib-push cluster1.xml

 

Cette configuration devra donc donner les informations suivantes avec un pcs status :

# pcs status --full
Cluster name: cluster_pghd12
Stack: corosync
Current DC: ip-172-44-2-226 (1) (version 1.1.21-4.el7-f14e36fd43) - partition with quorum
Last updated: Fri Sep 4 10:15:16 2020
Last change: Fri Sep 4 10:12:37 2020 by root via cibadmin on ip-172-44-2-143

2 nodes configured
5 resources configured

Online: [ ip-172-44-2-143 (2) ip-172-44-2-226 (1) ]

Full list of resources:

Master/Slave Set: pgsql-ha [pgsqld]
pgsqld (ocf::heartbeat:pgsqlms): Slave ip-172-44-2-226
pgsqld (ocf::heartbeat:pgsqlms): Master ip-172-44-2-143
Masters: [ ip-172-44-2-143 ]
Slaves: [ ip-172-44-2-226 ]
clusterfence (stonith:fence_aws): Started ip-172-44-2-143
Resource Group: aws-group
pgsql_awsvip (ocf::heartbeat:awsvip): Started ip-172-44-2-143
pgsql-master-ip (ocf::heartbeat:IPaddr2): Started ip-172-44-2-143

Node Attributes:
* Node ip-172-44-2-143 (2):
+ master-pgsqld : 1001
* Node ip-172-44-2-226 (1):
+ master-pgsqld : 1000

PCSD Status:
ip-172-44-2-143: Online
ip-172-44-2-226: Online

Daemon Status:
corosync: active/disabled
pacemaker: active/disabled
pcsd: active/enabled

 

Dans cette configuration, nous voyons bien que le nœud primaire est ip-172-44-2-143, celui ci porte la VIP système et la seconde IP AWS.
L’instance PostgreSQL est primaire sur ce noeud. Vérifions les informations  :

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.44.2.143  netmask 255.255.255.0  broadcast 172.44.2.255
        inet6 fe80::845:a9ff:fec9:3e  prefixlen 64  scopeid 0x20<link>
        ether 0a:45:a9:c9:00:3e  txqueuelen 1000  (Ethernet)
        RX packets 57218  bytes 54966962 (52.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42097  bytes 5473829 (5.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.44.2.144  netmask 255.255.255.0  broadcast 172.44.2.255
        ether 0a:45:a9:c9:00:3e  txqueuelen 1000  (Ethernet)

 

et sur AWS

 

 

[root@ip-172-44-2-143:0 ~]# Instance_ID=`/usr/bin/curl --silent http://169.254.169.254/latest/meta-data/instance-id`
[root@ip-172-44-2-143:0 ~]# aws ec2 describe-instances --instance-ids  $Instance_ID --region eu-west-3 | grep "PrivateIpAddress"
                    "PrivateIpAddress": "172.44.2.143",
                            "PrivateIpAddress": "172.44.2.143",
                            "PrivateIpAddresses": [
                                    "PrivateIpAddress": "172.44.2.143"
                                    "PrivateIpAddress": "172.44.2.144"




S’il l’on lance une connexion depuis un client PostgreSQL quelconque (exemple d’un VM dont l’IP est dans le même subnet, à savoir 172.44.2.194)

[postgres@ip-172-44-2-194 ~]$ psql -h 172.44.2.144 -U manu manuelo
Password for user manu:
psql (12.0, server 12.4)
Type "help" for help.

manuelo=# select usename,client_addr,query from pg_stat_activity where usename is not null;
 usename   | client_addr  | query
 ----------+--------------+----------------------------------------------------------------------------------- 
 postgres  |              |
 repli     | 172.44.2.226 |
 manu      | 172.44.2.194 | select usename,client_addr,query from pg_stat_activity where usename is not null;
 
(3 rows)

Nous avons donc réaliser notre connexion sur la VIP 172.44.2.144 depuis une autre VM EC2 Amazon du même subnet.
Nous voyons également que la réplication, via le user “repli” est active depuis l’autre noeud du cluster portant l’IP 172.44.2.226.

Il suffira de jouer avec les “security groups” Amazon afin d’autoriser la connexion à la VIP pour d’autres VMs d’un subnet différent et pouvoir ainsi autoriser les connexions.

 

Exploitation du cluster

Cas d’une bascule d’instance PostgreSQL

Il sera tout à fait possible d’effectuer un switchover d’instance PostgreSQL.
Rappelons que pour notre exemple, l’instance primaire est sur ip-172-44-2-143 et la standby sur ip-172-44-2-226 :

# pcs status --full
…..
 Master/Slave Set: pgsql-ha [pgsqld]
     pgsqld     (ocf::heartbeat:pgsqlms):       Slave ip-172-44-2-226
     pgsqld     (ocf::heartbeat:pgsqlms):       Master ip-172-44-2-143
     Masters: [ ip-172-44-2-143 ]
     Slaves: [ ip-172-44-2-226 ]
clusterfence   (stonith:fence_aws):    Started ip-172-44-2-143
 Resource Group: aws-group
     pgsql_awsvip       (ocf::heartbeat:awsvip):        Started ip-172-44-2-143
     pgsql-master-ip    (ocf::heartbeat:IPaddr2):       Started ip-172-44-2-143

 

S’il l’on souhaite inverser les rôles, donc passer l’instance primaire sur ip-172-44-2-226, et la standby sur ip-172-44-2-143, nous lancerons la commande suivante;

# pcs resource move --wait --master pgsql-ha
Resource 'pgsql-ha' is master on node ip-172-44-2-226; slave on node ip-172-44-2-143.

 

Dans le cas d’un cluster 3 noeuds et plus, ajouter à la fin de la commande, le nom du noeud.
Regardons l’état du cluster, et de l’instance PostgreSQL :

[root@ip-172-44-2-226:0 ~]# pcs status --full
...
 Master/Slave Set: pgsql-ha [pgsqld]
     pgsqld     (ocf::heartbeat:pgsqlms):       Master ip-172-44-2-226
     pgsqld     (ocf::heartbeat:pgsqlms):       Slave ip-172-44-2-143
     Masters: [ ip-172-44-2-226 ]
     Slaves: [ ip-172-44-2-143 ]
 clusterfence   (stonith:fence_aws):    Started ip-172-44-2-143
 Resource Group: aws-group
     pgsql_awsvip       (ocf::heartbeat:awsvip):        Started ip-172-44-2-226
     pgsql-master-ip    (ocf::heartbeat:IPaddr2):       Started ip-172-44-2-226

 

Nous remarquons également que la VIP locale et l’adresse IP secondaire Amazon ont basculées vers ip-172.44.2.226

# ifconfig

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.44.2.226  netmask 255.255.255.0  broadcast 172.44.2.255
        inet6 fe80::8ae:d4ff:feac:9526  prefixlen 64  scopeid 0x20<link>
        ether 0a:ae:d4:ac:95:26  txqueuelen 1000  (Ethernet)
        RX packets 518354  bytes 389187631 (371.1 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 394871  bytes 219328497 (209.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


eth0:1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.44.2.144  netmask 255.255.255.0  broadcast 172.44.2.255
        ether 0a:ae:d4:ac:95:26  txqueuelen 1000  (Ethernet)

 

et sur AWS

 

#  aws ec2 describe-instances --instance-id $Instance_ID --region eu-west-3 | grep "PrivateIpAddress"
                    "PrivateIpAddress": "172.44.2.226",
                            "PrivateIpAddress": "172.44.2.226",
                            "PrivateIpAddresses": [
                                    "PrivateIpAddress": "172.44.2.226"
                                    "PrivateIpAddress": "172.44.2.144"

 

Une connexion cliente viendra valider notre bascule. Notre connexion “repli” de l’instance standby se fait depuis ip-172-44-2-143.

 

[postgres@ip-172-44-2-194 ~]$ psql -h 172.44.2.144 -U manu manuelo
Password for user manu:
psql (12.0, server 12.4)
Type "help" for help.

manuelo=# select usename,client_addr,query from pg_stat_activity where usename is not null;
 usename  | client_addr  | query
 ---------+--------------+-----------------------------------------------------------------------------------
 repli    | 172.44.2.143 |
 postgres |              |
 manu     | 172.44.2.194 | select usename,client_addr,query from pg_stat_activity where usename is not null;

(3 rows)

 

 

fencing de noeud

Lorsque nous avons effectué notre bascule de la ressource “pgsql-ha”, nous avons vu que nous sommes passés, pour l’instance PostgreSQL et la VIP, du noeud ip-172-44-2-143 vers ip-172-44-2-226.

En revanche, ce que nous voyons également, c’est que la ressource “clusterfence” est restée en mode master sur ip-172-44-2-143.

Cela veut dire que, au redémarrage complet du cluster, c’est ce nœud qui est configuré comme master, et donc qui reprendra l’instance PostgreSQL en tant que primaire.

S’il l’on tente un fencing sur l’instance EC2 AWS ip-172-44-2-143.

# pcs stonith fence ip-172-44-2-143
Node: ip-172-44-2-143 fenced

Nous perdons immédiatement la connexion au serveur ip-172-44-2-143. Celui ci doit redémarrer.
Au redémarrage, celui ci revient, mais rien ne change, car “pgsql-ha” était déjà en mode primaire sur ip-172-44-2-226.

Full list of resources:

 Master/Slave Set: pgsql-ha [pgsqld]
     pgsqld     (ocf::heartbeat:pgsqlms):       Master ip-172-44-2-226
     pgsqld     (ocf::heartbeat:pgsqlms):       Slave ip-172-44-2-143
     Masters: [ ip-172-44-2-226 ]
     Slaves: [ ip-172-44-2-143 ]
 clusterfence   (stonith:fence_aws):    Started ip-172-44-2-143
 Resource Group: aws-group
     pgsql_awsvip       (ocf::heartbeat:awsvip):        Started ip-172-44-2-226
     pgsql-master-ip    (ocf::heartbeat:IPaddr2):       Started ip-172-44-2-226

 

Il n’y a donc eu aucune interruption sur l’instance PostgreSQL.
On peut d’ailleurs voir , avec la commande “pcs status –full”, l’historique de fencing pour ce cluster

Fencing History:
* reboot of ip-172-44-2-143 successful: delegate=ip-172-44-2-226, client=stonith_admin.24029, origin=ip-172-44-2-226,
completed='Fri Sep 4 12:56:55 2020'

 

Mais que se passe-t-il si c’est le nœud primaire qui “fence” ?

 

[root@ip-172-44-2-143:0 ~]# pcs stonith fence ip-172-44-2-226
Node: ip-172-44-2-226 fenced

 

A noter que la commande met un peu plus de temps pour rendre la main, les opérations en cours sont plus nombreuses.

Et grâce à PAF , aussitôt ça bascule !!

 

[root@ip-172-44-2-143:0 ~]# pcs status --full
….
Online: [ ip-172-44-2-143 (2) ]
OFFLINE: [ ip-172-44-2-226 (1) ]

Full list of resources:

 Master/Slave Set: pgsql-ha [pgsqld]
     pgsqld     (ocf::heartbeat:pgsqlms):       Master ip-172-44-2-143
     pgsqld     (ocf::heartbeat:pgsqlms):       Stopped
     Masters: [ ip-172-44-2-143 ]
     Stopped: [ ip-172-44-2-226 ]
 clusterfence   (stonith:fence_aws):    Started ip-172-44-2-143
 Resource Group: aws-group
     pgsql_awsvip       (ocf::heartbeat:awsvip):        Started ip-172-44-2-143
     pgsql-master-ip    (ocf::heartbeat:IPaddr2):       Started ip-172-44-2-143

 

Le nœud ip-172-44-2-226 est noté OFFLINE, mais nous récupérons aussitôt l’instance primaire PostgreSQL sur ip-172-44-2-143.

Lorsque le nœud ip-172-44-2-226 a fini de redémarrer complètement, l’instance PostgreSQL passe en mode slave sur celui ci.

 

[root@ip-172-44-2-143:0 ~]# pcs status --full
…
Online: [ ip-172-44-2-143 (2) ip-172-44-2-226 (1) ]

Full list of resources:


 Master/Slave Set: pgsql-ha [pgsqld]
     pgsqld     (ocf::heartbeat:pgsqlms):       Slave ip-172-44-2-226
     pgsqld     (ocf::heartbeat:pgsqlms):       Master ip-172-44-2-143
     Masters: [ ip-172-44-2-143 ]
     Slaves: [ ip-172-44-2-226 ]
 clusterfence   (stonith:fence_aws):    Started ip-172-44-2-143
 Resource Group: aws-group
     pgsql_awsvip       (ocf::heartbeat:awsvip):        Started ip-172-44-2-143
     pgsql-master-ip    (ocf::heartbeat:IPaddr2):       Started ip-172-44-2-143

 

Une fois de plus, l’historique de fencing indique que tout s’est bien déroulé

Fencing History:
* reboot of ip-172-44-2-226 successful: delegate=ip-172-44-2-143, client=stonith_admin.2316, origin=ip-172-44-2-143,
    completed='Fri Sep  4 13:10:37 2020'

 

Conclusion

 

Grâce au package “fence-agents-aws” disponible dans les dépôts Red Hat CentOS, nous disposons d’une solution de fencing efficace dans le cadre de l’utilisation d’un cluster PostgreSQL HD sur des VM Amazon.
La VIP, au sein de AWS, consiste alors à fournir une seconde adresse IP au noeud portant l’instance primaire.

 

Il est également possible, grâce à ce package, de travailler sur une Elastic IP :

# pcs resource describe awseip
Assumed agent name 'ocf:heartbeat:awseip' (deduced from 'awseip')
ocf:heartbeat:awseip - Amazon AWS Elastic IP Address Resource Agent

Resource Agent for Amazon AWS Elastic IP Addresses.

It manages AWS Elastic IP Addresses with awscli.

 

Cette Elastic IP pourra alors basculer d’une VM EC2 à une autre dans le cadre du cluster.
Ceci peut être utilisé pour un site Web ou un serveur d’application avec haute disponibilité sur des VM Amazon nécessitant une IP Publique.

 

@ bientôt

 

Emmanuel RAMI

Continuez votre lecture sur le blog :

twitterlinkedinmail

Emmanuel RAMI

2 commentaires

  1. Salut, et merci pour le tuto !
    Le application_name dans postrgresql.auto.conf, il est à rajouter manuellement ou il est censé être écrit par postgres lors de la config du streaming replication ? Le mien ne contient pas de application_name…

  2. Bonjour Thomas
    il faut l’ajouter manuellement, celui ci est, en effet, utilisé pour Corosync/pacemaker.
    Il peut servir également lorsque vous configurer un “replication slot” dans PostgreSQL, vous avez alors l’info dans la vue “pg_replication_slots”.
    Attention, pour “application_name”, il faut bien positionner le nom du serveur sur lequel vous êtes situé.
    Cordialement.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.