Statefulset et les apps stateful et les bases de données
Statefulset
Un StatefulSet est une ressource Kubernetes utilisée pour gérer des applications stateful, c'est-à-dire des applications qui ont un état ou des données persistantes. Contrairement aux Deployments et ReplicaSets, qui sont adaptés aux applications stateless (sans état), un StatefulSet offre des garanties spécifiques pour le déploiement et la gestion d'applications stateful, telles que les bases de données et les systèmes de fichiers distribués.
Voici un schéma simplifié d'un StatefulSet dans Kubernetes pour vous aider à visualiser ses composants clés :

-
Le "StatefulSet" est la ressource de niveau supérieur qui spécifie le nombre de réplicas désirés, le nom du service associé et le sélecteur pour les pods qu'il gère.
-
Les "Pods (Stateful)" sont créés et maintenus par le "StatefulSet". Ils sont les instances individuelles de l'application, et chaque pod a un nom unique. Les noms de pod suivent une convention de nommage basée sur l'index du pod, par exemple, "mon-statefulset-0," "mon-statefulset-1," etc.
-
Les cpnteneurs exécutent l'application. Chaque pod peut contenir un ou plusieurs conteneurs. Dans cet exemple, chaque pod contient un conteneur nommé "mon-conteneur" utilisant l'image "mon-image."
Le "StatefulSet" est utilisé pour gérer des applications stateful telles que les bases de données et les systèmes de fichiers distribués. Il garantit que chaque instance de l'application a un nom unique et fournit un mécanisme de déploiement, de mise à jour et de mise à l'échelle des réplicas stateful tout en maintenant la stabilité des noms de pods.
Ce schéma représente un StatefulSet simple avec trois réplicas de l'application "mon-app" et montre comment les noms de pods sont gérés de manière séquentielle avec des index numériques.
Exemples d'utilisation courants de StatefulSets c'est les bases de données : On monte un cluster cassandra avec 3 replicas.
Cassandra est un bon exemple d'application qui profite pleinement des caractéristiques des StatefulSets en Kubernetes, car chaque nœud doit avoir une adresse réseau stable et son propre stockage persistant:
- Sotrage class avec local-path-provisioner:
Staorage class: on va juste executer ce commande sans chercher à comprendre d'abord. Dans la suite, les pv/pvc seront trainté dans un autre chapitre.
Ça va nous permettre de créer des pv/pvc de test.
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.30/deploy/local-path-storage.yaml
- Statefulset de cassandra
apiVersion: v1
kind: Service
metadata:
name: cassandra
spec:
ports:
- port: 9042
name: cql
clusterIP: None # Service Headless pour permettre la découverte DNS
selector:
app: cassandra
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: cassandra
spec:
serviceName: "cassandra"
replicas: 3 # Nombre de réplicas
selector:
matchLabels:
app: cassandra
template:
metadata:
labels:
app: cassandra
spec:
containers:
- name: cassandra
image: cassandra:5.0.2 # Utiliser une version stable de Cassandra
ports:
- containerPort: 9042 # Port pour le CQL (Cassandra Query Language)
env:
- name: CASSANDRA_SEEDS
value: "cassandra-0.cassandra,cassandra-1.cassandra,cassandra-2.cassandra" # Liste des nœuds du cluster
- name: CASSANDRA_CLUSTER_NAME
value: "K8DemoCluster"
- name: CASSANDRA_DC
value: "DC1"
- name: CASSANDRA_RACK
value: "Rack1"
- name: CASSANDRA_ENDPOINT_SNITCH
value: "GossipingPropertyFileSnitch"
volumeMounts:
- name: cassandra-data
mountPath: /var/lib/cassandra
volumeClaimTemplates:
- metadata:
name: cassandra-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "local-path"
resources:
requests:
storage: 1Gi
Explications des Sections
-
Service Headless (clusterIP: None) : Permet la découverte DNS pour chaque pod Cassandra. Chaque instance aura un nom comme cassandra-0.cassandra, cassandra-1.cassandra, etc., qui reste constant même en cas de redémarrage.
-
CASSANDRA_SEEDS : Spécifie les nœuds initiaux (seed nodes) du cluster. Ces nœuds sont essentiels pour que les nouveaux nœuds puissent rejoindre le cluster. Ici, nous utilisons les trois premiers pods comme seeds.
-
StatefulSet avec Réplicas : Le nombre de réplicas est défini à 3, mais vous pouvez augmenter ce nombre si nécessaire. Grâce au StatefulSet, chaque réplique conserve sa propre identité réseau (cassandra-0, cassandra-1, etc.).
-
Volume Persistant : Le volumeClaimTemplates assure qu'un volume persistant est créé pour chaque pod, permettant à chaque nœud Cassandra de conserver ses données même en cas de redémarrage.
- Pour comprendre le service Headless, il faut voir le charpitre sur les services
- Appliquer le ficher
kubectl apply -f statefulset.yaml
# on attend 2 minutes
kubectl get sts,po,svc
# voir les logs
kubectl logs cassandra-0
kubectl logs cassandra-1
kubectl logs cassandra-2

- Vérifier l'état du cluster
La commande que vous avez déjà utilisée permet de vérifier l'état du cluster et de ses nœuds :
kubectl exec -it cassandra-0 -- nodetool status

- Vérifier les métriques de la base de données
Pour obtenir des informations sur l'activité de la base de données, notamment le nombre de requêtes et les délais de lecture/écriture :
kubectl exec -it cassandra-0 -- nodetool netstats

- Réplication et Topologie du Cluster
Pour afficher la répartition des données et les nœuds qui sont responsables de chaque "token" dans le cluster :
kubectl exec -it cassandra-0 -- nodetool ring

- Vérifier l'état des compactions
Cassandra effectue des opérations de "compaction" pour fusionner les fichiers de données. Pour surveiller l’état de la compaction :
Cela montre des statistiques sur les opérations de compaction en cours, leur durée et leur progression.
kubectl exec -it cassandra-0 -- nodetool compactionstats

- Vérification des tables et index
Pour afficher des informations sur les tables Cassandra et leurs index :
# Pour afficher des informations sur les tables Cassandra et leurs inde
kubectl exec -it cassandra-0 -- cqlsh -e "DESCRIBE TABLES"Commentaires
Aucun commentaire pour le moment.