Industrialisation avec pglift et Ansible

Atelier Industrialisation PostgreSQL

Dalibo & Contributors

Présentation

Introduction

Présentation de pglift

  • Permet de déployer et de gérer des instances PostgreSQL uniformisées
  • Instances prêtes pour la production dès leur déploiement
  • Capable de déployer des instances en réplication avec patroni
  • Prends en charge pgBackRest en mode local ou distant

CLI

  • L’ensemble de ces fonctionnalités sont exposées dans une interface en ligne de commande

Ansible (Collection dalibo.pglift)

  • Fonctionnalités de pglift accessibles depuis la collection dalibo.pglift
  • Permet d’intégrer pglift dans un processus de déploiement automatisé ansible

Ansible (Collections dalibo.essential, dalibo.advanced, dalibo.extras)

  • Permet une installation et un déploiement automatisé de l’ensemble des éléments nécessaires à pglift
  • Chaque collection est spécifique à un thème :
    • dalibo.essential : PostgreSQL, réplication, monitoring, sauvergarde
    • dalibo.advanced : HA, performances, audit, ldap, pooler
    • dalibo.extras : Tous les outils annexes (ETCD,rsyslog, logrotate, etc)

Installation et création d’instance avec pglift (CLI).

Pré-requis

  • Dépôts Powertools, EPEL, PGDG et Dalibo Labs
  • Utilisateur système postgres
  • Activer le lingering

Installation de PostgreSQL

Installer PostgreSQL 16 :

[root@srv-pg1 ~]# dnf install -y postgresql16 postgresql16-server \
postgresql16-contrib

Installation de pgBackrest

Installer pgBackRest :

[root@srv-pg1 ~]# dnf install -y pgbackrest

Installation de pglift

pipx

Installer pglift avec pipx, en tant que postgres :

[root@srv-pg1 ~]# su - postgres << EOF
  pip3.9 install pipx
  ~/.local/bin/pipx install "pglift[cli]" --include-deps
  ~/.local/bin/pipx ensurepath
EOF

Ouvrir une nouvelle session est nécessaire pour que le binaire pglift soit dans le ${PATH} de l’utilisateur postgres

Configuration initiale

  • Fichier de configuration pglift :
    • ~/.config/pglift/settings.yaml
    • /etc/pglift/settings.yaml
  • Template de configuration PostgreSQL et pgBackRest
  • Installer la configuration de site : pglift site-configure install

Déploiement d’une instance (CLI)

$ pglift instance create main \ 
--pgbackrest-stanza=main

Installation et création d’instance avec pglift (Ansible).

Inventaire

Inventaire Ansible : ~/ansible/inventory

srv-pg1      ansible_port=2201
srv-pg2      ansible_port=2202
srv-pg3      ansible_port=2203

[all:vars]
ansible_connection=ssh
ansible_host=127.0.0.1
ansible_user=dalibo
ansible_ssh_pass=Password

[etcd]
srv-pg1
srv-pg2
srv-pg3

[database]
srv-pg1
srv-pg2

[primary]
srv-pg1

[standby]
srv-pg2

[temboard]
srv-pg3

Collection

collections:
  - dalibo.pglift
  - community.general
  - dalibo.essential
  - dalibo.advanced
  - dalibo.extras
$ ansible-galaxy collection install -fr collections/requirements.yml

Génération des certificats TLS

$ ansible-playbook -i inventory prerequisites.yml

Installation de temBoard UI

  • Roles :
    • dalibo.essential.temboard : Pour l’installation
    • temboard : Pour la configuration
  • Playbook : temboard.yml
$ ansible-playbook -i inventory temboard.yml

Installation du cluster ETCD

  • Roles :
    • dalibo.extras.etcd : Pour l’installation et la configuration
  • Playbook : etcd.yml
$ ansible-playbook -i inventory etcd.yml

Installation de l’environnement

- name: Install Database Server
  hosts: database
  become: true
  roles:
    - dalibo.extras.repo_epel
    - dalibo.essential.repo_pgdg
    - dalibo.essential.repo_dalibo
    - dalibo.extras.accounts
    - dalibo.essential.postgresql
    - dalibo.essential.pgbackrest
    - dalibo.advanced.patroni
    - dalibo.essential.temboard_agent
    - dalibo.essential.pglift
