Ce document décrit comment installer les bases de données PostgreSQL, MongoDB et Redis
au sein d'un cluster Kubernetes. Plusieurs instances de ces bases sont déployées afin
d'assurer la haute disponibilité des données.
La mise en place des bases de données PostgreSQL est effectuée à l'aide de kubegres,
un opérateur Kubernetes qui met en place automatiquement des instances de réplications.
Il est possible de définir n'importe quel nom pour les clefs superUserPassword et
replicationUserPassword.
Si souhaité, il est possible de définir un script bash primary_init_script.sh qui sera
exécuté la première fois qu'une instance primaire est créée. Ceci permet de créer en
avance les bases de données et utilisateurs.
Créer un fichier postgres-conf.yaml avec le contenu suivant :
apiVersion:v1kind:ConfigMapmetadata:name:mypostgres-confnamespace:postgresdata:primary_init_script.sh:|#!/bin/bashset -edt=$(date '+%d/%m/%Y %H:%M:%S');echo "$dt - Running init script the 1st time Primary PostgreSql container is created...";POSTGRES_USER="postgres"export PGPASSWORD=$POSTGRES_PASSWORDecho "$dt - Running: psql -v ON_ERROR_STOP=1 --username $POSTGRES_USER";psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQLCREATE USER backup_user;CREATE DATABASE cit_geocoding_db;CREATE DATABASE cit_per_db;EOSQLecho "$dt - Init script is completed";
Appliquer cette ConfigMap avec kubectl apply -f postgres-conf.yaml.
Les bases de données Postgres de Botalista nécessitent l'extension Postgis. Il faut donc
créer un objet Kubegres à partir d'une image postgis, qui utilise longhorn-local
comme StorageClass et mypostgres-conf comme ConfigMap.
La création de l'objet Kubegres va créer 3 instances de PostgreSQL, avec un service
pour accéder à l'instance principale et un autre pour celles de réplication.
Cette section contient la marche à suivre pour créer les bases de données des
modules de Botalista durant la réalisation de mon travail de Bachelor. Cette marche
à suivre n'est pas forcément pertinente dans un autre contexte.
Afin de créer les bases de données et utilisateurs requis par Botalista, il faut
exécuter un shell bash au sein du pod de l'instance maître.
L'instance maître devrait correspondre au pod postgres-1-0 après l'installation,
néanmoins il est recommandé de vérifier cela en vérifiant l'endpoint correspondant au
service postgres.
Exécuter ensuite un bash interactif au pod dont l'IP correspond à l'endpoint du service
postgres (ici postgres-1-0) afin d'importer les fichiers dumps.
Les commandes ci-dessous vont tout d'abord ajouter une copie des fichiers dump dans un
répertoire du pod postgres, pour ensuite les importer dans la base de données.
exportDUMP_FOLDER=<dump_folder>
# Create a copy of the dump files in the /tmp folder of the podfordump_filein$DUMP_FOLDER/*.sql;\dokubectlexec-ipod/postgres-1-0--\bash-c"cat > /tmp/$(basename--$dump_file)"<$dump_file;done;# Start a shell inside the podkubectlexec-itpod/postgres-1-0--bash
# Add a leading space to prevent saving the command in the bash historyexportPGPASSWORD="<your_password>"# Import the dump files# psql -U postgres -d <database> -f <dump.sql>psql-Upostgres-dchat_bota_acq_db-fchat_bota_acq_prd.sql
...
Configuration spécifique pour les tables business_cit :
apiVersion:mongodbcommunity.mongodb.com/v1kind:MongoDBCommunitymetadata:name:mongodbnamespace:mongodbspec:members:3type:ReplicaSetversion:"6.0.5"security:authentication:# SCRAM-SHA-1 seems required, but should but avoidedmodes:["SCRAM","SCRAM-SHA-1"]users:# Admin user-name:bota-admindb:adminpasswordSecretRef:name:admin-passwordroles:-name:clusterAdmindb:admin-name:userAdminAnyDatabasedb:adminscramCredentialsSecretName:admin-scram# Botalista users-name:chat_bota_exp_userdb:chat_bota_exp_dbpasswordSecretRef:name:chat-passwordroles:-name:readWritedb:chat_bota_exp_dbscramCredentialsSecretName:chat-scram-name:g_bota_exp_userdb:g_bota_exp_dbpasswordSecretRef:name:g-passwordroles:-name:readWritedb:g_bota_exp_dbscramCredentialsSecretName:g-scramadditionalMongodConfig:storage.wiredTiger.engineConfig.journalCompressor:zlibstatefulSet:spec:template:spec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:-matchExpressions:-key:node-role.kubernetes.io/db-hostoperator:ExistspodAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:-labelSelector:matchExpressions:-key:appoperator:Invalues:-mongodb-svctopologyKey:kubernetes.io/hostnamevolumeClaimTemplates:-metadata:name:data-volumespec:accessModes:["ReadWriteOnce"]storageClassName:longhorn-localresources:requests:storage:2Gi# You may need to increase the storage size-metadata:name:logs-volumespec:accessModes:["ReadWriteOnce"]storageClassName:longhorn-localresources:requests:storage:1Gi# You may need to increase the storage size
Ce fichier permet de créer un Replica Set MongoDB avec 3 membres, tout en y
définissant des utilisateurs à créer à partir d'un secret Kubernetes.
# This secret can be deleted after creating the mongodb clusterapiVersion:v1kind:Secretmetadata:name:admin-passwordnamespace:mongodbtype:OpaquestringData:password:superUserPassword
Une fois les secrets créés, le Replica Set peut à son tour être créé :
Se connecter via le service sans spécifier le Replica Set peut provoquer des erreurs
pour les requêtes en écritures, car le service à lui seul ne permet pas de garantir une
connexion à l'instance principale.
# Create the namespacekubectlcreatensredis&&kubectlconfigset-context--current--namespace=redis
# Create the secretkubectlcreatesecretgenericredis-password-secret--from-file=redis-password
# Install Redis with Helmhelmrepoaddbitnamihttps://charts.bitnami.com/bitnami
helmrepoupdate
helminstallredisbitnami/redis-fvalues.yaml
La désactivation de Sentinel est envisageable si le mécanisme de failover avec Sentinel
n'est pas souhaité ou nécessaire. Voici le fichier values.yaml modifié en conséquence:
global:storageClass:longhorn-localauth:usePasswordFiles:trueexistingSecret:redis-password-secretmaster:persistence:size:1Giresources:requests:cpu:50mmemory:256Milimits:cpu:250mmemory:512Mireplica:replicaCount:2# This was changed from 3 to 2affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:-matchExpressions:-key:node-role.kubernetes.io/db-hostoperator:ExistspodAntiAffinity:requiredDuringSchedulingIgnoredDuringExecution:-labelSelector:matchExpressions:-key:app.kubernetes.io/nameoperator:Invalues:-redistopologyKey:kubernetes.io/hostnamepersistence:size:1Giresources:requests:cpu:50mmemory:256Milimits:cpu:250mmemory:512Misentinel:enabled:false# This is now disabled
Cette configuration expose 2 services (port 6379) au lieu d'un seul :
service/redis-master: pour les requêtes en lecture/écriture
service/redis-replicas: pour les requêtes en lecture