Run 3 - Persistance
Quickstart : Installation et Configuration de Longhorn pour la Gestion des Volumes Persistants dans Kubernetes
Ce TP vous guide à travers l'installation et la configuration de Longhorn pour la gestion des volumes persistants dans un cluster Kubernetes, en utilisant des disques montés en loopback.
Étape 1 : Préparer des disques en loopback
Créer des fichiers de disque
dd if=/dev/zero of=/var/lib/longhorn-disk-a bs=10M count=2
dd if=/dev/zero of=/var/lib/longhorn-disk-b bs=10M count=2Créer des devices loopback
losetup /dev/loop10 /var/lib/longhorn-disk-a
losetup /dev/loop11 /var/lib/longhorn-disk-bFormater les disques
mkfs.ext4 /dev/loop10
mkfs.ext4 /dev/loop11Créer des points de montage
mkdir /mnt/longhorn-disk-a /mnt/longhorn-disk-b
Monter les disques
mount /dev/loop10 /mnt/longhorn-disk-a
mount /dev/loop11 /mnt/longhorn-disk-b
Étape 2 : Installer Longhorn via Helm
Ajouter le dépôt Helm de Longhorn
helm repo add longhorn https://charts.longhorn.io
helm repo updateInstaller Longhorn
helm install longhorn longhorn/longhorn --namespace longhorn-system --create-namespace
Étape 3 : Configurer les volumes persistants
Définir un PersistentVolume (pv.yaml)
apiVersion: v1
kind: PersistentVolume
metadata:
name: longhorn-pv-a
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: longhorn
hostPath:
path: /mnt/longhorn-disk-a
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: longhorn-pv-b
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: longhorn
hostPath:
path: /mnt/longhorn-disk-bAppliquer la configuration
kubectl apply -f pv.yaml
Définir un PersistentVolumeClaim (pvc.yaml)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: longhorn-pvc-a
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 2MiAppliquer la configuration
kubectl apply -f pvc.yaml
Étape 4 : Utiliser les volumes persistants dans un pod
Définir un Pod utilisant les PVCs (pod.yaml)
apiVersion: v1
kind: Pod
metadata:
name: longhorn-test-pod
spec:
containers:
- name: longhorn-test-container
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- mountPath: "/data-a"
name: longhorn-volume-a
volumes:
- name: longhorn-volume-a
persistentVolumeClaim:
claimName: longhorn-pvc-aAppliquer la configuration
kubectl apply -f pod.yaml
La persistance de données : un sujet complEx: ### Historique des technologies de mise à disposition de volumes sur le réseau
Les technologies de mise à disposition de volumes sur le réseau ont évolué considérablement au fil des décennies.
Au début, les systèmes Unix utilisaient NFS (Network File System) pour permettre le partage de fichiers entre machines sur un réseau local.
Ensuite, les systèmes d'exploitation comme Windows ont adopté SMB/CIFS (Server Message Block/Common Internet File System) pour des fonctionnalités similaires.
Avec le temps, des solutions plus robustes et distribuées comme iSCSI (Internet Small Computer Systems Interface) ont émergé, permettant de connecter des disques distants via TCP/IP.
L'avènement des technologies de virtualisation et des conteneurs a conduit à des solutions de stockage distribuées telles que Ceph et GlusterFS, qui offrent une haute disponibilité et une évolutivité accrue.
Kubernetes a standardisé l'intégration de ces solutions via les CSI (Container Storage Interface) et les plugins de stockage, facilitant ainsi la gestion des volumes persistants dans des environnements cloud-native.
Difficultés de la persistance dans les systèmes distribués
Dans les systèmes distribués, la mise à disposition de block devices over network pose plusieurs défis.
L'architecture d'une solution de stockage de disque sur le réseau répond à des contraintes logiques, pratiques et matérielles.
- Acquittements d'écriture : Choisir entre les acquittements synchrones (garantissent la persistance avant de répondre) et asynchrones (répondent avant que les données ne soient persistées) pour un équilibre entre performance et sécurité.
- Redondance de données : Utiliser des techniques de redondance comme le mirroring ou l'EC (Erasure Coding) pour garantir la résilience et la disponibilité des données, comme dans Ceph.
- Gestion de quorum : Implémenter un système de quorum pour garantir la cohérence des données en cas de pannes de nœuds ou de réseaux.
- Scalabilité : Assurer la capacité d'ajouter ou de retirer des nœuds sans interrompre le service pour répondre aux besoins de stockage croissants.
- Monitoring et gestion proactive : Intégrer des outils de surveillance et d'alerting pour détecter et résoudre rapidement les problèmes de performance ou de défaillance matérielle.
- Sécurité des données : Mettre en place des mécanismes de chiffrement pour les données en transit et au repos pour protéger contre les accès non autorisés.
- Automatisation des backups : Intégrer des solutions automatisées pour la sauvegarde régulière des données afin d'assurer la récupération en cas de perte de données.
- Gestion des snapshots : Utiliser des snapshots pour permettre des restaurations rapides et minimiser les temps d'arrêt en cas de corruption ou de perte de données.
La maintenance pratique inclut les aspects suivants :
- Backups : Sauvegarder les données de manière régulière et fiable pour prévenir les pertes en cas de panne.
- Monitoring des disques : Surveiller l'état et les performances des disques pour détecter et anticiper les problèmes.
- Changement matériel défaillant : Remplacer rapidement et efficacement les composants matériels défaillants sans interruption majeure du service.
- Accroissement de la capacité : Augmenter la capacité de stockage de manière transparente et sans affecter les applications en cours d'exécution.
Comparaison de solutions de stockage réseau
Critère | NFS | GlusterFS | Ceph | Longhorn |
---|---|---|---|---|
Acquittements d'écriture | Asynchrones | Asynchrones | Synchrones/Asynchrones (configurable) | Synchrones/Asynchrones (configurable) |
Redondance de données | Non | Réplication | Réplication, Fragmentation | Réplication |
Gestion de quorum | Non | Oui | Oui | Non |
Scalabilité | Limitée | Haute | Très haute | Haute |
Chiffrement | Non (doit être ajouté séparément) | Oui (TLS pour transport) | Oui (chiffrement au repos et en transit) | Oui (TLS pour transport) |
Backups et snapshots | Non natif (doit être ajouté) | Oui | Oui | Oui |
Conclusion
Ce tableau compare les solutions de stockage réseau en termes d'acquittements d'écriture, de redondance de données, de gestion de quorum, de scalabilité, de chiffrement, et de capacités de backups et de snapshots, permettant de choisir la solution la mieux adaptée en fonction des besoins spécifiques.
Solutions Kubernetes
Kubernetes propose plusieurs mécanismes pour résoudre ces problèmes de persistance :
Plugins de stockage
Kubernetes utilise des plugins de stockage pour intégrer différentes solutions de stockage.
La norme des plugins de stockage pour Kubernetes est appelée Container Storage Interface (CSI).
La documentation est disponible sur le site officiel de Kubernetes.
CSI permet l'intégration de solutions de stockage externes avec Kubernetes via des drivers.
Cela fonctionne en déployant des plugins CSI dans le cluster Kubernetes, qui communiquent avec les systèmes de stockage sous-jacents.
Pour ajouter un plugin CSI, vous devez déployer les composants nécessaires (driver CSI) en utilisant des fichiers de configuration YAML spécifiques au plugin choisi.
Storage Class
Les Storage Classes définissent les types de stockage disponibles et leurs caractéristiques (performances, résilience, etc.).
Pour associer une StorageClass avec un plugin Container Storage Interface (CSI), on spécifie le provisioner CSI dans la définition de la StorageClass.
Pour offrir plusieurs qualités de disques, on crée plusieurs StorageClasses avec des paramètres variés tels que la taille minimale, la vitesse (IOPS), et le type de disque (SSD, HDD).
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-ceph
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
csi.storage.k8s.io/fstype: ext4
csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
size: 10Gi
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
Cette configuration utilise un plugin CSI pour provisionner des disques SSD rapides avec une taille minimale de 10Gi dans la zone spécifiée.
Persistent Volumes (PV)
Les administrateurs créent et gèrent les Persistent Volumes, qui représentent des unités de stockage abstraites.
Les PVs sont découplés du cycle de vie des pods, garantissant la persistance des données.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-fast-ceph
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteOnce
storageClassName: fast-ceph
csi:
driver: rook-ceph.rbd.csi.ceph.com
fsType: ext4
volumeAttributes:
clusterID: rook-ceph
pool: replicapool
imageFormat: "2"
imageFeatures: layering
volumeHandle: "unique-volume-id"
nodeStageSecretRef:
name: rook-csi-rbd-node
namespace: rook-ceph
controllerExpandSecretRef:
name: rook-csi-rbd-provisioner
namespace: rook-ceph
controllerPublishSecretRef:
name: rook-csi-rbd-provisioner
namespace: rook-ceph
Persistent Volume Claims (PVC)
Les utilisateurs créent des Persistent Volume Claims pour demander des ressources de stockage sans avoir à connaître les détails de l'infrastructure sous-jacente.
Les PVCs sont automatiquement associés aux PVs disponibles, en fonction des critères définis dans les Storage Classes.~~
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: fast-ceph
Quelques produits Kubernetes pour les stockages distribués
- OpenEBS : Solution de stockage en mode bloc.
- Longhorn : Solution de stockage en mode bloc.
- Rook : Orchestrateur pour diverses solutions de stockage (Ceph, Cassandra, NFS, etc.).
- MinIO : Système de stockage d'objets compatible S3.
Et les bases de données ?
Il existe plusieurs patterns d'architecture pour les bases de données dans Kubernetes
Voici quelques critères de choix:
- Performance et latence : Bases de données proches des applications pour réduire la latence.
- Isolation : Sécuriser les bases de données en les séparant des charges applicatives
- Scalabilité : Utiliser une plateforme capable d'accueillir rapidement de nouveaux noeuds
- Gestion et maintenance : Adapter les efforts de maintenance au budget et aux compétences internes.
Base de données managée
Utiliser des services managés comme AWS RDS, GCP Cloud SQL ou Azure Database.
Les bases de données sont gérées par le fournisseur de cloud, offrant haute disponibilité, sauvegarde automatique et scalabilité.
Base de données dans le namespace de l'application
Déployer dans le même namespace que l'application pour simplifier la gestion et le réseau.
Idéal pour des environnements de développement ou des applications de petite échelle, ex: Redis de cache local.
Base de données dans le cluster Kubernetes
Déployer des bases de données dans le même cluster Kubernetes mais dans des namespaces dédiés présente plusieurs avantages.
Cette approche offre une gestion centralisée des ressources tout en assurant l'isolation des applications et des bases de données.
Utiliser des taints et des tolerations permet de spécifier que les pods de la base de données doivent être déployés sur des nœuds physiques équipés de disques NVMe, offrant des performances de stockage élevées.
Cela optimise l'accès aux données pour des applications nécessitant des I/O intensifs, tout en maintenant une structure de gestion simplifiée et sécurisée au sein du cluster.
Base de données dans un cluster dédié
Avoir un cluster Kubernetes séparé exclusivement pour les bases de données.
Cela permet d'isoler les ressources et de réduire le risque de contention des ressources avec les applications.
Cette approche permet de standardiser les outils propres à la gestion des bases de données (operators, monitoring), d'avoir des noeuds physiques avec du matériel dédié dans une architecture scalable et de limiter les accès aux DBA.
Cette solution est en cloud privé celle qui permet de s'approcher des performances des services managés.
Base de données sur des VMs
Héberger les bases de données sur des machines virtuelles en dehors du cluster Kubernetes, tout en faisant tourner les applications dans Kubernetes.
Cette approche combine la flexibilité des VMs pour les bases de données avec les avantages de l'orchestration des conteneurs pour les applications.
C'est la solution classique et conservatrice (Pet vs. Cattle), qui permet d'obtenir de très bons niveaux de compartimentations, de performance, de maintenance, et de sécurité.
TP : Installation du MySQL Operator et d'une base de données MySQL avec réplication master-slave
Installer le MySQL Operator dans un cluster Kubernetes et déployer une instance de base de données MySQL avec réplication master-slave row-based.
Prérequis
- Un cluster Kubernetes fonctionnel
- kubectl installé et configuré
Étape 1 : Installer le MySQL Operator
Créer le namespace pour le MySQL Operator
kubectl create namespace mysql-operator
Installer le MySQL Operator en utilisant Helm
helm repo add presslabs https://presslabs.github.io/charts
helm repo update
helm install mysql-operator presslabs/mysql-operator --namespace mysql-operator
Étape 2 : Déployer une base de données MySQL avec réplication
Créer un fichier de configuration pour la base de données MySQL (mysql-cluster.yaml)
apiVersion: mysql.presslabs.org/v1alpha1
kind: MysqlCluster
metadata:
name: my-mysql-cluster
namespace: mysql-operator
spec:
replicas: 2
secretName: my-mysql-secret
mysqlVersion: "5.7"
masterSpec:
mysqlConf:
log-bin: mysql-bin
binlog-format: ROW
server-id: 1
log-slave-updates: true
replicaSpec:
mysqlConf:
server-id: 2
log-bin: mysql-bin
binlog-format: ROW
relay-log: relay-binCréer un secret pour le mot de passe MySQL
kubectl create secret generic my-mysql-secret --from-literal=ROOT_PASSWORD=root_password -n mysql-operator
Appliquer la configuration pour déployer le cluster MySQL
kubectl apply -f mysql-cluster.yaml
Étape 3 : Vérification du déploiement
Vérifier que le cluster MySQL est en cours d'exécution
kubectl get pods -n mysql-operator
Obtenir l'adresse IP du service MySQL
kubectl get svc -n mysql-operator