StatefulSets - ii02735/learn-k8 GitHub Wiki
Un StatefulSet est un contrôleur pour les applications avec état (stateful) : il gère des Pods qui ont besoin d'une identité stable et d'un stockage stable.
Contrairement à un Deployment (des Pods interchangeables et anonymes), chaque Pod d'un StatefulSet est unique et reconnaissable :
- un nom stable et ordonné :
web-0,web-1,web-2… ; - une identité réseau stable : un nom DNS par Pod ;
- un stockage stable : chaque Pod possède son propre volume, conservé même après un redémarrage.
Pour les applications qui ne peuvent pas être anonymes :
- les bases de données (PostgreSQL, MySQL, MongoDB, Cassandra…) ;
- les files de messages (Kafka, RabbitMQ…) ;
- les systèmes distribués qui ont besoin d'une identité par instance ou d'un quorum (etcd, ZooKeeper, Elasticsearch…) ;
- toute application qui écrit des données sur disque et doit les retrouver après un redémarrage.
À l'inverse, une application sans état (API, frontend) se déploie avec un Deployment.
- Les Pods sont nommés de façon ordinale :
web-0,web-1,web-2… - Si un Pod est supprimé, il est recréé avec le même nom (et rejoint son volume).
- On associe au StatefulSet un Service headless (
clusterIP: None, référencé parserviceName). - Chaque Pod obtient alors un nom DNS stable :
web-0.web.<namespace>.svc.cluster.local
On peut donc adresser un Pod précis (ex. le primaire d'une base), ce qu'un Service classique ne permet pas.
-
volumeClaimTemplatesdemande un PVC par Pod, généré automatiquement :data-web-0,data-web-1… ⚠️ Ces PVC ne sont pas supprimés lorsque le Pod — ou même le StatefulSet — est supprimé. C'est voulu (protection des données), mais il faut les nettoyer à la main.
- Par défaut (
podManagementPolicy: OrderedReady), la création est séquentielle :web-0doit être Ready avant queweb-1ne soit créé, etc. - La suppression (ou la réduction) se fait en ordre inverse :
web-2d'abord. -
podManagementPolicy: Parallelcrée/supprime tous les Pods en même temps (utile quand l'ordre n'importe pas).
Un Service headless doit accompagner le StatefulSet :
apiVersion: v1
kind: Service
metadata:
name: web
spec:
clusterIP: None
selector:
app: web
ports:
- name: web
port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: web
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: app
image: nginx
ports:
- name: web
containerPort: 80
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi- Deployment : Pods interchangeables, noms aléatoires, pas de stockage propre, aucun ordre.
- StatefulSet : Pods identifiables (nom, DNS, volume), créés/supprimés dans l'ordre.
Note
Un StatefulSet garantit une identité, pas une haute disponibilité : la réplication et le failover (élection d'un primaire…) restent la responsabilité de l'application (ou d'un opérateur dédié).
- Lister les StatefulSets :
kubectl get statefulsets(oukubectl get sts) - Obtenir les détails :
kubectl describe sts web - Voir les Pods ordinaux :
kubectl get pods -l app=web - Voir les volumes :
kubectl get pvc(ex.data-web-0,data-web-1…) - Mettre à l'échelle :
kubectl scale statefulset web --replicas=5 - Suivre une mise à jour :
kubectl rollout status statefulset/web - Supprimer le StatefulSet (les PVC restent) :
kubectl delete statefulset web