{"id":10562,"date":"2024-05-29T09:58:17","date_gmt":"2024-05-29T08:58:17","guid":{"rendered":"https:\/\/blog.capdata.fr\/?p=10562"},"modified":"2024-05-29T09:59:28","modified_gmt":"2024-05-29T08:59:28","slug":"pgo-la-suite","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/","title":{"rendered":"PGO : la suite"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10562&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10562&#038;title=PGO%20%3A%20la%20suite\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PGO%20%3A%20la%20suite&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10562\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>La gestion efficace des clusters PostgreSQL dans un environnement Kubernetes est un d\u00e9fi complexe auquel sont confront\u00e9es de nombreuses entreprises aujourd&#8217;hui. PGO offre une solution d\u00e9clarative qui automatise la gestion des clusters PostgreSQL, simplifiant ainsi le d\u00e9ploiement, la mise \u00e0 l&#8217;\u00e9chelle et la gestion des bases de donn\u00e9es PostgreSQL dans un environnement Kubernetes.<\/p>\n<p>Pour faire suite \u00e0 l&#8217;article de David sur PGO et \u00e0 la demande d&#8217;un de nos clients, j&#8217;ai r\u00e9alis\u00e9 une \u00e9tude approfondie de plusieurs fonctionnalit\u00e9s de PGO.<br \/>\nCet article va faire un petit tour d&#8217;horizon des outils principaux inclus dans l&#8217;impl\u00e9mentation de PGO. Que ce soit pour la sauvegarde avec pgbackrest, pour la balance des connexion avec pgbouncer ou pour le monitoring avec prometheus, PGO ne manque pas d&#8217;utilitaire dont l&#8217;utilisation est facilit\u00e9e par la solution tout embarqu\u00e9.<\/p>\n<h3>Pgbackrest :<\/h3>\n<h4>Utilit\u00e9 :<\/h4>\n<p>PgBackRest est une solution de sauvegarde et de restauration pour les bases de donn\u00e9es PostgreSQL qui propose plusieurs fonctionnalit\u00e9s, telles que la sauvegarde et la restauration parall\u00e8les, la compression, les sauvegardes compl\u00e8tes, diff\u00e9rentielles et incr\u00e9mentielles, la rotation des sauvegardes et l&#8217;expiration des archives, l&#8217;int\u00e9grit\u00e9 des sauvegardes, etc. Il prend en charge plusieurs r\u00e9f\u00e9rentiels, qui peuvent \u00eatre situ\u00e9s localement ou \u00e0 distance via TLS\/SSH, ou \u00eatre des stockages fournis par le cloud comme S3\/GCS\/Azure.<br \/>\nL&#8217;architecture de pgbackrest pour PGO est la suivante :<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-10564\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image1-300x168.png\" alt=\"\" width=\"300\" height=\"168\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image1-300x168.png 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image1.png 605w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h4>Mise en place :<\/h4>\n<p>On peut imaginer plusieurs moyens de mettre en place le pgbackrest. Dans un premier temps, nous avons la sauvegarde classique en syst\u00e8me de fichier, comme dans notre exemple sur le blog :<\/p>\n<h5>1) La sauvegarde sur volume persistant Kubernetes :<\/h5>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\n- name: repo1\r\n  volume:\r\n    volumeClaimSpec:\r\n      accessModes:\r\n      - &quot;ReadWriteOnce&quot;\r\n      resources:\r\n        requests:\r\n          storage: 1Gi\r\n<\/pre>\n<p>Ce type de sauvegarde utilise un volume persistant de Kubernetes pour recueillir nos sauvegardes et les garder.<br \/>\nUne PersistentVolumeClaim (PVC) est une demande de stockage faite par un utilisateur. Elle est similaire \u00e0 un Pod. Les Pods consomment des ressources de n\u0153ud et les PVC consomment des ressources de PV (PersistentVolume). Les Pods peuvent demander des niveaux sp\u00e9cifiques de ressources (CPU et m\u00e9moire). Les revendications peuvent demander une taille sp\u00e9cifique et des modes d&#8217;acc\u00e8s sp\u00e9cifiques (par exemple, elles peuvent \u00eatre mont\u00e9es en ReadWriteOnce, ReadOnlyMany, ReadWriteMany, ou ReadWriteOncePod, voir AccessModes).<\/p>\n<h5>2) Le stockage pour S3 :<\/h5>\n<p>Pour pouvoir faire du stockage dans S3, il faut rajouter un fichier de configuration dans notre dossier de d\u00e9ploiement. Le fichier doit s\u2019appeler s3.conf. Ce fichier contient les cr\u00e9dential de connexion \u00e0 un AWS S3 :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nrepo1-s3-key=$YOUR_AWS_S3_KEY\r\nrepo1-s3-key-secret=$YOUR_AWS_S3_KEY_SECRET\r\n<\/pre>\n<p>Une fois que c\u2019est configur\u00e9 dans votre fichier, il ne reste plus qu\u2019\u00e0 modifier le postgresql.yaml, et configurer dans la partie backup :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nbackups:\r\n    pgbackrest:\r\n      image: registry.developers.crunchydata.com\/crunchydata\/crunchy-pgbackrest:ubi8-2.49-0\r\n      configuration:\r\n      - secret:\r\n          name: pgo-s3-creds\r\n      global:\r\n        repo1-path: \/pgbackrest\/postgres-operator\/pgcluster1\/repo1\r\n      repos:\r\n      - name: repo1\r\n        s3:\r\n          bucket: &quot;&lt;YOUR_AWS_S3_BUCKET_NAME&gt;&quot;\r\n          endpoint: &quot;&lt;YOUR_AWS_S3_ENDPOINT&gt;&quot;\r\n          region: &quot;&lt;YOUR_AWS_S3_REGION&gt;&quot;\r\n<\/pre>\n<p>Une fois configur\u00e9, et le job mis dans le cron, vous devriez voir apparaitre les sauvegardes sur le volume S3.<\/p>\n<h5>3) Le stockage GCS :<\/h5>\n<p>Comme pour Amazon S3 on peut sauvegarder nos backups dans Google Cloud Storage. Pour pouvoir le faire fonctionner il vous faut copier votre GCS key secret (qui est un fichier JSON) dans un gcs.conf que vous allez placer dans votre dossier Kustomize.<br \/>\nIl vous suffit ensuite de modifier votre fichier postgres.yaml pour ajouter dans la partie backup la configuration pour une sauvegarde gcs :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nbackups:\r\n    pgbackrest:\r\n      image: registry.developers.crunchydata.com\/crunchydata\/crunchy-pgbackrest:ubi8-2.49-0\r\n      configuration:\r\n      - secret:\r\n          name: pgo-gcs-creds\r\n      global:\r\n        repo1-path: \/pgbackrest\/postgres-operator\/pgcluster1\/repo1\r\n      repos:\r\n      - name: repo1\r\n        gcs:\r\n          bucket: &quot;&lt;YOUR_GCS_BUCKET_NAME&gt;&quot;\r\n<\/pre>\n<p>Il ne vous reste plus qu\u2019\u00e0 reg\u00e9n\u00e9rer vos pods, et votre sauvegarde arrivera directement dans votre Google Cloud Service.<\/p>\n<h5>4) Le stockage Azur Blob Storage :<\/h5>\n<p>Comme pour les deux points pr\u00e9c\u00e9dents, vous pouvez \u00e9galement stocker vos sauvegardes sur le blob storage d\u2019Azure. Pour cela il vous faut cr\u00e9er un fichier dans votre kustomize, avec \u00e0 l\u2019int\u00e9rieur la configuration pour votre point de sauvegarde Azure. Il vous faut l\u2019appeler azure.conf et il devra contenir les lignes suivantes :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nrepo1-azure-account=$YOUR_AZURE_ACCOUNT\r\nrepo1-azure-key=$YOUR_AZURE_KEY\r\n<\/pre>\n<p>Il faut ensuite int\u00e9grer ces modifications dans votre fichier postgres.yaml :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nbackups:\r\n    pgbackrest:\r\n      image: registry.developers.crunchydata.com\/crunchydata\/crunchy-pgbackrest:ubi8-2.49-0\r\n      configuration:\r\n      - secret:\r\n          name: pgo-azure-creds\r\n      global:\r\n        repo1-path: \/pgbackrest\/postgres-operator\/pgcluster\/repo1\r\n      repos:\r\n      - name: repo1\r\n        azure:\r\n          container: &quot;&lt;YOUR_AZURE_CONTAINER&gt;&quot;\r\n<\/pre>\n<p>Bien sur rien ne vous interdit, et c\u2019est m\u00eame conseill\u00e9, de joindre plusieurs moyens de sauvegarde. Cela permet notamment de s\u2019assurer une plus grande fiabilit\u00e9 du syst\u00e8me de sauvegarde, en s\u2019assurant qu\u2019elles sont disponibles \u00e0 plusieurs endroits.<br \/>\nUne fois que vous avez d\u00e9cid\u00e9 d\u2019o\u00f9 vous allez stocker vos sauvegardes, et que vous l\u2019avez configur\u00e9, il faut maintenant d\u00e9cider des diff\u00e9rents param\u00e8tres de ces sauvegardes : la programmation, la r\u00e9tention\u2026<\/p>\n<h5>5) La programmation des sauvegardes :<\/h5>\n<p>Il faut savoir que par d\u00e9faut, PGO sauvegarde automatiquement les WAL dans la m\u00e9thode de sauvegarde que vous lui avez configur\u00e9. C\u2019est donc une forme de sauvegarde en soit.<br \/>\nMais dans le cadre d\u2019une r\u00e9cup\u00e9ration apr\u00e8s incident majeur, il peut aussi \u00eatre utilise d\u2019avoir des sauvegardes full programm\u00e9es. Pgbackrest, qui est l\u2019outil utilis\u00e9 par PGO permet de mettre en place trois types de sauvegarde : les incr\u00e9mentales, les diff\u00e9rentielles et les fulls.<br \/>\nChaque type de sauvegarde peut \u00eatre programm\u00e9e en suivant une notation identique \u00e0 celle des crontab. Par exemple :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nbackups:\r\n    pgbackrest:\r\n      repos:\r\n      - name: repo1\r\n        schedules:\r\n          full: &quot;0 1 * * 0&quot;\r\n          differential: &quot;0 1 * * 1-6&quot;\r\n<\/pre>\n<p>Le fait d\u2019impl\u00e9menter ces planifications cr\u00e9era des CronJobs dans Kubernetes.<\/p>\n<h5>6) La r\u00e9tention des backups :<\/h5>\n<p>Vous pouvez d\u00e9finir une r\u00e9tention maximum pour vos backups sur le support de backup de votre choix. Une fois que cette r\u00e9tention sera atteinte, pgbackrest fera le m\u00e9nage tout seul des sauvegardes et des WAL qui lui sont reli\u00e9es.<br \/>\nIl y a deux types de r\u00e9tentions que l\u2019on peut d\u00e9finir : les r\u00e9tentions \u00ab count \u00bb bas\u00e9es sur le nombre de backup que l\u2019on souhaite garder et les r\u00e9tentions \u00ab time \u00bb bas\u00e9es sur le nombre de jours ou vous souhaitez garder votre sauvegarde.<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nbackups:\r\n    pgbackrest:\r\n      global:\r\n        repo1-retention-full: &quot;14&quot;\r\n        repo1-retention-full-type: time\r\n<\/pre>\n<h5>7) La sauvegarde unique :<\/h5>\n<p>Si dans le cadre d\u2019un besoin particuliers, une grosse modification ou une migration par exemple, vous avez besoin de prendre une sauvegarde imm\u00e9diate sans forc\u00e9ment attendre que le cron n\u2019arrive, vous pouvez le faire.<br \/>\nPour la configuration de cette sauvegarde, il faudra l\u2019annoter comme \u00ab manuelle \u00bb :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\n  backups:\r\n    pgbackrest:\r\n      manual:\r\n        repoName: repo1\r\n        options:\r\n         - --type=full\r\n<\/pre>\n<p>Il vous faudra ensuite d\u00e9clencher cette sauvegarde avec une commande manuelle. Dans le cadre de notre cluster exemple pgcluster1 :<br \/>\nkubectl annotate -n postgres-operator postgrescluster pgcluster1 \\ postgres-operator.crunchydata.com\/pgbackrest-backup=&#8221;$(date)&#8221;<\/p>\n<h5>8) Faire un clone \u00e0 partir d\u2019un repo :<\/h5>\n<p>Quand on a configur\u00e9 un repo sur notre instance primaire, on peut facilement cr\u00e9er un clone de notre instance \u00e0 l\u2019aide de notre sauvegarde. Ainsi, on cr\u00e9er un tout nouveau Pods \u00e0 partir des informations stock\u00e9es \u00e0 propos du pod que l\u2019on poss\u00e8de d\u00e9j\u00e0. Ici, nous allons cr\u00e9er un nouveau pod \u00e0 partir de notre pod pgcluster1 :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\napiVersion: postgres-operator.crunchydata.com\/v1beta1\r\nkind: PostgresCluster\r\nmetadata:\r\n  name: pgcluster2\r\nspec:\r\n  dataSource:\r\n    postgresCluster:\r\n      clusterName: pgcluster1\r\n      repoName: repo1\r\n  image: registry.developers.crunchydata.com\/crunchydata\/crunchy-postgres:ubi8-16.2-0\r\n  postgresVersion: 16\r\n  instances:\r\n    - dataVolumeClaimSpec:\r\n        accessModes:\r\n        - &quot;ReadWriteOnce&quot;\r\n        resources:\r\n          requests:\r\n            storage: 1Gi\r\n  backups:\r\n    pgbackrest:\r\n      image: registry.developers.crunchydata.com\/crunchydata\/crunchy-pgbackrest:ubi8-2.49-0\r\n      repos:\r\n      - name: repo1\r\n        volume:\r\n          volumeClaimSpec:\r\n            accessModes:\r\n            - &quot;ReadWriteOnce&quot;\r\n            resources:\r\n              requests:\r\n                storage: 1Gi\r\n<\/pre>\n<p>Ici on peut noter entre autres la partie spec de la configuration, qui est le morceau de yaml nous permettant de dire qu\u2019on s\u2019appuie sur le cluster existant pour cr\u00e9er un clone ind\u00e9pendant :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nspec:\r\n  dataSource:\r\n    postgresCluster:\r\n      clusterName: pgcluster1\r\n      repoName: repo1\r\n<\/pre>\n<h5>9) Point in Time Recovery :<\/h5>\n<p>De la m\u00eame fa\u00e7on, si l\u2019on veut faire une restauration PITR, nous allons remplir la balise spec de notre yaml. Attention cependant, pour faire une restauration PITR, nous avons besoin de poss\u00e9der encore la sauvegarde. On ne peut pas faire une restauration PITR sur une sauvegarde lointaine qu\u2019on ne poss\u00e8derait plus. Imaginons que je souhaite repartir d\u2019une sauvegarde datant d\u2019hier soir \u00e0 20h30 de mon instance pgcluster1 sur mon instance pgcluster2, la configuration serait la suivante :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\napiVersion: postgres-operator.crunchydata.com\/v1beta1\r\nkind: PostgresCluster\r\nmetadata:\r\n  name: pgcluster2\r\nspec:\r\n  dataSource:\r\n    postgresCluster:\r\n      clusterName: pgcluster1\r\n      repoName: repo1\r\n      options:\r\n      - --type=time\r\n      - --target=&quot;2024-04-09 20:30:00-00&quot;\r\n  image: registry.developers.crunchydata.com\/crunchydata\/crunchy-postgres:ubi8-16.2-0\r\n  postgresVersion: 16\r\n  instances:\r\n    - dataVolumeClaimSpec:\r\n        accessModes:\r\n        - &quot;ReadWriteOnce&quot;\r\n        resources:\r\n          requests:\r\n            storage: 1Gi\r\n  backups:\r\n    pgbackrest:\r\n      image: registry.developers.crunchydata.com\/crunchydata\/crunchy-pgbackrest:ubi8-2.49-0\r\n      repos:\r\n      - name: repo1\r\n        volume:\r\n          volumeClaimSpec:\r\n            accessModes:\r\n            - &quot;ReadWriteOnce&quot;\r\n            resources:\r\n              requests:\r\n                storage: 1Gi\r\n<\/pre>\n<p>La partie qui nous int\u00e9resse ici est la partie spec, ou nous avons rajouter un type de restauration (ici time) et une heure target. Cela indique \u00e0 pgbackrest qu\u2019il doit aller chercher tous les fichiers de sauvegarde et WAL sur notre point de sauvegarde repo1 venant de l\u2019instance pgcluster1 pour les r\u00e9appliquer sur notre nouveau cluster pgcluster2.<br \/>\nVous pouvez \u00e9galement vouloir r\u00e9aliser une restauration In Place, c\u2019est-\u00e0-dire \u00e9craser l\u2019instance pr\u00e9sente pour la remplacer par la restauration. Auquel cas, plut\u00f4t que de pr\u00e9ciser comment s\u2019appellera notre nouveau cluster, il faut alors passer par la balise restore :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nspec:\r\n  backups:\r\n    pgbackrest:\r\n      restore:\r\n        enabled: true\r\n        repoName: repo1\r\n        options:\r\n        - --type=time\r\n        - --target=&quot;2024-04-09 20:30:00-00&quot;\r\n<\/pre>\n<p>Ici, comme pr\u00e9c\u00e9demment, nous restaurons \u00e0 l\u2019heure de 20 :30 hier soir, et cela sur notre propre instance. Ne reste plus qu\u2019\u00e0 lancer la restauration :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">kubectl annotate -n postgres-operator postgrescluster pgcluster1 --overwrite \\ postgres-operator.crunchydata.com\/pgbackrest-restore=&quot;$(date)&quot;<\/pre>\n<p>A noter qu\u2019il ne faut pas oublier de d\u00e9sactiver ensuite le restore en le passant \u00e0 false si vous ne souhaitez pas qu\u2019il soit de nouveau \u00e9cras\u00e9 au prochain changement de configuration.<\/p>\n<h5>10) Restaurer une base de donn\u00e9es sp\u00e9cifique :<\/h5>\n<p>Si votre besoin est de restaurer une base de donn\u00e9es sp\u00e9cifique plut\u00f4t que l\u2019int\u00e9gralit\u00e9 de l\u2019instance, vous pouvez le pr\u00e9ciser dans les param\u00e8tres de votre restauration.<br \/>\nAttention cependant, ce n\u2019est pas une restauration comme le serais un pg_dump. Ici si vous restaurez simplement une seule base de donn\u00e9es et pas le reste du cluster, les autres bases que vous n\u2019avez pas choisit de restaurer deviendront inaccessibles.<br \/>\nSi nous voulons restaurer une base de donn\u00e9es, et uniquement elle, voici la proc\u00e9dure :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nspec:\r\nbackups:\r\n  pgbackrest:\r\n    restore:\r\n      enabled: true\r\n      repoName: repo1\r\n      options:\r\n        - --db-include=capdata\r\n<\/pre>\n<p>Ici, on ne restaurera que la base de donn\u00e9es capdata, et aucunes autres bases \u00e0 partir de notre repo1.<\/p>\n<h3>PgBouncer :<\/h3>\n<h4>Utilit\u00e9 :<\/h4>\n<p>PgBouncer est un pooler de connexion pour PostgreSQL. Un pooler de connexion permet de maintenir ouvertes des sessions entre lui-m\u00eame et le serveur, ce qui rend plus rapide l&#8217;ouverture de sessions depuis les clients, une application Web par exemple.<br \/>\nPgBouncer permet aussi de mutualiser les sessions dans le serveur, \u00e9conomisant ainsi des ressources. PgBouncer propose plusieurs modes de partage : par requ\u00eate (default), par transaction ou par session.<\/p>\n<h4>Mise en place :<\/h4>\n<p>Pour ajouter un bouncer \u00e0 notre configuration c\u2019est une r\u00e9alit\u00e9 tr\u00e8s simple. Il suffit d\u2019ajouter dans notre fichier postgres.yaml la rubrique proxy :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nproxy:\r\n  pgBouncer:\r\n    image: registry.developers.crunchydata.com\/crunchydata\/crunchy-pgbouncer:ubi8-1.21-3\r\n<\/pre>\n<p>Une fois que vous avez rajout\u00e9 cela dans la configuration, il n\u2019y a plus qu\u2019\u00e0 appliquer celle-ci :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\"> kubectl apply -k kustomize\/keycloak <\/pre>\n<p>Quand PGO cr\u00e9\u00e9 un nouveau connexion pooler sur notre instance d\u00e9ploy\u00e9e, il modifier le fichier secrets de l\u2019utilisateur.<br \/>\nOn voit que plusieurs champs qui concerne pg_bouncer sont apparus. Ils constituent les informations qui vont vous permettre de vous connecter sur votre bouncer nouvellement cr\u00e9\u00e9 :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\n{\r\n    &quot;apiVersion&quot;: &quot;v1&quot;,\r\n    &quot;data&quot;: {\r\n        &quot;dbname&quot;: &quot;cGdjbHVzdGVyMQ==&quot;,\r\n        &quot;host&quot;: &quot;cGdjbHVzdGVyMS1wcmltYXJ5LnBvc3RncmVzLW9wZXJhdG9yLnN2Yw==&quot;,\r\n        &quot;jdbc-uri&quot;: &quot;amRiYzpwb3N0Z3Jlc3FsOi8vcGdjbHVzdGVyMS1wcmltYXJ5LnBvc3RncmVzLW9wZXJhdG9yLnN2Yzo1NDMyL3BnY2x1c3RlcjE\/cGFzc3dvcmQ9NXNSaSUzRCU1QmZZbSUzQ2lSSGslMkElNUIlM0VuWGhqaiU3Q1EmdXNlcj1wZ2NsdXN0ZXIx&quot;,\r\n        &quot;password&quot;: &quot;NXNSaT1bZlltPGlSSGsqWz5uWGhqanxR&quot;,\r\n        &quot;pgbouncer-host&quot;: &quot;cGdjbHVzdGVyMS1wZ2JvdW5jZXIucG9zdGdyZXMtb3BlcmF0b3Iuc3Zj&quot;,\r\n        &quot;pgbouncer-jdbc-uri&quot;: &quot;amRiYzpwb3N0Z3Jlc3FsOi8vcGdjbHVzdGVyMS1wZ2JvdW5jZXIucG9zdGdyZXMtb3BlcmF0b3Iuc3ZjOjU0MzIvcGdjbHVzdGVyMT9wYXNzd29yZD01c1JpJTNEJTVCZlltJTNDaVJIayUyQSU1QiUzRW5YaGpqJTdDUSZwcmVwYXJlVGhyZXNob2xkPTAmdXNlcj1wZ2NsdXN0ZXIx&quot;,\r\n        &quot;pgbouncer-port&quot;: &quot;NTQzMg==&quot;,\r\n        &quot;pgbouncer-uri&quot;: &quot;cG9zdGdyZXNxbDovL3BnY2x1c3RlcjE6NXNSaT0lNUJmWW0lM0NpUkhrJTJBJTVCJTNFblhoamolN0NRQHBnY2x1c3RlcjEtcGdib3VuY2VyLnBvc3RncmVzLW9wZXJhdG9yLnN2Yzo1NDMyL3BnY2x1c3RlcjE=&quot;,\r\n        &quot;port&quot;: &quot;NTQzMg==&quot;,\r\n        &quot;uri&quot;: &quot;cG9zdGdyZXNxbDovL3BnY2x1c3RlcjE6NXNSaT0lNUJmWW0lM0NpUkhrJTJBJTVCJTNFblhoamolN0NRQHBnY2x1c3RlcjEtcHJpbWFyeS5wb3N0Z3Jlcy1vcGVyYXRvci5zdmM6NTQzMi9wZ2NsdXN0ZXIx&quot;,\r\n        &quot;user&quot;: &quot;cGdjbHVzdGVyMQ==&quot;,\r\n        &quot;verifier&quot;: &quot;U0NSQU0tU0hBLTI1NiQ0MDk2OlgyQ3NQRU1FZjh3QkVlc05McDFJTkE9PSRKcDhKakl5Q0o1ZEpFRVhia1ptUERTNE5rR3d0V00rczdrMElsQmx0YkpvPTpEaHg3VzNCOE5vNDRYSHJ1Qm1RdENMQW9jNEtnSUZQa2dIeStUMkVWUUowPQ==&quot;\r\n    },\r\n    &quot;kind&quot;: &quot;Secret&quot;,\r\n    &quot;metadata&quot;: {\r\n        &quot;creationTimestamp&quot;: &quot;2024-04-09T16:37:36Z&quot;,\r\n        &quot;labels&quot;: {\r\n            &quot;postgres-operator.crunchydata.com\/cluster&quot;: &quot;pgcluster1&quot;,\r\n            &quot;postgres-operator.crunchydata.com\/pguser&quot;: &quot;pgcluster1&quot;,\r\n            &quot;postgres-operator.crunchydata.com\/role&quot;: &quot;pguser&quot;\r\n        },\r\n        &quot;name&quot;: &quot;pgcluster1-pguser-pgcluster1&quot;,\r\n        &quot;namespace&quot;: &quot;postgres-operator&quot;,\r\n        &quot;ownerReferences&quot;: [\r\n            {\r\n                &quot;apiVersion&quot;: &quot;postgres-operator.crunchydata.com\/v1beta1&quot;,\r\n                &quot;blockOwnerDeletion&quot;: true,\r\n                &quot;controller&quot;: true,\r\n                &quot;kind&quot;: &quot;PostgresCluster&quot;,\r\n                &quot;name&quot;: &quot;pgcluster1&quot;,\r\n                &quot;uid&quot;: &quot;7260b882-116f-4b02-b51a-18d4fe3a8038&quot;\r\n            }\r\n        ],\r\n        &quot;resourceVersion&quot;: &quot;9495&quot;,\r\n        &quot;uid&quot;: &quot;1fbdf1d2-48ea-4a45-b7d6-01248317dbee&quot;\r\n    },\r\n    &quot;type&quot;: &quot;Opaque&quot;\r\n}\r\n<\/pre>\n<p>Pour se connecter \u00e0 notre pgbouncer, il suffit d\u2019utiliser les informations fournies par le fichier de secret \u00e0 la place de nos infos de connexion habituelles, et cela nous permet d\u2019acc\u00e9der directement au bouncer et non plus \u00e0 l\u2019instance elle-m\u00eame.<\/p>\n<p>Cette connexion peut \u00eatre facilement modifi\u00e9e en utilisant la documentation de pgbouncer afin de pouvoir configurer \u00e0 notre guise notre pgbouncer. Un exemple de configuration qu\u2019on pourrais rencontrer serait :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\n  proxy:\r\n    pgBouncer:\r\n      image: {{.Values.image.pgBouncer }}\r\n      config:\r\n        global:\r\n          default_pool_size: &quot;100&quot;\r\n          max_client_conn: &quot;10000&quot;\r\n          pool_mode: transaction\r\n<\/pre>\n<p>Pour cet exemple on voit qu\u2019on a d\u00e9finit un nombre de client maximum, la taille du pool \u00e0 100 et un mode transaction pour notre pool.<\/p>\n<h3>PGO et Prometheus<\/h3>\n<h4>Utilit\u00e9 :<\/h4>\n<p>Prometheus est une trousse \u00e0 outils de surveillance et d&#8217;alerte des syst\u00e8mes en open source.<br \/>\nPrometheus collecte et stocke ses m\u00e9triques sous forme de donn\u00e9es de s\u00e9ries temporelles, c&#8217;est-\u00e0-dire que les informations de m\u00e9triques sont stock\u00e9es avec le timestamp auquel elles ont \u00e9t\u00e9 enregistr\u00e9es, aux c\u00f4t\u00e9s de paires cl\u00e9-valeur optionnelles appel\u00e9es labels.<br \/>\n&#8211; Un mod\u00e8le de donn\u00e9es multidimensionnel avec des donn\u00e9es de s\u00e9ries temporelles identifi\u00e9es par le nom de la m\u00e9trique et des paires cl\u00e9-valeur<br \/>\n&#8211; PromQL, un langage de requ\u00eate flexible pour exploiter cette dimensionnalit\u00e9<br \/>\n&#8211; Aucune d\u00e9pendance sur le stockage distribu\u00e9 ; les n\u0153uds de serveur individuels sont autonomes<br \/>\n&#8211; La collecte de s\u00e9ries temporelles se fait via un mod\u00e8le de tirage sur HTTP<br \/>\n&#8211; La pouss\u00e9e de s\u00e9ries temporelles est prise en charge via une passerelle interm\u00e9diaire<br \/>\n&#8211; Les cibles sont d\u00e9couvertes via la d\u00e9couverte de service ou la configuration statique<br \/>\n&#8211; Prise en charge de plusieurs modes de graphiques et de tableaux de bord<\/p>\n<h4>Mise en place :<\/h4>\n<p>Pour pouvoir mettre en place une surveillance pour notre cluster, il est plus simple de t\u00e9l\u00e9charger et compl\u00e9ter le mod\u00e8le fournit dans les exemples de pgo.<br \/>\nAinsi, on peut r\u00e9cup\u00e9rer les exemples \u00e0 l\u2019aide de git :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nYOUR_GITHUB_UN=&quot;$YOUR_GITHUB_USERNAME&quot;\r\ngit clone --depth 1 &quot;git@github.com:${YOUR_GITHUB_UN}\/postgres-operator-examples.git&quot;\r\ncd postgres-operator-examples\r\n<\/pre>\n<p>Les diff\u00e9rentes configurations se trouvent dans le dossier kustomize\/monitoring.<br \/>\nPour activer le monitoring de notre instance, il faut ajouter la balise monitoring \u00e0 notre fichier postgres.yaml :<\/p>\n<pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\r\nmonitoring:\r\n  pgmonitor:\r\n    exporter:\r\n      image: registry.developers.crunchydata.com\/crunchydata\/crunchy-postgres-exporter:ubi8-5.5.1-0\r\n<\/pre>\n<p>Une fois notre configuration modifi\u00e9e, on l\u2019applique afin que PGO d\u00e9tecte les changements et configure tout seul l\u2019exporter pour qu\u2019il puisse se connecter \u00e0 nos bases de donn\u00e9es et r\u00e9cup\u00e9rer les m\u00e9triques.<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nkubectl apply -k kustomize\/postgres\r\n<\/pre>\n<p>Il faut ensuite appliquer la configuration de base de pgmonitor pour qu\u2019il cr\u00e9\u00e9 lui-m\u00eame les fichiers de configuration pour prometheus (il le fera en m\u00eame temps pour Grafana et Alertmanager qui sont deux autres outils de surveillance). Pour cela on applique le kustomize pr\u00e9sent dans le dossier monitoring :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n$kubectl apply -k kustomize\\postgres\r\npostgrescluster.postgres-operator.crunchydata.com\/pgcluster1 configured\r\n$kubectl apply -k kustomize\\monitoring\r\nserviceaccount\/alertmanager created\r\nserviceaccount\/grafana created\r\nserviceaccount\/prometheus created\r\nclusterrole.rbac.authorization.k8s.io\/prometheus created\r\nclusterrolebinding.rbac.authorization.k8s.io\/prometheus created\r\nconfigmap\/alert-rules-config created\r\nconfigmap\/alertmanager-config created\r\nconfigmap\/crunchy-prometheus created\r\nconfigmap\/grafana-dashboards created\r\nconfigmap\/grafana-datasources created\r\nsecret\/grafana-admin created\r\nservice\/crunchy-alertmanager created\r\nservice\/crunchy-grafana created\r\nservice\/crunchy-prometheus created\r\npersistentvolumeclaim\/alertmanagerdata created\r\npersistentvolumeclaim\/grafanadata created\r\npersistentvolumeclaim\/prometheusdata created\r\ndeployment.apps\/crunchy-alertmanager created\r\ndeployment.apps\/crunchy-grafana created\r\ndeployment.apps\/crunchy-prometheus created\r\n<\/pre>\n<p>Nos services ont \u00e9t\u00e9 correctement d\u00e9ploy\u00e9s, il ne nous reste plus qu\u2019\u00e0 utiliser celui qui nous int\u00e9resse, ici service\/crunchy-prometheus et lui indiquer de commencer \u00e0 envoyer les informations sur notre prometheus :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n$kubectl -n postgres-operator port-forward service\/crunchy-prometheus 9090:9090\r\nForwarding from 127.0.0.1:9090 -&gt; 9090\r\nForwarding from [::1]:9090 -&gt; 9090\r\nHandling connection for 9090\r\nHandling connection for 9090\r\n<\/pre>\n<p>Afin d\u2019acc\u00e9der \u00e0 notre service prometheus, il ne nous reste plus qu\u2019\u00e0 se connecter avec l\u2019adresse de notre machine, sur le port 9090 pr\u00e9alablement ouvert, pour voir apparaitre le dashboard de prometheus :<\/p>\n<p><a href=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-10567\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image2-300x66.jpg\" alt=\"\" width=\"300\" height=\"66\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image2-300x66.jpg 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image2-1024x226.jpg 1024w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image2-768x170.jpg 768w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/Image2.jpg 1386w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<h3>PGO Client :<\/h3>\n<h4>Utilit\u00e9 :<\/h4>\n<p>Pour pouvoir g\u00e9rer plus facilement le cluster cr\u00e9\u00e9 par PGO, CrunchyData \u00e0 d\u00e9velopp\u00e9 une surcouche \u00e0 kubectl qui permet de faciliter les commandes que nous pouvons r\u00e9aliser sur le cluster.<br \/>\nCela permet de ne pas avoir \u00e0 taper les longues lignes de commandes qui permettent par exemple de d\u00e9marrer les sauvegardes unitaires.<\/p>\n<h4>Mise en place :<\/h4>\n<p>Pour pouvoir installer cette surcouche, il faut t\u00e9l\u00e9charger la version qui correspond au syst\u00e8me d\u2019exploitation \u00e0 partir du GIT de pgo client :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# wget https:\/\/github.com\/CrunchyData\/postgres-operator-client\/releases\/download\/v0.4.1\/kubectl-pgo-linux-arm64\r\n--2024-04-11 12:07:45--  https:\/\/github.com\/CrunchyData\/postgres-operator-client\/releases\/download\/v0.4.1\/kubectl-pgo-linux-arm64\r\nResolving github.com (github.com)... 140.82.121.4\r\nConnecting to github.com (github.com)|140.82.121.4|:443... connected.\r\nHTTP request sent, awaiting response... 302 Found\r\nResolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.109.133, 185.199.111.133, 185.199.110.133, ...\r\nConnecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.109.133|:443... connected.\r\nHTTP request sent, awaiting response... 200 OK\r\nLength: 47895849 (46M) [application\/octet-stream]\r\nSaving to: \u2018kubectl-pgo-linux-arm64\u2019\r\n\r\nkubectl-pgo-linux-arm64                                     100%[========================================================================================================================================&gt;]  45.68M  --.-KB\/s    in 0.1s\r\n\r\n2024-04-11 12:07:45 (373 MB\/s) - \u2018kubectl-pgo-linux-arm64\u2019 saved [47895849\/47895849]\r\n<\/pre>\n<p>On renome le fichier t\u00e9l\u00e9charg\u00e9 en kubectl-pgo et on le d\u00e9place dans nos bin pour pouvoir les utiliser :<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\n# mv kubectl-pgo-linux-arm64 kubectl-pgo\r\n# sudo mv kubectl-pgo \/usr\/local\/bin\/kubectl-pgo\r\n# sudo chmod +x \/usr\/local\/bin\/kubectl-pgo\r\nUne fois que ces actions sont r\u00e9alis\u00e9es, on peut tester le fonctionnement :\r\n# kubectl pgo version\r\nClient Version: v0.4.1\r\nOperator Version: v5.5.1\r\n<\/pre>\n<p>Les commandes disponibles avec cette extension sont les suivantes :<br \/>\n&#8211; backup : Backup cluster<br \/>\n&#8211; create : Create a resource<br \/>\n&#8211; delete : Delete a resource<br \/>\n&#8211; help : Help about any command<br \/>\n&#8211; restore : Restore cluster<br \/>\n&#8211; show Show : PostgresCluster details<br \/>\n&#8211; start : Start cluster<br \/>\n&#8211; stop : Stop cluster<br \/>\n&#8211; support : Crunchy Support commands for PGO<br \/>\n&#8211; version : PGO client<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10562&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10562&#038;title=PGO%20%3A%20la%20suite\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=PGO%20%3A%20la%20suite&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F10562\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>La gestion efficace des clusters PostgreSQL dans un environnement Kubernetes est un d\u00e9fi complexe auquel sont confront\u00e9es de nombreuses entreprises aujourd&#8217;hui. PGO offre une solution d\u00e9clarative qui automatise la gestion des clusters PostgreSQL, simplifiant ainsi le d\u00e9ploiement, la mise \u00e0&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":41,"featured_media":10581,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[266],"tags":[480,481,443],"class_list":["post-10562","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-postgresql","tag-devops","tag-infraascode","tag-kubernetes"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>PGO : la suite - Capdata TECH BLOG<\/title>\n<meta name=\"description\" content=\"Tour d&#039;horizon des fonctionnalit\u00e9s annexes de l&#039;op\u00e9rateur kubernetes PGO pour PostgreSQL\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PGO : la suite - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Tour d&#039;horizon des fonctionnalit\u00e9s annexes de l&#039;op\u00e9rateur kubernetes PGO pour PostgreSQL\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2024-05-29T08:58:17+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-29T08:59:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/container-3118783_1280.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1280\" \/>\n\t<meta property=\"og:image:height\" content=\"802\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Sarah FAVEERE\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sarah FAVEERE\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\"},\"author\":{\"name\":\"Sarah FAVEERE\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2\"},\"headline\":\"PGO : la suite\",\"datePublished\":\"2024-05-29T08:58:17+00:00\",\"dateModified\":\"2024-05-29T08:59:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\"},\"wordCount\":3484,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"#devops\",\"#InfraAsCode\",\"Kubernetes\"],\"articleSection\":[\"PostgreSQL\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\",\"name\":\"PGO : la suite - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2024-05-29T08:58:17+00:00\",\"dateModified\":\"2024-05-29T08:59:28+00:00\",\"description\":\"Tour d'horizon des fonctionnalit\u00e9s annexes de l'op\u00e9rateur kubernetes PGO pour PostgreSQL\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PGO : la suite\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2\",\"name\":\"Sarah FAVEERE\",\"sameAs\":[\"http:\/\/blog.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/sfaveere\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PGO : la suite - Capdata TECH BLOG","description":"Tour d'horizon des fonctionnalit\u00e9s annexes de l'op\u00e9rateur kubernetes PGO pour PostgreSQL","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/","og_locale":"fr_FR","og_type":"article","og_title":"PGO : la suite - Capdata TECH BLOG","og_description":"Tour d'horizon des fonctionnalit\u00e9s annexes de l'op\u00e9rateur kubernetes PGO pour PostgreSQL","og_url":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2024-05-29T08:58:17+00:00","article_modified_time":"2024-05-29T08:59:28+00:00","og_image":[{"width":1280,"height":802,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2024\/05\/container-3118783_1280.jpg","type":"image\/jpeg"}],"author":"Sarah FAVEERE","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Sarah FAVEERE","Dur\u00e9e de lecture estim\u00e9e":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/"},"author":{"name":"Sarah FAVEERE","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2"},"headline":"PGO : la suite","datePublished":"2024-05-29T08:58:17+00:00","dateModified":"2024-05-29T08:59:28+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/"},"wordCount":3484,"commentCount":0,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["#devops","#InfraAsCode","Kubernetes"],"articleSection":["PostgreSQL"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/","url":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/","name":"PGO : la suite - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2024-05-29T08:58:17+00:00","dateModified":"2024-05-29T08:59:28+00:00","description":"Tour d'horizon des fonctionnalit\u00e9s annexes de l'op\u00e9rateur kubernetes PGO pour PostgreSQL","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/pgo-la-suite\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"PGO : la suite"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/686f2452f7ec79115d31e41c230a9da2","name":"Sarah FAVEERE","sameAs":["http:\/\/blog.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/sfaveere\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/10562","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=10562"}],"version-history":[{"count":12,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/10562\/revisions"}],"predecessor-version":[{"id":10580,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/10562\/revisions\/10580"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/10581"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=10562"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=10562"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=10562"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}