$ ansible-playbook -i inventory postgresql.yml

Déploiement d’une instance avec Ansible

  • Module dalibo.pglift.instance

Création de l’instance

---

- name: Deploy a standalone Instance
  hosts: primary
  become: true
  become_user: postgres
  tasks:
    - name: Create Instance
      dalibo.pglift.instance:
        name: main
        state: started
        version: 16
        port: 5432
        surole_password: Passw0rd
        pgbackrest:
          password: Passw0rd
          stanza: main-stz
        temboard:
          password: Passw0rd
        replrole_password: Passw0rd
        databases:
          - name: ws1
$ ansible-playbook -i inventory instance_standalone.yml

Création d’un secondaire en streaming réplication

---

- name: Get instances gather facts
  hosts: primary
  gather_facts: true

- name: Deploy standby Instance
  hosts: standby
  become: true
  become_user: postgres
  tasks:
    - name: Creating standby Instance
      dalibo.pglift.instance:
        name: standby
        state: started
        version: 16
        port: 5432
        surole_password: Passw0rd
        pgbackrest:
          password: Passw0rd
          stanza: main-stz
        standby:
          primary_conninfo: "host={{ hostvars[item]['ansible_eth1'].ipv4.address }} user=replication port=5432"
          password: Passw0rd
        temboard:
          password: Passw0rd
      loop: "{{ groups['primary'] }}"
$ ansible-playbook -i inventory standby_instance.yml

Sauvegarde et Restauration pgbackrest avec pglift

Rappel Point In Time Recovery (PITR)

  • Point In Time Recovery
  • À chaud
  • En continu
  • Cohérente

Sauvegarde

$ pglift instance backup main
INFO     backing up instance 16/main with pgBackRest

Restauration

$ pglift database -i main drop ws1
INFO     dropping 'ws1' database
$ pglift instance stop main
INFO     stopping PostgreSQL 16-main
$ pglift instance restore main --label '20240118-084757F_20240118-085536I'
INFO     restoring instance 16/main with pgBackRest

Manipulation d’instances avec pglift

Lister les instances

$ pglift instance list

Obtenir la descriptions des instances

$ pglift instance get main

Obtenir le statut d’une instance

$ pglift instance status main

Gestion de l’état

$ pglift instance start main
$ pglift instance stop main
$ pglift instance restart main
$ pglift instance reload main

Consulter les traces

$ pglift instance logs main

Gestion de la configuration de PostgreSQL

  • pglift peut manipuler la configuration des instances PostgreSQL avec la commande pglift pgconf
  • Opérations possibles : edit, remove, set, show

Modifier la configuration

$ pglift pgconf -i main edit
$ pglift pgconf -i main set

Afficher la configuration

$ pglift pgconf -i main show

Supprimer une configuration

$ pglift pgconf -i main remove

Gestion du pg_hba.conf

  • pglift peut manipuler le pg_hba.conf avec la commande pglift pghba
  • Opérations possibles : add, remove

Maintenance des données

$ pglift database -i main run "ANALYZE"
$ pglift database -i main run -d postgres "VACUUM FULL"
$ pglift database -i main run -x postgres "VACUUM"

Opérations sur les roles

$ pglift role
tasks:
  - name: my role
    dalibo.pglift.role:
      instance: main
      name: dba
      pgpass: true
      login: true
      connection_limit: 10
      valid_until: '2025-01-01T00:00'
      memberships:
        - role: pg_read_all_stats

Opérations sur les bases de données

$ pglift database
tasks:
- name: my database
  dalibo.pglift.database:
    instance: main
    name: myapp
    owner: dba

Réplication

$ pglift instance create <INSTANCE> --stanby-for
tasks:
  - name: Creating standby Instance
    dalibo.pglift.instance:
      name: standby
      [...]
      standby:
        primary_conninfo: "host=X.X.X.X user=replication port=5432"
        password: Passw0rd

Déployer des instances en Haute Disponibilité avec pglift

