Yacine Merghoub

Chaîne DevOps intégrant Jenkins avec Ansible ou OpenShift (2/2)

Introduction

Le but de cet article est de présenter brièvement le concept de DevOps, illustré par une implémentation concrète dans un environnement applicatif de microservices Restfull, développés dans le contexte d’une approche agile.

La première partie est consacrée au rappel des principes de DevOps et à la présentation du schéma architectural d’une chaîne DevOps avec Github, Jenkins, Artifactory et Ansible.

Cette deuxième partie présente une autre chaîne DevOps avec Github, Jenkins, Artifactory et OpenShift.

1 Exemple d’une mise en oeuvre avec OpenShift

La chaîne DevOps décrite ci-dessous permet d’assurer des déploiements dans une plateforme de containers (OpenShift) sur différents namespaces  (§. 1.1 ci-dessous) : INT, VAL et PROD.

Elle est composée des éléments suivants :

  • GitHub
  • Git local installé sur chaque poste développeur
  • OpenShift qui héberge différents namespaces. Dans chaque namespace, un pod Jenkins pilote les builds (compilation/packaging) et le déploiement
  • Artifactory : repository des artifacts

Dans ce cas d’utilisation, tout se passe dans OpenShift, plateforme de containers. La plateforme est structurée en namespaces. Chaque namespace correspond à un environnement technique d’un projet (VAL, INT, PROD, …).

Chaque namespace (§. 1.1 ci-dessous) dispose de son propre pod Jenkins. Celui-ci exécute, à chaque update du projet dans Github (déclenchement par webhook), un job de type pipeline qui comporte plusieurs phases (stages) :

    1. Git clone du repository Github
    2. Build par maven (compilation –> tests unitaires –> tests intégration –> packaging)
    3. Audit du code par sonar
    4. Déploiement exécuté en fonction d’une build configuration et d’une deployment configuration (§. 1.1 ci-dessous)
      • Création d’une image docker à partir des sources de l’application
      • Création d’un pod (host exécutant le microservice) incluant le container de cette image
      • Génération du service, interface externe correspondant aux différents pods d’une application, et joue le rôle de répartiteur de charge
      • Génération des routes qui permettent d’accéder au service d’un pod

Exemple d’un dashboard de pipeline Jenkins, illustré ci-dessous :

Par ailleurs, OpenShift assure d’autres fonctionnalités opérationnelles :

  • Il gère les variations de charge de l’application par l’intermédiaire d’un replication controller: ajuste le nombre d’instances d’un pod en fonction de la charge.
  • Il assure le monitoring des applications qu’il héberge
  • Il gère les logs : logs des builds et logs applicatifs
  • Il permet via une interface Web d’accéder et d’administrer toutes ces fonctionnalités (§. 1.3 ci-dessous)

 

1.1    Notion de namespace dans OpenShift

La notion de namespace dans OpenShift vient de Kubernetes dont il est une sur-couche. Elle permet de regrouper dans un même espace de nommage les ressources qui décrivent une application et comment elle doit être déployée. La figure ci-dessous regroupe tous les éléments qui constituent un namespace :

Contrairement à Kubernetes qui permet d’accéder à tous les namespaces d’un cluster, OpenShift encapsule chaque namespace dans un projet qui va permettre d’en contrôler les accès par un modèle d’authentification et d’autorisations basé sur les users et les groups.

Il existe 3 canaux pour interagir avec un cluster Openshift à travers son API Rest : une CLI (ligne de commande) oc, une interface Web et l’API elle-même. Plus de détails dans la documentation OpenShift.

1.2    CLI (Ligne de commande) OpenShift

L’objet de ce document n’étant pas d’exposer en détail le fonctionnement d’OpenShift, on se contentera de montrer ci-dessous quelques vues du déploiement d’un service de base de données PostgreSql en exécutant des commandes oc. Dans le paragraphe suivant, on verra les vues relatives à ce service dans la console Web.

  • Déploiement d’une base PostgreSql

  • Affichage de la description du déploiement dc/my-database, créé par la commande précédente :

1.3    Console web OpenShift

