Contrairement aux Deployments, les StatefulSets conservent l'identité de chaque pod lors des redémarrages, ce qui en fait le choix idéal pour les bases de données, les files d'attente de messages et les systèmes de stockage distribués. Cette rubrique explique le fonctionnement des StatefulSets et comment en créer un dans Container Service for Kubernetes (ACK).
À l'issue de cette lecture, vous saurez :
Expliquer les trois garanties d'identité fournies par les StatefulSets
Créer un StatefulSet via la console ACK ou kubectl
Vérifier que les pods conservent leurs noms et identités réseau après suppression
Fonctionnement des StatefulSets
Un StatefulSet gère un nombre fixe de pods, à l'instar d'un Deployment. La différence réside dans l'attribution, par les StatefulSets, d'une identité stable et persistante à chaque pod, identité qui survit aux redémarrages et aux replanifications. Cette identité repose sur trois composants :
Noms de pods ordonnés
Les pods sont nommés selon le format <StatefulSet name>-<serial number>, en commençant par 0. Un StatefulSet nommé db-app avec deux réplicas crée les pods db-app-0 et db-app-1. Si un pod est supprimé puis recréé, il conserve le même nom.
Identité réseau stable
Associez un service headless au StatefulSet en définissant spec.serviceName sur le nom du service. Le service headless attribue à chaque pod un nom DNS stable au format suivant :
<pod name>.<headless Service name>.<namespace>.svc.<ClusterDomain>
Par exemple : db-app-01.db-app.default.svc.cluster.local
Contrairement à un service standard, un service headless n'équilibre pas la charge du trafic ; il renvoie directement les adresses IP de tous les pods backend pour les requêtes DNS. Lorsqu'un pod est recréé, son nom DNS se résout automatiquement vers la nouvelle adresse IP du pod.
Stockage persistant stable
Définissez un modèle de revendication de volume persistant (PVC) dans spec.volumeClaimTemplates. Le StatefulSet crée automatiquement un PVC distinct pour chaque pod, nommé <PVC template name>-<pod name>. Lors de la suppression d'un pod, son PVC est conservé. Lorsque le pod est recréé avec le même numéro de série, le PVC est automatiquement rattaché.
Ces trois garanties assurent conjointement qu'un pod recréé reprend exactement là où l'original s'est arrêté : même nom, même adresse DNS et mêmes données persistantes.
Pour consulter la spécification complète des StatefulSets, reportez-vous à la documentation StatefulSets.
Limitations
Avant d'utiliser les StatefulSets, tenez compte des points suivants :
Un service headless est requis. Vous devez créer le service headless vous-même ; ACK ne le crée pas automatiquement. Sans celui-ci, les pods ne disposent pas de noms DNS stables.
Les PVC ne sont pas supprimés avec le StatefulSet. La suppression d'un StatefulSet n'entraîne pas celle des PVC qu'il a créés. Nettoyez manuellement les PVC après la suppression d'un StatefulSet afin d'éviter des coûts de stockage imprévus.
La création et la suppression des pods s'effectuent de manière séquentielle. Par défaut, le pod
N+1ne démarre pas tant que le podNn'est pas en état Running et Ready. De même, le podN+1est arrêté avant le podN. Réduisez le StatefulSet à 0 avant sa suppression pour garantir un arrêt propre et ordonné.
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
-
Un cluster ACK avec accès au réseau public, permettant le tirage des images d'exemple. Pour configurer l'accès :
(Recommandé) Activer l'accès Internet pour un cluster ACK existant : créez une passerelle NAT publique pour le Virtual Private Cloud (VPC) hébergeant le cluster.
Attribuer des adresses IP publiques statiques aux nœuds : attribuez une adresse IP publique à chaque nœud exécutant des workloads.
Pour une création via kubectl, vous avez également besoin de :
kubectl connecté au cluster. Pour les instructions de configuration, consultez Obtenir le fichier kubeconfig d'un cluster et utiliser kubectl pour se connecter au cluster.
Créer un StatefulSet
Création depuis la console
Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.
Sur la page Clusters, cliquez sur le nom du cluster. Dans le volet latéral gauche, choisissez Workloads > StatefulSets.
Dans le coin supérieur gauche de la page StatefulSets, cliquez sur Create from Image.
Lors de l'étape Basic Information, configurez les paramètres de base de l'application. Cliquez sur Next.
-
Lors de l'étape Container, configurez Image Name et Port. Conservez les valeurs par défaut pour les autres paramètres. Pour Image Name, utilisez :
ImportantLe cluster doit avoir accès à Internet pour tirer cette image. Si vous avez conservé la valeur par défaut pour Configure SNAT for VPC lors de la création du cluster, l'accès Internet est déjà activé. Pour les clusters existants, consultez Activer l'accès Internet pour un cluster ACK existant.
registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latestCliquez sur Next.