Configuration de pglift

  • Fichier de configuration pglift :
    • ~/.config/pglift/settings.yaml
  • Template de configuration PostgreSQL (pg_hba.conf)
  • Installer la configuration de site

Déploiement d’instances en Haute Disponibilité avec pglift

  • Via le terminal avec pglift
  • Via un playbook Ansible et la collection dalibo.pglift

CLI

$ pglift instance create main --pgbackrest-stanza=main-app \
         --replrole-password PasswOrd \
         --patroni-cluster maincluster \
         --patroni-node <node_name> \
         --patroni-restapi-connect-address "<IP-Machine>:8008" \
         --patroni-restapi-listen "<IP-Machine>:8008" \
         --patroni-postgresql-connect-host <IP-Machine>

Ansible

  • Module dalibo.pglift.instance

Création des noeuds du cluster

---
- name: Create Instances
  hosts: database
  become_user: postgres
  become: true
  tasks:

    - name: Managing instances
      dalibo.pglift.instance:
        name: main
        state: started
        version: 16
        port: 5432
        surole_password: Passw0rd
        replrole_password: Passw0rd
        temboard:
          password: Passw0rd
        pgbackrest:
          password: Passw0rd
          stanza: maincluster-stz
        patroni:
          cluster: maincluster
          node: "{{ ansible_hostname }}"
          restapi:
            connect_address: "{{ ansible_eth1.ipv4.address }}:8008"
            listen: "{{ ansible_eth1.ipv4.address }}:8008"
          postgresql:
            connect_host: "{{ ansible_default_ipv4.address }}"
      throttle: 1
$ ansible-playbook -i inventory instance_ha.yml

Gestion de la configuration du cluster

Avec Patroni

$ pglift instance exec main -- patronictl edit-config maincluster

Avec pglift

$ pglift pgconf -i main edit

Statut du cluster

$ pglift instance exec main -- patronictl list
+ Cluster: maincluster (7334815726709754190) ----------+----+-----------+
| Member  | Host            | Role         | State     | TL | Lag in MB |
+---------+-----------------+--------------+-----------+----+-----------+
| srv-pg1 | 192.168.121.172 | Leader       | running   |  1 |           |
| srv-pg2 | 192.168.121.89  | Sync Standby | streaming |  1 |         0 |
+---------+-----------------+--------------+-----------+----+-----------+

Switchover

$ pglift instance exec main -- patronictl switchover 

Failover

  • Simuler une panne en arrêtant le processus patroni :
$ pkill -9 patroni 
  • srv-pg2 redémarre suite au déclanchement du watchdog par patroni

Gestion de parc d’instances avec temBoard.

Présentation de temBoard

  • temBoard : supervision et administration de PostgreSQL
  • Un composant serveur, paquet temboard
  • Un agent pour les serveurs PostgreSQL, paquet temboard-agent

Enregistrement de l’instance

---

- name: Get instances gather facts
  hosts: database
  gather_facts: true

- name: Register instances in temBoard
  hosts: temboard
  gather_facts: true
  become: true
  become_user: temboard
  tasks:
    - name: Register instances in temBoard
      ansible.builtin.shell: "temboard register-instance {{ hostvars[item]['ansible_default_ipv4']['address'] }} 2345 -e default"
      loop: "{{ groups['primary'] }}"

    - name: Register instances in temBoard
      ansible.builtin.shell: "temboard register-instance {{ hostvars[item]['ansible_default_ipv4']['address'] }} 2345 -e default"
      loop: "{{ groups['standby'] }}"
$ ansible-playbook -i inventory temboard_register.yml

Visualisation des métriques

  • Vue Dashboard : Résumé des métriques
  • Vue Activity : Activité de l’instance en temps réel
  • Vue Monitoring : Afficher des métriques sous forme de graphes
  • Vue Status : Statut des sondes de supervision
  • Vue Maintenance :
    • Informations sur l’utilisation des disques
    • Possibilité de déclencher des opérations de maintenance (VACUUM [FULL], ANALYZE, REINDEX)
  • Vue Configuration : Modifier le paramétrage de l’instance