Ci-dessous, quelques vues dans la console Web relatives au déploiement décrit dans le paragraphe précédent :

  • Description du déploiement dc/my-database : on voit une représentation du pod correspondant. Les flèches haut/bas (encadrée en rouge) permettent d’augmenter/diminuer manuellement le nombre d’instances du pod.

 

  • Vue des services : Outre le service my-database, on distingue un autre service, (microservice springboot) déployé qui utilise le service my-database

  • Vue d’une route (URL) pour accéder au microservice :

  • Vue du monitoring :

 En résumé

Dans cet article ont été rappelés les concepts de DevOps en relation avec une approche agile du développement d’applications. Deux schémas architecturaux de chaînes DevOps sont présentés ayant en commun les outils de versionning et de repositories (GitHub et Artifactory) ainsi que Jenkins comme pilote de l’intégration et du déploiement continus.

Dans cette deuxième partie, la chaîne DevOps présentée utilise OpenShift. Celui-ci joue les rôles à la fois d’une plateforme de containers et d’un cloud privé. A travers la notion de namespace encapsulé dans un projet, il gère les aspects droits d’accès, cycle de vie des applications, répartition de charges, gestion des logs et monitoring.

La première partie de cet artice est consacrée à la présentation d’une autre chaîne DevOps.  Elle utilise Ansible pour exécuter les déploiements sur les différents nœuds et environnements de l’application. Ansible est installé sur un nœud unique et permet via les playbooks et son interface Ansible Tower d’automatiser le processus de déploiement sur un grand nombre de nœuds (serveurs, périphériques, …).

 Pour en savoir plus

Chaîne DevOps intégrant Jenkins avec Ansible ou OpenShift (1/2)

Introduction

Le but de cet article est de présenter brièvement le concept de DevOps, illustré par une implémentation concrète dans un environnement applicatif de microservices Restfull, développés dans le contexte d’une approche agile.

La première partie est consacrée au rappel des principes de DevOps et à la présentation du schéma architectural d’une chaîne DevOps avec Github, Jenkins, Artifactory et Ansible.

La deuxième partie présente une autre chaîne DevOps avec Github, Jenkins, Artifactory et OpenShift.

1      Agile et DevOps main dans la main

Image result for devops

Le développement d’applications dans le cadre d’une approche agile impose des livraisons fréquentes au rythme des itérations,  tout en préservant la qualité des livrables, la maîtrise des releases et l’adaptabilité à différents environnements techniques et applicatifs. Pour répondre à ces exigences, l’automatisation des processus est nécessaire ainsi qu’une synergie entre les équipes de développement et celles des opérations. C’est là que DevOps apporte la solution à ces problématiques d’intégration continue (IC) et de déploiement continu (DC).

2     Les apports de DevOps

  • Fréquence des déploiements accrue
  • Délai d’exécution réduit pour les modifications
  • Récupération plus rapide en cas de problème
  • Une sécurité plus robuste et mieux intégrée
  • Qualité accrue
  • Feedback rapide

3      Les outils de DevOps

A chacune des étapes du workflow automatisé de DevOps correspondent des outils open source ou propriétaires (ci-dessous une liste non exhaustive) :

  • Versionning-commit de code : SVN, Git, TFS, GitHub, Tuleap
  • Qualité de code : SonarQube, IntelliJ, Eclipse
  • Sécurité : SonarQube, Checkmarx, dependency-check-maven
  • Tests : JUnit, Mockito, Selenium, Postman, Gatling, Jmeter
  • Build : Maven, NPM
  • Intégration/Déploiement/Livraison continus : Jenkins, Teamcity, Bamboo, TFS
  • Gestion des releases : Nexus, Artifactory
  • Déploiement : Ansible, Docker, OpenShift, Azure, AWS, VmWare
  • Performance, monitoring : Nagios, Zabbix, Spring boot Actuator
  • Logs : Splunk, Logstash, Elasticsearch

4      Exemple d’une mise en oeuvre avec Ansible

La chaîne DevOps décrite ci-dessous permet d’assurer des déploiements sur différents environnements techniques : INT, VAL et PROD.