-
Lors de l'étape Advanced, accédez à la section Access Control. Créez un service Cluster IP, sélectionnez Headless Service et cliquez sur OK. Ensuite, cliquez sur Create.

Les paramètres des étapes Basic Information, Container et Advanced sont identiques à ceux d'un Deployment. Pour plus de détails sur tous les paramètres, consultez Paramètres.
Création avec kubectl
-
Créez un fichier nommé
statefulset.yamlet collez-y le contenu suivant. Le manifeste définit trois ressources :Un service headless nommé
nginx, fournissant des noms DNS stables pour les podsUn StatefulSet nommé
nginx-testavec un volumehostPathmontéUn service LoadBalancer nommé
nginx-test-svc, utilisé pour vérifier l'accès au StatefulSet
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: clusterIP: None # Headless Service selector: app: nginx ports: - port: 80 name: http --- apiVersion: apps/v1 kind: StatefulSet # The workload type. metadata: name: nginx-test namespace: default # Change the namespace as needed. labels: app: nginx spec: serviceName: "nginx" # Specify the name of the headless Service you created. replicas: 2 # Specify the number of pods. selector: matchLabels: app: nginx template: # The pod configurations. metadata: labels: # The pod labels. app: nginx spec: containers: - name: nginx # The name of the container. image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 # The version of the NGINX image. ports: - containerPort: 80 # The port exposed by the container. protocol: TCP # Set the protocol to TCP or UDP. volumeMounts: - name: node-dir-volume # The volume name. The value must be the same as the volume name specified in the following volumes section. mountPath: /tmp # The mount path of the volume in the container. volumes: - name: node-dir-volume hostPath: path: /local_storage # The directory on the host that you want to mount as a volume. type: DirectoryOrCreate # If the specified directory does not exist, the system automatically creates the directory. --- apiVersion: v1 kind: Service metadata: name: nginx-test-svc namespace: default # Change the namespace as needed. labels: app: nginx spec: selector: app: nginx # The label used to match backend pods. ports: - port: 80 # The port provided by the Service in the cluster. targetPort: 80 # The port on which the application in the container listens (containerPort). protocol: TCP # The protocol. Default value: TCP. type: LoadBalancer # The Service type. Default value: ClusterIP. ClusterIP Services are accessible from within the cluster. -
Appliquez le manifeste :
kubectl apply -f statefulset.yamlSortie attendue :
service/nginx created statefulset.apps/nginx-test created service/nginx-test-svc created -
Récupérez l'adresse IP publique du service LoadBalancer :
kubectl get svcSortie attendue :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 172.16.**.*** <none> 443/TCP 4h47m nginx ClusterIP None <none> 80/TCP 1h10m nginx-test-svc LoadBalancer 172.16.**.*** 106.14.**.*** 80:31130/TCP 1h10m -
Ouvrez un navigateur et accédez à l'adresse IP externe (106.14..*) pour confirmer que le conteneur NGINX est accessible.

Vérifier les garanties du StatefulSet
Cette section démontre que lorsqu'un pod est supprimé, le StatefulSet le recrée avec le même nom, illustrant ainsi la garantie d'identité stable.
-
Vérifiez l'état du pod
nginx-test-0:kubectl get pod nginx-test-0Sortie attendue :
NAME READY STATUS RESTARTS AGE nginx-test-0 1/1 Running 0 7m41s -
Supprimez le pod :
kubectl delete pod nginx-test-0Sortie attendue :
pod "nginx-test-0" deleted -
Interrogez à nouveau le pod :
kubectl get pod nginx-test-0Sortie attendue :
NAME READY STATUS RESTARTS AGE nginx-test-0 1/1 Running 0 20sLe pod est de nouveau en cours d'exécution avec son nom d'origine
nginx-test-0. La valeurAGEest réinitialisée car il s'agit d'un nouveau pod, mais son nom et son numéro de série sont préservés.
Étapes suivantes
Pour résoudre les problèmes rencontrés lors de la création de workloads, consultez FAQ sur les workloads.
Pour résoudre les anomalies des pods, consultez Dépannage des pods.