A StatefulSet, also known as a "stateful workload," differs from a deployment in that it maintains the state for the pod, making it ideal for scenarios such as databases, message queues, and distributed storage systems. This topic describes the characteristics of a StatefulSet, the steps to create one using the console and kubectl, and provides an example to verify the persistence of pod states.
Introduction to StatefulSet
Similar to a deployment, a StatefulSet ensures that a specified number of pods are running. However, a StatefulSet maintains the identity of pods through the following measures:
-
Ordered, fixed names: Each pod in a StatefulSet is named sequentially as <StatefulSet name>-<ordinal number>
. For instance, if the StatefulSet name is db-app, the pod names are db-app-0, db-app-1, etc. When a pod is deleted and recreated, the new pod inherits the original name.
-
Stable network identity: A StatefulSet typically requires a headless service (specified by spec.serviceName
) for association. Unlike a ClusterIP, this headless service does not provide load balancing but offers a fixed domain name for pods (when a DNS query is performed on the headless service, DNS returns the IP addresses of all matching pods). After specifying the headless service, the pod domain name format is <Pod name>.<Headless Service name>.<namespace>.svc.<ClusterDomain>
, for example, db-app-01.db-app.default.svc.cluster.local
. The domain name automatically resolves to the new pod after recreation.
-
Stable persistent storage: You can define a PVC template (specified by spec.volumeClaimTemplates
) within a StatefulSet. The StatefulSet creates a unique PersistentVolumeClaim (PVC) for each pod based on this template, and the PVC name is <PVC template name>-<Pod name>
. When a pod is deleted, the PVC is retained and automatically associated with a new pod that uses the same ordinal number.
These measures ensure that pods in a StatefulSet can inherit their original network and storage states after being recreated, allowing the application to resume operation from persistent data. For more information about StatefulSet, see the official documentation.
Create a StatefulSet
Create by using the console
Create by using kubectl
Log on to the ACK console. In the left-side navigation pane, click Clusters.
On the Clusters page, find the cluster that you want to manage and click its name. In the left-side pane, choose .
-
On the StatefulSet page, click Create Using Image.
-
On the Application Basic Information configuration wizard page, you can set the basic information for the application. Then click Next to proceed to the Container Configuration wizard page.
-
In the Container Configuration section, complete the basic configuration of the Image Name and Port for the container. Other parameters are optional. Keep the default settings. Then click Next to go to the Advanced Configuration wizard page. The image address is as follows.
Important
Before pulling this image, ensure the cluster has Internet access. If you selected Configure SNAT For VPC when creating the cluster, it already has Internet access. If not, see Enable Internet access for the cluster.
registry.cn-hangzhou.aliyuncs.com/acs-sample/nginx:latest

-
On the Advanced Configuration wizard page, configure access, scaling, scheduling, and tag annotations. In the Access Settings section, create a ClusterIPtype service, select Service Discovery Between Instances (headless Service), and click OK. Then, click Create at the bottom.

-
When creating a StatefulSet, the configuration items (Application Basic Information, Container Configuration, Advanced Configuration) on the console are the same as those for a deployment. For descriptions of other configuration items, see Configuration item description.
-
Copy the following YAML file and save it as statefulset.yaml. This YAML defines:
-
A headless service nginx
to provide a stable domain name.
-
A StatefulSet associated with hostPath
storage for the pod.
-
A LoadBalancer type service to expose the StatefulSet
externally, which is only used as a means to verify the Nginx page in this example.
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
clusterIP: None
selector:
app: nginx
ports:
- port: 80
name: http
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-test
namespace: default
labels:
app: nginx
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
ports:
- containerPort: 80
protocol: TCP
volumeMounts:
- name: node-dir-volume
mountPath: /tmp
volumes:
- name: node-dir-volume
hostPath:
path: /local_storage
type: DirectoryOrCreate
---
apiVersion: v1
kind: Service
metadata:
name: nginx-test-svc
namespace: default
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
protocol: TCP
type: LoadBalancer
-
Run the following command to create the StatefulSet and service.
kubectl apply -f statefulset.yaml
Expected output:
service/nginx created
statefulset.apps/nginx-test created
service/nginx-test-svc created
-
Run the following command to query the public IP address of the service.
Expected output:
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
-
Enter the public IP address of nginx (106.14.**.***
) into your browser to access the Nginx container of the workload. 
Verify the characteristics of StatefulSet
-
Run the following command to check the status of the pod.
kubectl get pod nginx-test-0
The expected output is as follows.
NAME READY STATUS RESTARTS AGE
nginx-test-0 1/1 Running 0 7m41s
-
Run the following command to delete the pod.
kubectl delete pod nginx-test-0
Expected output:
pod "nginx-test-0" deleted
-
Run the following command to check the status of the pod.
kubectl get pod nginx-test-0
The expected output is as follows. When the STATUS
is Running
, it indicates that the new pod is operating correctly and has inherited the original name.
NAME READY STATUS RESTARTS AGE
nginx-test-0 1/1 Running 0 20s