Hello
Il y a quelques temps, je vous avais présenté un premier article sur l’installation d’une instance de base de données PostgreSQL sous Docker. C’est cet article qui nous a permis de mettre un premier pas dans le monde de la containerisation de services.
L’article d’aujourd’hui reprend les mêmes concepts, à savoir, comment installer et configurer PostgreSQL sous minikube et Kubernetes.
Présentation de l’environnement Kubernetes
Avant de présenter Minikube, il nous faut parler de Kubernetes.
Kubernetes est un outil d’orchestration de conteneurs. En d’autres termes, celui ci permet de gérer des déploiements d’applications directement via une plate forme open-source.
Pour le fonctionnement, il nous faut un environnement virtualisé avec l’hyperviseur qui communique avec les couches applicatives précompilées embarquant leurs librairies. Ce sont donc ces couches applicatives que l’on appelle containers et qui peuvent être utilisées sur des serveurs “on premise” ou dans un service Cloud.
C’est autour de ce concept que Minikube s’est créé. Cet outil utilise les fonctionnalités propres à Kubernetes mais assure un déploiement sur un noeud unique.
Il vous est donc possible de profiter d’un éco-système Kubernetes complet sur un simple PC de bureau (avec une configuration RAM/Cpu exigeante) .
L’objectif de cet article est donc de déployer une instance PostgreSQL sur Minikube.
Prérequis propres à AWS
Si, comme moi, vous utilisez des VMs EC2 AWS, il y a quelques informations à connaître.
Tout d’abord, il faut savoir que AWS met à disposition un service nommé EKS, Elastic Kubernetes Service, pour la gestion de clusters directement intégré dans AWS.
Il n’est donc pas nécessaire de configurer manuellement Kubernetes via des commandes “kubectl”. De plus les mises à jour des outils sont automatisées.
AWS met également à disposition AWS Fargate. Un service qui permet de configurer des containers, sans se soucier des types de serveurs à mettre à disposition. L’utilisateur de cette solution ne voit donc que le coté application, ses besoins en terme de scalabilité, et AWS fait le reste.
Mais pour notre article, comme nous souhaitons utiliser Minikube, il nous faut une VM supportant les exigences de la virtualisation. Or sous AWS, ce sont les instances EC2 de type “bare metal” qui répondent à ce besoin. Attention donc à regarder ce point, et surtout prendre en considération la partie facturation qui est loin d’être négligeable
Pour notre exemple, nous partirons sur une instance EC2 “c5.metal”. Ce type d’instance permet la virtualisation.
Les différentes étapes d’installation
Il conviendra de s’assurer que les CPU de notre instance acceptent la virtualisation. Passer les commandes ci après
# egrep -q 'vmx|svm' /proc/cpuinfo "&&" echo yes || echo no yes
ou
# grep -E "vmx|svm" /proc/cpuinfo flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l3 cdp_l3 invpcid_single intel_ppin ssbd mba ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm mpx rdt_a avx512f avx512dq rdseed adx smap clflushopt clwb intel_pt avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts hwp hwp_act_window hwp_epp hwp_pkg_req pku ospke avx512_vnni md_clear flush_l1d arch_capabilities flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb cat_l3 cdp_l3 invpcid_single intel_ppin ssbd mba ibrs ibpb stibp ibrs_enhanced tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid cqm mpx rdt_a avx512f avx512dq rdseed adx smap clflushopt clwb intel_pt avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local dtherm ida arat pln pts hwp hwp_act_window hwp_epp hwp_pkg_req pku ospke avx512_vnni md_clear flush_l1d arch_capabilities .........
Le système d’exploitation choisi pour ce serveur est un Rocky Linux 8.7 , un fork Red Hat avec lequel nous pourrons gérer nos packages d’installation via yum.
Plusieurs packages sont à intégrer afin de faire fonctionner notre cluster mono nœud.
Installer la couche KVM
Afin de pouvoir installer Minikube, il nous faut un gestionnaire de container.
Pour l’article propre à Docker, nous avions utilisé le Docker Engine, qui a la particularité de pouvoir se passer de la partie Virtualisation et d’hyperviseur.
Pour notre exemple, l’idée est d’utiliser KVM (Kernel-linux Virtual Machine), qui nécessite une virtualisation active.
Installer les packages suivants sur le serveur
# yum update # yum install qemu-kvm libvirt libguestfs-tools virt-install
La librairie de virtualisation doit être activée et le service démarré automatiquement
# systemctl enable libvirtd.service # systemctl start libvirtd.service
Installer helm et kubectl
Ces outils sont nécessaires à l’administration de notre cluster, et l’installation d’applications. Helm nous sert à installer PostgreSQL depuis un repository, et kubectl est un interpréteur de commandes pour notre cluster.
# curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 138 100 138 0 0 1179 0 --:--:-- --:--:-- --:--:-- 1179 100 45.8M 100 45.8M 0 0 70.1M 0 --:--:-- --:--:-- --:--:-- 117M
# curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 # chmod 700 get_helm.sh # ./get_helm.sh Downloading https://get.helm.sh/helm-v3.11.2-linux-amd64.tar.gz Verifying checksum... Done. Preparing to install helm into /usr/local/bin helm installed into /usr/local/bin/helm
Installer ces binaires dans “/usr/local/bin”. Attention, par la suite, votre variable PATH doit contenir le chemin vers ce répertoire.
# install kubectl /usr/local/bin/kubectl # install helm /usr/local/bin/helm # chmod 755 /usr/local/bin/helm # chmod 755 /usr/local/bin/kubectl
Valider l’installation de helm et kubectl.
# helm version version.BuildInfo{ Version:"v3.11.2", GitCommit:"912ebc1cd10d38d340f048efaf0abda047c3468e", GitTreeState:"clean", GoVersion:"go1.18.10" }
# kubectl version -o json { "clientVersion": { "major": "1", "minor": "26", "gitVersion": "v1.26.2", "gitCommit": "fc04e732bb3e7198d2fa44efa5457c7c6f8c0f5b", "gitTreeState": "clean", "buildDate": "2023-02-22T13:39:03Z", "goVersion": "go1.19.6", "compiler": "gc", "platform": "linux/amd64" }, "kustomizeVersion": "v4.5.7" }
Installation de minikube
Télécharger et installer le binaire Minikube, puis le placer dans le répertoire “/usr/local/bin”.
# curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 # install minikube-linux-amd64 /usr/local/bin/minikube
Attention, minikube doit fonctionner avec un utilisateur linux dédié, autre que “root”. Il convient donc de créer un utilisateur appartenant aux 2 groupes “libvirt” et “qemu”.
# useradd -u 1001 -g qemu -G qemu,libvirt manu # passwd manu
Se connecter avec ce nouvel utilisateur et vérifier ses groupes.
# su - manu [manu@ ~]$ id uid=1001(manu) gid=107(qemu) groups=107(qemu),986(libvirt) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Gestion du cluster Minikube
Une fois les packages installés il nous faut démarrer Minikube avec notre compte linux dédié.
manu@~$ minikube start --driver=kvm2 * minikube v1.29.0 on Rocky 8.7 * Using the kvm2 driver based on user configuration * Downloading driver docker-machine-driver-kvm2: docker-machine-driver-kvm2-...: 65 B / 65 B [---------] 100.00% ? p/s 0s docker-machine-driver-kvm2-...: 12.30 MiB / 12.30 MiB 100.00% 13.05 MiB * Downloading VM boot image ... minikube-v1.29.0-amd64.iso....: 65 B / 65 B [---------] 100.00% ? p/s 0s minikube-v1.29.0-amd64.iso: 276.35 MiB / 276.35 MiB 100.00% 167.79 MiB * Starting control plane node minikube in cluster minikube * Downloading Kubernetes v1.26.1 preload ... preloaded-images-k8s-v18-v1...: 397.05 MiB / 397.05 MiB 100.00% 111.49 * Creating kvm2 VM (CPUs=2, Memory=6000MB, Disk=20000MB) ... * Preparing Kubernetes v1.26.1 on Docker 20.10.23 ... - Generating certificates and keys ... - Booting up control plane ... - Configuring RBAC rules ... * Configuring bridge CNI (Container Networking Interface) ... - Using image gcr.io/k8s-minikube/storage-provisioner:v5 * Verifying Kubernetes components... * Enabled addons: storage-provisioner, default-storageclass * Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Au premier démarrage, Minikube cherche les différentes images dont il a besoin.
Le démarrage suivant donnera ce résultat :
manu@~$ minikube start * minikube v1.29.0 on Rocky 8.7 * Using the kvm2 driver based on existing profile * Starting control plane node minikube in cluster minikube * Restarting existing kvm2 VM for "minikube" ... * Preparing Kubernetes v1.26.1 on Docker 20.10.23 ... * Configuring bridge CNI (Container Networking Interface) ... * Verifying Kubernetes components... - Using image gcr.io/k8s-minikube/storage-provisioner:v5 - Using image docker.io/kubernetesui/dashboard:v2.7.0 - Using image docker.io/kubernetesui/metrics-scraper:v1.0.8 * Some dashboard features require the metrics-server addon. To enable all features please run: minikube addons enable metrics-server * Enabled addons: storage-provisioner, dashboard, default-storageclass * Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Minikube est maintenant actif sur notre serveur.
Vérifier l’état de la couche virtualisation.
manu@~ $ sudo virsh net-list --all Name State Autostart Persistent ------------------------------------------------ default active yes yes mk-minikube active yes yes
Valider notre cluster avec “kubctl”
manu@~$ kubectl get nodes NAME STATUS ROLES AGE VERSION minikube Ready control-plane 35m v1.26.1
Pour arrêter le cluster
manu@~$ minikube stop * Stopping node "minikube" ... * 1 node stopped.
Déploiement générique de PostgreSQL sur Minikube
L’outil helm permet de déployer simplement une instance PostgreSQL sur notre cluster mono-nœud Minikube.
Pour cela, utilisons le repository “bitnami” via le site : https://charts.bitnami.com/bitnami.
Le fonctionnement s’apparente “un peu” à yum pour un système RedHat, il s’agit d’une source vers laquelle chercher pour enregistrer des applications à containeriser.
manu@ ~$ helm repo add bitnami https://charts.bitnami.com/bitnami "bitnami" has been added to your repositories
Une fois le repository initier, vérifier les versions PostgreSQL disponibles.
manu@~ $ helm search repo postgres NAME CHART VERSION APP VERSION DESCRIPTION bitnami/postgresql 12.2.5 15.2.0 PostgreSQL (Postgres) is an open source object-... bitnami/postgresql-ha 11.1.6 15.2.0 This PostgreSQL cluster solution includes the P... bitnami/supabase 0.1.4 0.23.2 Supabase is an open source Firebase alternative...
Le repository bitnami nous propose la dernière version 15.2 de PostgreSQL. Nous allons l’installer pour notre environnement minikube.
manu@~ $ helm install postgres bitnami/postgresql NAME: postgres LAST DEPLOYED: Mon Mar 20 15:41:00 2023 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: postgresql CHART VERSION: 12.2.5 APP VERSION: 15.2.0 ** Please be patient while the chart is being deployed ** PostgreSQL can be accessed via port 5432 on the following DNS names from within your cluster: postgres-postgresql.default.svc.cluster.local - Read/Write connection To get the password for "postgres" run: export POSTGRES_PASSWORD=$(kubectl get secret --namespace default postgres-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d) To connect to your database run the following command: kubectl run postgres-postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:15.2.0-debian-11-r13 --env="PGPASSWORD=$POSTGRES_PASSWORD" \ --command -- psql --host postgres-postgresql -U postgres -d postgres -p 5432 NOTE: If you access the container using bash, make sure that you execute "/opt/bitnami/scripts/postgresql/entrypoint.sh /bin/bash" in order to avoid the error "psql: local user with ID 1001} does not exist" To connect to your database from outside the cluster execute the following commands: kubectl port-forward --namespace default svc/postgres-postgresql 5432:5432 "&" PGPASSWORD="$POSTGRES_PASSWORD" psql --host 127.0.0.1 -U postgres -d postgres -p 5432 WARNING: The configured password will be ignored on new installation in case when previous Posgresql release was deleted through the helm command. In that case, old PVC will have an old password, and setting it through helm won't take effect. Deleting persistent volumes (PVs) will solve the issue.
Vérifier le déploiement dans le repository
manu@~ $ helm list NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION postgres default 1 2023-03-20 15:41:00.677760646 +0000 UTC deployed postgresql-12.2.5 15.2.0
Notre application containerisée PostgreSQL est bien déployée dans le repository.
Vérifier son installation dans le cluster minikube et voir les différents services présents :
manu@~ $ kubectl get deployment,pods,svc NAME READY STATUS RESTARTS AGE pod/postgres-postgresql-0 1/1 Running 0 18m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 none 443/TCP 36m service/postgres-postgresql ClusterIP 10.109.83.132 none 5432/TCP 18m service/postgres-postgresql-hl ClusterIP None none 5432/TCP 18m
Nous remarquons que notre application PostgreSQL est enregistrée sous l’adresse IP 10.109.83.132. Le port de communication est 5432.
C’est cette adresse qui sera référencée comme VIP pour notre cluster.
Connexion à l’instance PostgreSQL
Lors de l’installation, les instructions de connexion nous ont été données (notamment la gestion du password de connexion).
Pour retrouver le password postgres, c’est l’outil “kubectl” qui est appelé.
manu@~ $ kubectl get secret --namespace default postgres-postgresql -o jsonpath="{.data.postgres-password}" | base64 -d HvbCO9Co5R
Enregistrer cette valeur dans une variable que l’on peut nommer PGPASS par exemple.
manu@~$ export PGPASS=$(kubectl get secret --namespace default postgres-postgresql -o jsonpath="{.data.postgres-password}" | base64 --decode)
Lancer la commande, indiquée lors de l’installation de PostgreSQL avec “helm”, pour se connecter à l’instance.
manu@~$ kubectl run postgres-postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:15.2.0-debian-11-r13 --env="PGPASSWORD=$PGPASS" --command -- psql --host postgres-postgresql -U postgres -d postgres -p 5432 If you don't see a command prompt, try pressing enter. postgres=# \l+ List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description -----------+----------+----------+-------------+-------------+-----------------------+---------+------------+-------------------------------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | 7453 kB | pg_default | default administrative connection database template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +| 7297 kB | pg_default | unmodifiable empty database | | | | | postgres=CTc/postgres | | | template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +| 7525 kB | pg_default | default template for new databases | | | | | postgres=CTc/postgres | | | (3 rows) postgres=# select version(); version --------------------------------------------------------------------------------------------------- PostgreSQL 15.2 on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit (1 row)
Pour se connecter à cette instance PostgreSQL, nous avons lancé une application “PostgreSQL cliente” déployée à partir d’une image Docker ‘docker.io/bitnami/postgresql:15.2.0-debian-11-r13’ en PostgreSQL version 15.2 compilée sous un Debian 11.13. Cette application une fois déployée, nous permet d’exécuter l’outil “psql” pour se connecter.
A noter qu’à la première exécution, cette image est enregistrée dans le node minikube
manu@ ~$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES postgres-postgresql-0 1/1 Running 2 (25m ago) 24h 10.244.0.17 minikube none none postgres-postgresql-client 0/1 Completed 0 16m 10.244.0.19 minikube none none
Repérer le pod “postgres-postgresql-client”, le status est à “completed” car nous n’avons plus de connexion active. D’ailleurs, le “READY” est à 0/1 car aucune connexion.
Il est tout à fait possible de retirer cette application publiée dans les pods de minikube. Pour cela, lancer la commande :
manu@ ~$ kubectl delete pod postgres-postgresql-client pod "postgres-postgresql-client" deleted
Vérifier:
manu@ ~$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES postgres-postgresql-0 1/1 Running 2 (25m ago) 24h 10.244.0.17 minikube none none
Nous venons donc d’installer une instance PostgreSQL par défaut grâce à l’outil helm dans notre cluster Minikube.
Configuration d’instance et volume persisté sur Minikube
Afin de pouvoir conserver vos données sur disque, il est possible de monter une instance PostgreSQL avec, ce que l’on appelle, un “volume persisté”.
Il faut, pour cela, dédier un FileSystem pour les données PostgreSQL sur la VM locale exécutant Minikube.
De plus, PostgreSQL peut être créé avec des valeurs de configuration différentes que ce qui est proposé avec l’outil helm.
L’intérêt est de monter une instance pré-configurée, pour une application métier, dès le démarrage.
Les fichiers YAML
Pour le déploiement d’une instance PostgreSQL spécifique, nous devons utiliser des fichiers de configuration “yaml” que nous chargerons dans le cluster via “kubectl”.
fichier YAML de configuration d’instance
Un fichier “configmap” doit être créé si l’on souhaite spécifier des informations sur les credentials (user/password), et/ou base de données métier.
Utiliser pour cela le fichier yaml suivant pour créer un utilisateur “capdata“, avec une base “capddb” pour l’application “postgres”.
apiVersion: v1 kind: ConfigMap metadata: name: pg-capdata labels: app: postgres data: POSTGRES_DB: capdb POSTGRES_USER: capdata POSTGRES_PASSWORD: passcapdata2023
Appliquer ce fichier à votre configuration Kubernenetes Minikube, puis valider celle ci
manu@~$ kubectl apply -f pg-configmap.yaml configmap/pg-capdata created manu@ ~$ kubectl get configmap NAME DATA AGE kube-root-ca.crt 1 3d23h pg-capdata 3 4s
fichier YAML pour les volumes
Choisir un FileSystem dédié sur le serveur, et créer le répertoire pour accueillir l’instance PostgreSQL.
manu@ ~$ df -h /data Filesystem Size Used Avail Use% Mounted on /dev/nvme1n1p1 19G 28K 18G 1% /data manu@ ~$ mkdir -p /data/postgresql
Nous aurons besoin de 2 fichiers yaml pour la configuration des volumes, 1 pour le volume persisté qui nous permet de conserver nos données d’instance durant le cycle de vie de celle ci. De plus, il nous faut, ce que l’on appelle, un “Persistent Volume Claim”. C’est une vue logique du volume géré par le cluster Kubernetes.
Les 2 fichiers contiennent les entrées suivantes :
pg-data-pvc.yaml
apiVersion: v1 kind: PersistentVolume metadata: name: pg-data labels: type: local app: postgres spec: storageClassName: manual capacity: storage: 8Gi accessModes: - ReadWriteMany hostPath: path: "/data/postgresql"
pg-data-pvc.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pg-data-claim labels: app: postgres spec: storageClassName: manual accessModes: - ReadWriteMany resources: requests: storage: 8Gi
Charger ces 2 fichiers yaml dans Kubernetes.
manu@ ~$ kubectl apply -f pg-data.yaml manu@ ~$ kubectl apply -f pg-data-pvc.yaml
Vérifier les informations dans le cluster
manu@ ~$ kubectl get pv -o wide NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE pg-data 8Gi RWX Retain Bound default/pg-data-claim manual 2m50s Filesystem manu@ ~$ kubectl get pvc -o wide NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE pg-data-claim Bound pg-data 8Gi RWX manual 94s Filesystem
Fichier YAML de déploiement
Après avoir déclarer la configuration, les volumes, nous pouvons déployer l’instance dans le cluster Kubernetes. Par exemple, nous déclarons 2 répliquas d’une instance PostgreSQL 15.2, écoutant sur le port 5432.
apiVersion: apps/v1 kind: Deployment metadata: name: postgres spec: replicas: 2 selector: matchLabels: app: postgres template: metadata: labels: app: postgres spec: containers: - name: postgres image: postgres:15.2 imagePullPolicy: "IfNotPresent" ports: - containerPort: 5432 envFrom: - configMapRef: name: pg-capdata volumeMounts: - mountPath: /var/lib/postgresql/data name: postgresdata volumes: - name: postgresdata persistentVolumeClaim: claimName: pg-data-claim
Appliquer ce fichier yaml et vérifier que le status “Running” apparaisse sur les 2 répliquas PostgreSQL. On appelle “pod” sur Kubernetes, un container applicatif avec ses librairies embarquées.
manu@ ~$ kubectl apply -f pg-deploiement.yaml deployment.apps/postgres-deploy created manu@ ~$ kubectl get pods,deployments -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod/postgres-66855ddfc5-drsqj 1/1 Running 0 83s 10.244.0.3 minikube none none pod/postgres-66855ddfc5-n9fc8 1/1 Running 1 (71s ago) 83s 10.244.0.4 minikube none none NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR deployment.apps/postgres 2/2 2 2 83s postgres postgres:15.2 app=postgres
Sur le node nommé “Minikube”, nous voyons donc tourner nos 2 répliquas PostgreSQL avec leurs IP en 10.244.0.***
Fichier yaml de service PostgreSQL
Afin de pouvoir se connecter à notre instance PostgreSQL, il faut lui définir un service. C’est une sorte de porte d’entrée pour accéder à notre instance.
apiVersion: v1 kind: Service metadata: name: postgres-capdata labels: app: postgres spec: type: NodePort ports: - port: 5432 selector: app: postgres
Appliquer ce fichier yaml sur le cluster.
manu@ ~$ kubectl apply -f pg-service.yaml service/postgres-capdata created[/yaml] manu@ ~$ kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR kubernetes ClusterIP 10.96.0.1 none 443/TCP 16d none postgres NodePort 10.110.166.18 none 5432:32581/TCP 6m48s app=postgres
Connexion à PostgreSQL
2 méthodes pour nous connecter à l’instance PostgreSQL s’offrent à nous.
- Connexion via Kubernetes
Utiliser l’outil “kubectl” pour se connecter à l’instance PostgreSQL. Utiliser le compte préalablement défini, “capdata“, sur la base “capdb“.
manu@ ~$ kubectl exec -it postgres-66855ddfc5-drsqj -- psql -h localhost -U capdata --password -p 5432 capdb Password: psql (15.2 (Debian 15.2-1.pgdg110+1)) Type "help" for help. capdb=# \conninfo You are connected to database "capdb" as user "capdata" on host "localhost" (address "127.0.0.1") at port "5432". capdb=#
- Connexion via un client PostgreSQL local à la VM.
Sur notre VM Rocky Linux, nous disposons d’une vieille version de “psql” que nous pouvons utiliser pour la connexion (version 10 de PostgreSQL).
Repérer auparavant, la valeur du port de sortie que nous avions trouvé lorsque nous avons passé la commande “kubectl get svc -o wide”.
Pour notre service dédié à postgreSQL, nous avons comme port “5432:32581”. Le 5432 est le port d’écoute local à Kubernetes. Pour accèder depuis notre VM, c’est le port 32581 dont nous aurons besoin.
De plus, l’IP de notre cluster Kubernetes, doit être connue. Pour cela , exécuter cette commande :
manu@ip-172-44-3-198 ~]$ kubectl get pods --all-namespaces -o wide NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES default postgres-66855ddfc5-drsqj 1/1 Running 0 17m 10.244.0.3 minikube none none default postgres-66855ddfc5-n9fc8 1/1 Running 1(17m ago) 17m 10.244.0.4 minikube none none kube-system coredns-787d4945fb-87kzd 1/1 Running 0 23m 10.244.0.2 minikube none none kube-system etcd-minikube 1/1 Running 0 23m 192.168.39.227 minikube none none kube-system kube-apiserver-minikube 1/1 Running 0 23m 192.168.39.227 minikube none none kube-system kube-controller-manager-minikube 1/1 Running 0 23m 192.168.39.227 minikube none none kube-system kube-proxy-lptq2 1/1 Running 0 23m 192.168.39.227 minikube none none kube-system kube-scheduler-minikube 1/1 Running 0 23m 192.168.39.227 minikube none none kube-system storage-provisioner 1/1 Running 1 (22m ago) 23m 192.168.39.227 minikube none none
L’IP du cluster Kubernetes est 192.168.39.227.
La connexion via PSQL se fait donc sur cette IP. Valider la connexion sur la base “capdb”.
manu@ ~$ psql -h 192.168.39.227 -U capdata -p 32581 capdb Password for user capdata: psql (10.23, server 15.2 (Debian 15.2-1.pgdg110+1)) WARNING: psql major version 10, server major version 15. Some psql features might not work. Type "help" for help. capdb=# \conninfo You are connected to database "capdb" as user "capdata" on host "192.168.39.227" at port "32581". capdb=# \l+ List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description -----------+---------+----------+------------+------------+---------------------+---------+------------+-------------------------------------------- capdb | capdata | UTF8 | en_US.utf8 | en_US.utf8 | | 7453 kB | pg_default | postgres | capdata | UTF8 | en_US.utf8 | en_US.utf8 | | 7453 kB | pg_default | default administrative connection database template0 | capdata | UTF8 | en_US.utf8 | en_US.utf8 | =c/capdata +| 7297 kB | pg_default | unmodifiable empty database | | | | | capdata=CTc/capdata | | | template1 | capdata | UTF8 | en_US.utf8 | en_US.utf8 | =c/capdata +| 7525 kB | pg_default | default template for new databases | | | | | capdata=CTc/capdata | | | (4 rows)
Le compte “capdata” que nous avons inscrit dans le fichier configmap est owner pour toutes les bases de cette instance.
Les logs
Il est possible d’aller regarder les logs de nos “pods” déployés sur Kubernetes.
Pour cela choisir la commande “kubectl logs”.
Par exemple, lancer cette commande sur 1 des répliquas PostgreSQL du cluster, et vous avec accès en lecture au fichier “postgresql.log” de l’instance
manu@ ~$ kubectl logs pod/postgres-66855ddfc5-drsqj The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale "en_US.utf8". The default database encoding has accordingly been set to "UTF8". The default text search configuration will be set to "english". Data page checksums are disabled. fixing permissions on existing directory /var/lib/postgresql/data ... ok creating subdirectories ... ok selecting dynamic shared memory implementation ... posix selecting default max_connections ... 100 selecting default shared_buffers ... 128MB selecting default time zone ... Etc/UTC creating configuration files ... ok running bootstrap script ... ok performing post-bootstrap initialization ... ok syncing data to disk ... ok initdb: warning: enabling "trust" authentication for local connections initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. Success. You can now start the database server using: pg_ctl -D /var/lib/postgresql/data -l logfile start pg_ctl: another server might be running; trying to start server anyway waiting for server to start....2023-03-27 09:30:32.071 UTC [48] LOG: starting PostgreSQL 15.2 (Debian 15.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit 2023-03-27 09:30:32.075 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2023-03-27 09:30:32.087 UTC [51] LOG: database system was interrupted; last known up at 2023-03-27 09:30:32 UTC 2023-03-27 09:30:32.110 UTC [51] LOG: database system was not properly shut down; automatic recovery in progress 2023-03-27 09:30:32.113 UTC [51] LOG: invalid record length at 0/14FE0E0: wanted 24, got 0 2023-03-27 09:30:32.113 UTC [51] LOG: redo is not required 2023-03-27 09:30:32.118 UTC [49] LOG: checkpoint starting: end-of-recovery immediate wait 2023-03-27 09:30:32.140 UTC [49] LOG: checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.006 s, sync=0.003 s, total=0.024 s; sync files=2, longest=0.002 s, average=0.002 s; distance=0 kB, estimate=0 kB 2023-03-27 09:30:32.144 UTC [48] LOG: database system is ready to accept connections done server started CREATE DATABASE /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/* 2023-03-27 09:30:32.262 UTC [48] LOG: received fast shutdown request waiting for server to shut down....2023-03-27 09:30:32.266 UTC [48] LOG: aborting any active transactions 2023-03-27 09:30:32.268 UTC [48] LOG: background worker "logical replication launcher" (PID 54) exited with exit code 1 2023-03-27 09:30:32.268 UTC [49] LOG: shutting down 2023-03-27 09:30:32.271 UTC [49] LOG: checkpoint starting: shutdown immediate 2023-03-27 09:30:32.341 UTC [49] LOG: checkpoint complete: wrote 916 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.013 s, sync=0.045 s, total=0.073 s; sync files=249, longest=0.036 s, average=0.001 s; distance=4217 kB, estimate=4217 kB 2023-03-27 09:30:32.345 UTC [48] LOG: database system is shut down done server stopped PostgreSQL init process complete; ready for start up. 2023-03-27 09:30:32.384 UTC [1] LOG: starting PostgreSQL 15.2 (Debian 15.2-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit 2023-03-27 09:30:32.385 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 2023-03-27 09:30:32.385 UTC [1] LOG: listening on IPv6 address "::", port 5432 2023-03-27 09:30:32.392 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" 2023-03-27 09:30:32.401 UTC [64] LOG: database system was shut down at 2023-03-27 09:30:32 UTC 2023-03-27 09:30:32.406 UTC [1] LOG: database system is ready to accept connections
Nous obtenons les informations de la création de l’instance jusqu’au dernier démarrage.
N’hésitez pas à laisser un message !
Emmanuel RAMI.
Continuez votre lecture sur le blog :
- Kubegres : l’opérateur Kubernetes clé en main pour PostgreSQL (David Baffaleuf) [ContainerDevopsPostgreSQL]
- PGO : opérateurs kubernetes pour PostgreSQL, la suite ! (David Baffaleuf) [ContainerDevopsPostgreSQL]
- Comparatif des gestionnaires de VIP dans un cluster Patroni : épisode 2 (VIP-MANAGER) (David Baffaleuf) [ContainerPostgreSQL]
- Comparatif des gestionnaires de VIP dans un cluster Patroni : épisode 1 (KEEPALIVED) (David Baffaleuf) [ContainerPostgreSQL]
- Containeriser PostgreSQL avec Docker ! (Emmanuel RAMI) [ContainerPostgreSQL]