Elle est composée des éléments suivants :

  • GitHub
  • Git local installé sur chaque poste développeur
  • Jenkins assure les builds (compilation/packaging)
  • Artifactory : repository des artifacts
  • Ansible assure les déploiements


Dans ce cas d’utilisation, un job Jenkins pilote le build (compilation, tests unitaires automatisés, audit de code par SonarQube, packaging). L’artifact résultant (un jar, dans le cas d’un microservice springboot) est uploadé dans Artifactory.

En post-action, le job va déclencher un script Ansible chargé de déployer le microservice dans les différents nœuds d’un cluster.

4.1    Concepts utilisés dans Ansible

Ansible permet d’automatiser les tâches de configuration et de déploiement des applications. Son administration se fait par le biais d’une interface Web, Ansible Tower.

Cette administration est centralisée dans une seule machine, le Control Node, où est installé Ansible. Aucune installation d’un agent n’est faite sur les autres machines gérées par Ansible (Managed nodes). Les concepts énumérés ci-dessous permettent de comprendre le fonctionnement de Ansible :

  • Inventory (inventaire) : liste des nœuds gérés, spécifiant des informations telles que les adresses IP. Cette liste peut être organisée selon différents critères : localisation, fonction, …
  • Module: c’est une unité de code Ansible spécialisée sur un type de fonctionnalités qu’on peut invoquer pour exécuter des tâches : administration des utilisateurs sur un type spécifique de base de données, gestion des interfaces VLAN sur un type spécifique de périphérique réseau, etc …
  • Task: c’est une unité d’action Ansible qu’on peut exécuter par une commande
  • Playbook: Liste ordonnée de tâches, enregistrées à exécuter à plusieurs reprises. Les playbooks peuvent inclure des variables ainsi que des tâches. C’est des fichiers écrits en YAML.
  • Roles : les rôles sont définis pour charger automatiquement des fichiers de configuration, tâches et gestionnaires. Ils sont organisés sous forme de fichiers dans des répertoires ayant un nommage et une structure pré-définis. Les rôles sont invoqués dans les playbooks (comme les imports dans un fichier java).

Exemple de mise en œuvre d’Ansible dans   Integrating Ansible with Jenkins in a CI/CD process.

  En résumé

Dans cette première partie,  ont été rappelés les concepts de DevOps en relation avec une approche agile du développement d’applications. Un premier schéma architectural de chaîne DevOps est présenté ayant comme outil de versionning et de repositories GitHub et Artifactory,  Jenkins comme pilote de l’intégration et du déploiement continus.

Cette chaîne utilise Ansible pour exécuter les déploiements sur les différents nœuds et environnements de l’application. Ansible est installé sur un nœud unique et permet via les playbooks et son interface Ansible Tower d’automatiser le processus de déploiement sur un grand nombre de nœuds (serveurs, périphériques, …).

Dans la deuxième partie, un autre schéma architectural d’une chaîne DevOps utilisant OpenShift sera présenté.

  Pour en savoir plus

Mise en oeuvre de la Haute disponibilité dans PostgreSQL

Rappels de quelques notions

Avant d’aborder le sujet de la HA (High Availability), il est utile de rappeler quelques principes qui vont être utilisés dans la suite de cet exposé.

RPO et RTO

Il existe plusieurs méthodes de sauvegarde d’une base de données PostgreSQL, chacune présentant des avantages et des inconvénients eu égard à la volumétrie des données, à la granularité des sauvegardes qu’on veut réaliser, à la cohérence des données sauvegardées, au transfert des données entre différentes versions de PostgreSQL et entre machines d’architectures différentes. Par ailleurs, on distingue deux types de sauvegardes : les sauvegardes logiques et les sauvegardes physiques.

Une sauvegarde logique consiste à archiver les commandes sql qui ont servi à générer la base et à les rejouer pour la restauration de celle-ci. Pour celà, il existe 2 commandes dans PostgreSQL : pg_dump et pg_dumpall. On trouvera plus de détails sur ces commandes dans  la documentation de PostgreSQL https://www.postgresql.org/docs/10/backup.html.

