Utiliser le MariaDB Operator dans Kubernetes
Ce guide explique comment déployer une instance MariaDB dans un cluster Kubernetes à l’aide du MariaDB Operator,
en configurant les paramètres via des ressources ConfigMap, Secret et MariaDB.
Configuration initiale
Commencez par créer les manifestes nécessaires pour stocker la configuration et les données sensibles utilisées par l’operator.
ConfigMap pour la configuration MariaDB
apiVersion: v1
kind: ConfigMap
metadata:
name: mariadb
namespace: mdb-demo
labels:
k8s.mariadb.com/watch: ""
data:
my.cnf: |
[mariadb]
bind-address=*
default_storage_engine=InnoDB
binlog_format=row
innodb_autoinc_lock_mode=2
innodb_buffer_pool_size=1024M
max_allowed_packet=256M
Secret pour les mots de passe
apiVersion: v1
kind: Secret
metadata:
name: mariadb
namespace: mdb-demo
labels:
k8s.mariadb.com/watch: ""
stringData:
password: change-me
root-password: change-me
Déploiement de l’instance MariaDB
Créez une ressource personnalisée de type MariaDB pour démarrer une instance.
Vous pouvez spécifier si les mots de passe doivent être générés automatiquement ou fournis via un secret existant.
La configuration my.cnf peut également être référencée.
apiVersion: k8s.mariadb.com/v1alpha1
kind: MariaDB
metadata:
name: mariadb
namespace: mdb-demo
spec:
username: mariadb-user
database: mariadb
port: 3306
storage:
size: 1Gi
myCnfConfigMapKeyRef:
name: mariadb
key: my.cnf
rootPasswordSecretKeyRef:
name: mariadb
key: root-password
generate: false
passwordSecretKeyRef:
name: mariadb
key: password
generate: false
La création de cette ressource MariaDB déclenchera automatiquement la génération des objets nécessaires :
- StatefulSet
- Pods
- Services
Ces composants permettront de déployer et d’exposer votre base de données MariaDB dans le cluster.
$ kubectl get mariadbs
NAME READY STATUS PRIMARY POD AGE
mariadb True Running mariadb-0 8m17s
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
mariadb-0 1/1 Running 0 8m40s
$ kubectl get statefulsets
NAME READY AGE
mariadb 1/1 8m38s
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mariadb ClusterIP 10.107.55.105 <none> 3306/TCP 8m49s
mariadb-internal ClusterIP None <none> 3306/TCP 8m49s
Utilisation
Une fois MariaDB opérationnel, vous pouvez créer des éléments supplémentaires tels que des bases de données, des utilisateurs et des droits d’accès.
Plusieurs options s’offrent à vous pour interagir avec la base de données :
- utiliser des interfaces comme
phpMyAdmin - développer du code personnalisé
- utiliser l’operator via des ressources Kubernetes dédiées
Ressources
Database
Le manifeste Database permet de créer un objet représentant une base de données structurée,
destinée à stocker et organiser les données dans MariaDB.
apiVersion: k8s.mariadb.com/v1alpha1
kind: Database
metadata:
name: database-2
namespace: mdb-demo
spec:
name: database-change-me
mariaDbRef:
name: mariadb
characterSet: utf8
collate: utf8_general_ci
requeueInterval: 30s
retryInterval: 5s
User
Le manifeste User permet de créer un objet représentant un utilisateur autorisé à interagir avec la base de données MariaDB.
apiVersion: k8s.mariadb.com/v1alpha1
kind: User
metadata:
name: user-2
namespace: mdb-demo
spec:
# If you want the user to be created with a different name than the resource name
name: user-change-me
mariaDbRef:
name: mariadb
passwordSecretKeyRef:
name: mariadb
key: password
# This field is immutable and defaults to 10
maxUserConnections: 20
host: "%"
retryInterval: 5s
Grant
Le manifeste Grant permet de créer un objet qui attribue des permissions à un utilisateur pour interagir avec une ou plusieurs bases de données MariaDB.
apiVersion: k8s.mariadb.com/v1alpha1
kind: Grant
metadata:
name: grant
namespace: mdb-demo
spec:
mariaDbRef:
name: mariadb
privileges:
- "SELECT"
- "INSERT"
- "UPDATE"
# - "ALL PRIVILEGES"
database: "*"
table: "*"
username: user-change-me
grantOption: true
host: "%"
requeueInterval: 30s
retryInterval: 5s
Data
Pour ajouter des tables et des données, vous pouvez utiliser une ressource SqlJob.
Ces jobs exécutent des scripts SQL simples et peuvent être lancés une seule fois ou de manière récurrente grâce à une syntaxe cron définie dans l’attribut schedule.
Les jobs peuvent également dépendre d’autres jobs, ce qui permet de garantir que les données liées à des relations entre tables soient créées dans le bon ordre.
apiVersion: k8s.mariadb.com/v1alpha1
kind: SqlJob
metadata:
name: 01-users
namespace: mdb-demo
spec:
mariaDbRef:
name: mariadb
inheritMetadata:
annotations:
database.myorg.io: mariadb
podMetadata:
labels:
sidecar.istio.io/inject: "false"
serviceAccountName: sqljob
username: mariadb-user
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
sql: |
CREATE TABLE IF NOT EXISTS users (
id bigint PRIMARY KEY AUTO_INCREMENT,
username varchar(255) NOT NULL,
UNIQUE KEY name__unique_idx (username)
);
INSERT INTO users(username) VALUES('marie')
ON DUPLICATE KEY UPDATE id=id;
INSERT INTO users(username) VALUES('arnaud')
ON DUPLICATE KEY UPDATE id=id;
---
apiVersion: k8s.mariadb.com/v1alpha1
kind: SqlJob
metadata:
name: 02-repos
namespace: mdb-demo
spec:
dependsOn:
- name: 01-users
mariaDbRef:
name: mariadb
username: mariadb-user
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
sql: |
CREATE TABLE IF NOT EXISTS repos (
id bigint PRIMARY KEY AUTO_INCREMENT,
name varchar(255) NOT NULL,
owner_id bigint NOT NULL,
UNIQUE KEY name__unique_idx (name),
FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE CASCADE
);
INSERT INTO repos(name, owner_id) VALUES('mariadb-operator', (SELECT id FROM users WHERE username = 'marie'))
ON DUPLICATE KEY UPDATE id=id;
INSERT INTO repos(name, owner_id) VALUES('mariadb-operator-helm', (SELECT id FROM users WHERE username = 'arnaud'))
ON DUPLICATE KEY UPDATE id=id;
---
apiVersion: k8s.mariadb.com/v1alpha1
kind: SqlJob
metadata:
name: 03-stars
namespace: mdb-demo
spec:
dependsOn:
- name: 01-users
- name: 02-repos
mariaDbRef:
name: mariadb
schedule:
cron: "*/1 * * * *"
suspend: false
username: mariadb-user
passwordSecretKeyRef:
name: mariadb
key: password
database: mariadb
sql: |
CREATE TABLE IF NOT EXISTS stars (
id bigint PRIMARY KEY AUTO_INCREMENT,
user_id bigint NOT NULL,
repo_id bigint NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (repo_id) REFERENCES repos(id) ON DELETE CASCADE,
UNIQUE KEY (user_id, repo_id)
);
INSERT INTO stars(user_id, repo_id)
VALUES((SELECT id FROM users ORDER BY RAND() LIMIT 1), (SELECT id FROM repos ORDER BY RAND() LIMIT 1))
ON DUPLICATE KEY UPDATE id=id;
INSERT INTO stars(user_id, repo_id)
VALUES((SELECT id FROM users ORDER BY RAND() LIMIT 1), (SELECT id FROM repos ORDER BY RAND() LIMIT 1))
ON DUPLICATE KEY UPDATE id=id;
Backup
L’une des fonctionnalités clés de l’operator MariaDB est sa capacité à générer des sauvegardes en fonction des paramètres définis
dans le manifeste de la ressource personnalisée Backup.
apiVersion: k8s.mariadb.com/v1alpha1
kind: Backup
metadata:
name: backup
namespace: mdb-demo
spec:
mariaDbRef:
name: mariadb
inheritMetadata:
annotations:
database.myorg.io: mariadb
podMetadata:
labels:
sidecar.istio.io/inject: "false"
serviceAccountName: backup
storage:
persistentVolumeClaim:
resources:
requests:
storage: 100Mi
accessModes:
- ReadWriteOnce
args:
- --single-transaction
- --all-databases
- --verbose
schedule:
cron: "*/1 * * * *"
suspend: false
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 512Mi
affinity:
# antiAffinityEnabled = false if the cluster only has one node
antiAffinityEnabled: false
Restore
Une fois la sauvegarde terminée, vous pouvez extraire le fichier SQL depuis le PVC utilisé par le pod de sauvegarde
ou directement depuis l’emplacement de stockage désigné.
L’operator inclut une ressource personnalisée nommée Restore, spécialement conçue pour exploiter les sauvegardes et restaurer les données.
apiVersion: k8s.mariadb.com/v1alpha1
kind: Restore
metadata:
name: restore
namespace: mdb-demo
spec:
mariaDbRef:
name: mariadb
backupRef:
name: backup
inheritMetadata:
annotations:
database.myorg.io: mariadb
podMetadata:
labels:
sidecar.istio.io/inject: "false"
serviceAccountName: restore
args:
- --verbose
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 512Mi
affinity:
# antiAffinityEnabled = false if the cluster only has one node
antiAffinityEnabled: false
Migration
L'Operator MariaDB vous permet de déployer une instance MariaDB à partir d’un fichier de sauvegarde.
Si vous préférez initialiser la base de données à l’aide d’un fichier SQL, cela est également possible en suivant le processus de migration ci-dessous.
Cette documentation se concentre sur l’utilisation d’un stockage compatible S3 (comme MinIO ou AWS S3). Si vous utilisez un autre type de stockage, veuillez consulter la documentation officielle de l’Operator.
1. Génération du fichier de sauvegarde sql
Utilisez mariadb-dump ou un outil équivalent pour exporter la base.
Le nom du fichier doit suivre le format suivant :
backup.[date_time_iso_8601].sql
mariadb-dump --user=${MARIADB_USER} --password=${MARIADB_PASSWORD} \
--host=${MARIADB_HOST} --port=${MARIADB_PORT} --single-transaction \
--events --routines --all-databases > ${PATH}/${BACKUP_NAME}
2. Export du fichier vers un stockage S3 ou MinIO
MinIO
mc alias set [ALIAS] [HOSTNAME] [ACCESS_KEY] [SECRET_KEY]
mc cp /[chemin]/[nom_du_fichier] myminio/[bucket]/[chemin_bucket]/[nom_du_fichier]
S3
aws s3 cp --endpoint-url [endpoint_url] /[chemin]/[nom_du_fichier] s3://[bucket]/[chemin_bucket]/[nom_du_fichier]
3. Utilisation du fichier
Créez une ressource personnalisée (CR) pour déployer l’instance MariaDB à partir du fichier de sauvegarde.
kind: MariaDB
metadata:
name: mariadb
namespace: mdb-demo
spec:
rootPasswordSecretKeyRef:
name: mariadb
key: password
storage:
size: 1Gi
bootstrapFrom:
s3:
bucket: backups
prefix: mariadb/
endpoint: https://xxx.fr
region: s3
accessKeyIdSecretKeyRef:
name: aws
key: access-key-id
secretAccessKeySecretKeyRef:
name: aws
key: secret-access-key
targetRecoveryTime: 2024-08-26T12:24:34Z
Ce manifest va produire deux pods : l’un pour l’instance MariaDB vide, et l’autre pour le pod de restauration,
qui utilisera le fichier de sauvegarde afin de peupler la base de données.
Réplication
La réplication MariaDB permet de créer des copies de votre base de données afin d’améliorer les performances, la scalabilité et la disponibilité.
MariaDB propose un proxy de base de données optionnel nommé MaxScale, qui s’intercale entre votre application et les serveurs MariaDB. Il offre des fonctionnalités avancées telles que :
- Répartition de charge (load balancing)
- Gestion automatique des basculements (failover)
- Routage des requêtes
- Supervision des instances
Architecture Active-Passive (réplication Master-Slave)
Dans une configuration active-passive, un nœud joue le rôle de maître et gère toutes les opérations d’écriture, tandis qu’un ou plusieurs nœuds esclaves répliquent les données du maître et prennent en charge les opérations de lecture. Composants :
- Nœud maître : gère les opérations d’écriture (INSERT, UPDATE, DELETE)
- Nœuds esclaves : répliquent les données du maître et gèrent les lectures (SELECT)
Avantages :
- Amélioration des performances en lecture grâce à la répartition des requêtes
- Gestion simplifiée du basculement (promotion d’un esclave en maître en cas de panne)
Exemples de fichiers :
- mariadb_replication.yaml
- mariadb_replication_maxscale.yaml
Architecture Active-Active (cluster Galera)
Dans une configuration active-active, tous les nœuds du cluster sont des maîtres capables de gérer à la fois les lectures et les écritures. Les modifications sont synchronisées en temps réel entre tous les nœuds.
Composants :
- Nœuds du cluster Galera : chaque nœud peut traiter des lectures et des écritures. La réplication est synchrone entre les nœuds.
Avantages :
- Haute disponibilité sans point de défaillance unique
- Meilleure tolérance aux pannes et répartition de la charge
Exemples de fichiers :
- mariadb_galera.yaml
- mariadb_galera_maxscale.yaml
Conclusion
Cet opérateur simplifie le déploiement et la gestion de MariaDB dans un cluster Kubernetes. Il automatise de nombreuses tâches telles que le déploiement, la sauvegarde et la restauration, facilitant ainsi la fiabilité et les performances de votre base de données.
Pour plus d’exemples et d’instructions détaillées, veuillez consulter la documentation officielle.