Une sauvegarde physique ou sauvegarde au niveau du système de fichiers consiste à archiver les répertoires des données de la base en utilisant les commandes de copie ou d’archivage des fichiers du système d’exploitation : tar, cp, scp, rsync, … On peut aussi réaliser une “image gelée” (frozen snapshot) du volume contenant la base de données et ensuite copier entièrement le répertoire de données (pas seulement quelques parties) de l’image sur un périphérique de sauvegarde, puis de libérer l’image gelée.

Les objectifs d’une bonne procédure de sauvegarde sont exprimés par deux métriques :

  • le RPO (Recovery Point Objective) : représente la quantité maximum de données qu’on peut tolérer de perdre suite à un incident de la base de données.
  • le RTO (Recovery Time Objective) : représente la durée maximum d’une interruption de service qu’on peut tolérer, le temps de restaurer la base et la remettre en service.

L’objectif idéal étant que ces 2 paramètres soient nuls, PostgreSQL propose des approches qui permettent de s’en approcher. Elles sont basées sur la mise en oeuvre de l’archivage continu et la récupération  d’un instantané (PITR : Point In Time Recovery).

Archivage continu et PITR

Cette approche est basée sur l’utilisation des journaux WAL (Write Ahead Log), appelés aussi journaux des transactions. Ils enregistrent chaque modification effectuée sur les fichiers de données des bases. Ils sont stockés dans le sous-répertoire pg_wal/ du répertoire des données du cluster.

La sauvegarde consiste à combiner une sauvegarde de niveau système de fichiers avec la sauvegarde des fichiers WAL.

La restauration consiste à restaurer les fichiers de la base puis de rejouer les fichiers WAL sauvegardés jusqu’à emmener la base à son état actuel.

Avantages :

  • Il n’est pas nécessaire de disposer d’une sauvegarde des fichiers parfaitement cohérente comme point de départ. Toute incohérence dans la sauvegarde est corrigée par la ré-exécution des journaux
  • Puisqu’une longue séquence de fichiers WAL peut être assemblée pour être rejouée, une sauvegarde continue est obtenue en continuant simplement à archiver les fichiers WAL. C’est particulièrement intéressant pour les grosses bases de données dont une sauvegarde complète fréquente est difficilement réalisable.
  • Les entrées WAL ne doivent pas obligatoirement être rejouées intégralement. La ré-exécution peut être stoppée en tout point, tout en garantissant une image cohérente de la base de données telle qu’elle était à ce moment-là. Ainsi, cette technique autorise la récupération d’un instantané (PITR) : il est possible de restaurer l’état de la base de données telle qu’elle était en tout point dans le temps depuis la dernière sauvegarde de base.
  • Si la série de fichiers WAL est fournie en continu à une autre machine chargée avec le même fichier de sauvegarde de base, on obtient un système « de reprise intermédiaire » : à tout moment, la deuxième machine peut être montée et disposer d’une copie quasi-complète de la base de données.

Contraintes :

  • approche plus complexe à administrer
  • ne supporte que la restauration d’un cluster de bases de données complet, pas d’un sous-ensemble
  • espace d’archivage important requis : si la sauvegarde de base est volumineuse et si le système est très utilisé, ce qui génère un grand volume de WAL à archiver.

La réplication

Dans une architecture maître-esclave, le transfert des données de base et des WAL (Log shipping) peut se configurer de 3 manières légèrement différentes :

  • Warm Standby : les fichiers des transactions (WAL) archivés sont transférés du maître vers l’esclave par copie et rejoués, avec un retard d’un fichier WAL (16 MB) par rapport au maître. La perte éventuelle de données ne peut donc excéder 16 MB. Dans cette configuration, la base esclave n’est pas accessible.
  • Hot Standby : le fonctionnement est identique au Warm Standby. La différence est que la base esclave est accessible en lecture seule.
  • Streaming Replication :  dans cette configuration, chaque transaction est transférée vers la machine esclave via le réseau, et rejouée, sans attendre que le fichier WAL soit complété.  Ainsi, le RPO est quasiment nul (une transaction perdue au maximum dans une réplication asynchrone, 0 dans une réplication synchrone).

Tolérance à panne

La tolérance à panne (failover) est la capacité d’un système à maintenir un état de fonctionnement en dépit d’une défaillance logicielle ou matérielle. Elle est rendue possible par la réplication. Nous étudierons ici les moyens à mettre en oeuvre pour assurer une continuité de service en toutes circonstances.

Gestion du Failover avec repmgr

Une Architecture Maître/Esclave sert à gérer les situations de failover où la machine Esclave prend le relais en cas de défaillance de la machine Maître.

Pour ce faire, une réplication continue est instaurée entre les 2 machines de telle façon que les données des 2 machines soient quasiment identiques à chaque instant.

Pour pouvoir gérer en plus,  la capacité de déclencher la bascule (le failover) automatiquement, il existe plusieurs outils dans l’écosystème PostgreSQL tels que repmgr. Celui-ci peut-être utilisé seul ou en conjonction avec d’autres outils de backup comme BARMAN (Backup and Recovery Manager for PostgreSQL) développé par 2ndQuadrant (https://www.2ndquadrant.com/) avec une licence GPL v3, dont la dernière version est la 2.5 du 23/10/2018 (http://www.pgbarman.org/).

Présentation de repmgr

repmgr est une suite d’outils open source développés par 2dQuadrant ( https://repmgr.org/docs/4.2/index.html) qui mettent en oeuvre la réplication native de PostgreSQL et qui permettent de disposer d’un serveur dédié aux opérations de lecture/écriture (Primary ou Maître) et d’un ou plusieurs serveurs en lecture seule (Standby ou Esclave). Deux principaux outils sont fournis :

  • repmgr : outil en ligne de commandes pour les tâches d’administration :
    • configuration des serveurs standby
    • promotion d’un serveur standby en primary
    • inverser les rôles des deux serveurs (switchover)
    • afficher les statuts des serveurs
  • repmgrd : deamon qui supervise l’état des serveurs et qui permet de :
    • surveiller les performances
    • opérer un failover quand il détecte la défaillance du primary en promouvant le standby
    • émettre des notifications sur des événements qui peuvent survenir sur les serveurs à des outils qui vont déclencher des alertes (mail par exemple)

Architecture

Pré-requis système

  • Linux/Unix
  • repmgr 4.x compatible avec PostgreSQL 9.3+
  • La même version de PostgreSQL sur tous les serveurs du cluster
  • repmgr doit être installé sur tous les serveurs du cluster, au moins dans la même version majeure*
  • les connections entre serveurs doivent être ouvertes sur leurs ports respectifs
  • les accès ssh par échange de clés publiques pour le user postgres de chacun des serveurs doivent être configurés.

Installation

L’installation se fait pour :

  • RedHat/CentOS/Fedora à partir du repository yum de 2ndQuadrant
  • Debian/Ubuntu à partir des repository APT de postgreSQL (http://apt.postgresql.org/) ou du repository APT de 2ndQuadrant (https://dl.2ndquadrant.com/default/release/site/)

Pour la version 10 de PostgrSQL :

sudo apt-get install postgresql-10-repmgr

Configuration de PostgreSQL

Les exemples ci-dessous concernent une version 10.x de PostgreSQL

Ajuster les paramètres ci-dessous dans les fichiers de configuration des PostgreSQL (postgresql.conf) :

  # Enable replication connections; set this figure to at least one more
   # than the number of standbys which will connect to this server
   # (note that repmgr will execute `pg_basebackup` in WAL streaming mode,
   # which requires two free WAL senders)

 max_wal_senders = 10

   # Enable replication slots; set this figure to at least one more
   # than the number of standbys which will connect to this server.
   # Note that repmgr will only make use of replication slots if
   # « use_replication_slots » is set to « true » in repmgr.conf

max_replication_slots = 3

   # Ensure WAL files contain enough information to enable read-only queries
   # on the standby.
   #
   # PostgreSQL 9.5 and earlier: one of ‘hot_standby’ or ‘logical’
   # PostgreSQL 9.6 and later: one of ‘replica’ or ‘logical’
   # (‘hot_standby’ will still be accepted as an alias for ‘replica’)
   #
   # See: https://www.postgresql.org/docs/current/static/runtime-config-wal.html#GUC-WAL-LEVEL

wal_level = replica

   # Enable read-only queries on a standby
   # (Note: this will be ignored on a primary but we recommend including
   # it anyway)

hot_standby = on

   # Enable WAL file archiving
archive_mode = on

   # Set archive command to a script or application that will safely store
   # you WALs in a secure place. /bin/true is an example of a command that
   # ignores archiving. Use something more sensible.
 archive_command = ‘/bin/true’

Création du user repmgr et du schéma repmgr

Le schéma repmgr sert à enregistrer les données de monitoring de repmgr. On y accède avec le user repmgr. Ils doivent être créés sur chacun des instances des serveurs :

sudo -i -u postgres

psql -p 5432

create role repmgr with password ‘password123’ ; alter role repmgr login ; alter role repmgr replication ; alter role repmgr superuser;

CREATE DATABASE repmgr OWNER repmgr;

Configuration de pg_hba.conf

L’objectif de cette configuration est de permettre au user repmgr de se connecter en mode replication :

 local   replication   repmgr                       trust
 host    replication   repmgr 127.0.0.1/32            trust
 host    replication   repmgr 195.154.39.0/24      trust

  local   repmgr      repmgr                       trust
  host    repmgr      repmgr 127.0.0.1/32             trust
  host    repmgr      repmgr 195.154.39.0/24         trust

Vérifier que la base sur le serveur primaire est joignable à partir du serveur standby :

psql ‘host=195.154.39.62 user=repmgr dbname=repmgr connect_timeout=2’

Configuration de repmgr dans le noeud primaire

La configuration se fait dans le fichier /etc/repmgr.conf aux niveau du primaire (node_id=1, node_name=val) et du standby ((node_id=2, node_name=customers).

Remarques :

  • Les paramètres indiqués ci-dessus sont les paramètres de base pour un fonctionnement standard de repmgr. On trouvera d’autres paramètres disponibles dans le fichier repmgr.conf.sample  fourni dans la distribution.

Enregistrement du serveur primaire

L’enregistrement du serveur primaire auprès de repmgr va créer les métadata dans le schéma repmgr et y initialisera un enregistrement correspondant au serveur primaire :

  • Avec le user postgres , exécuter la commande suivante :
  • $ repmgr -f /etc/repmgr.conf primary register
  • Vérifier le statut du cluster avec  la commande suivante :

Les metatda sont affichés  avec la commande suivante :

Configuration du serveur standby

Créer le fichier de configuration /etc/repmgr.conf, similaire à celui du primaire. Il diffère essentiellement par le n° et le nom du noeud ainsi que la chaîne de connexion conninfo :

Clonage du serveur standby

On exécutera la commande de clonage en dry-run pour s’assurer que toutes les conditions de succès sont satisfaites :

  • postgres@customers:~$ repmgr -h 195.154.39.62 -U repmgr -d repmgr -p 5434 -f /etc/repmgr.conf -F standby clone –dry-run

Si pas de problème rapporté, exécuter la même commande sans l’option dry-run :

  • postgres@customers:~$ repmgr -h 195.154.39.62 -U repmgr -d repmgr -p 5434 -f /etc/repmgr.conf -F standby clone
  • Si le clonage s’est bien terminé , vérifier que la réplication se passe bien.
    • Dans le serveur primaire, exécuter la commande suivante :
  • Dans le serveur standby, exécuter la commande suivante :

  • Enregistrer le standby :

postgres@customers:~$  /usr/lib/postgresql/10/bin/repmgr standby register

  • Vérifier que le standby est enregistré :

Vérifier que tout fonctionne

  • Créer une table sur le maître :

CREATE TABLE rep_test (test varchar(40));

INSERT INTO rep_test VALUES (‘replique moi);

  • Vérifier qu’elle est répliquée dans le standby:

SELECT * FROM rep_test;

Failover automatique avec repmgrd

Dans le schéma ci-dessus, si val est indisponible , customers est promu en primary, et en mode read-write. Ce failover peut être exécuté manuellement avec 2 commandes de repmgr :

  • Au niveau de customers : /usr/bin/repmgr standby promote -f /etc/repmgr.conf –log-to-file
  • Au cas où il y aurait plusieurs serveurs standby, on exécute au niveau de chacun une commande de follow, qui leur indique le nouveau serveur maître :

/usr/bin/repmgr standby follow -f /etc/repmgr.conf –log-to-file –upstream-node-id=2

Le daemon repmgrd permet de surveiller l’état des serveurs du cluster et de déclencher automatiquement les 2 opérations décrites ci-dessus.

Configuration de repmgrd

  • Pour utiliser repmgrd, inclure la librairie associée via la configuration de postgresql.conf :

shared_preload_libraries = ‘repmgr’

  • ajouter dans /etc/repmgr.conf les lignes suivantes :

failover=automatic

promote_command=’/usr/lib/postgresql/10/bin/repmgr standby promote -f /etc/repmgr.conf –log-to-file’

follow_command=’/usr/lib/postgresql/10/bin/repmgr standby follow -f /etc/repmgr.conf –log-to-file –upstream-node-id=%n’

monitoring_history=yes

  • Si repmgr a été installé à partir des packages de Debian/Ubuntu, il faudra configurer pour que repmgrd tourne en daemon, via le fichier /etc/default/repmgrd , dont le contenu est le suivant :

Démarrage de repmgrd

Pour démarrer repmgrd, exécuter la commande suivante sur chacun des serveurs, en tant que postgres :

/usr/lib/postgresql/10/bin/repmgrd -f /etc/repmgr.conf

Vérification du fonctionnement du failover

En considérant l’architecture à 2 serveurs ci-dessus , effectuer les opérations suivantes :

  • Statut du départ :
  • Après le démarrage de repmgrd sur les 2 serveurs, vérifier sur leurs logs respectifs qu’ils sont bien actifs
  • Arrêter le serveur primaire :

/usr/lib/postgresql/10/bin/pg_ctl stop -D /var/lib/postgresql/10/main

  • Vérifier de nouveau le statut du cluster :

On remarque que le noeud 2 est devenu primaire.

  • Une fois, val  “réparé”, le retour à la situation initiale s’effectue en 2 temps : d’abord mettre val comme standby du primaire customers puis faire un switchover sur val pour qu’il redevienne primaire et customers redevient standby :
  • Cloner val à partir de customers et l’enregistrer comme standby :

postgres@val$ /usr/lib/postgresql/10/bin/repmgr -h 195.154.39.117 -p 5433 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone –force

  • Redémarrer val :

postgres@val$ pg_ctlcluster 10 main start

  • enregistrer val en standby :

postgres@val$ /usr/lib/postgresql/10/bin/repmgr standby register –force

  • Vérifier l’état du cluster :

On constate que le cluster fonctionne avec customers comme primaire et val comme standby.

Pour inverser les rôles, on fait un switchover sur le standby :

  • Vérifier l’état du cluster

Remarque : le switchover agit sur le standby et sur les autres serveurs pour qu’ils soient avertis du nouveau primaire.

Conclusion

Ce post a permis d’exposer pas à pas les étapes pour configurer une HA sur un cluster à 2 noeuds, en mode primaire/standby. Pour ce faire, on a mis en oeuvre une streaming réplication avec repmgr et un monitoring des 2 noeuds avec le daemon associé à repmgr, ce qui permet de déclencher le failover automatique en cas de défaillance du noeud primaire. Le retour à la configuration initiale, après réparation de la défaillance, est réalisé avec un switchover. Le protocole de streamaing réplication permet de minimiser le RPO car il permet de rejouer les transactions au fil de l’eau au niveau du standby. Pour minimiser le RTO, il faut ajuster la fréquence des backup de base en fonction de la volumétrie des transactions.

La configuration qui a été présentée ici, peut être renforcée par un système de load balancing par un outil tiers dans le cas général , style pgpool-II ( http://www.pgpool.net ) ou par le driver jdbc si on est dans l’écosystème java.