This topic describes the typical scenarios in which a StatefulSet is needed for creating a stateful service, and the procedure for how to use one.

Background information

A StatefulSet with N replicas is typically used for applications that require one or more of the following conditions:
  • A stable deployment order. Pods are deployed or expanded sequentially. That is, pods are deployed in the defined order of 0 to N-1. Before a new pod is deployed, all its predecessors must have been in Running and Ready status.
  • A stable scaling order. Pods are deleted in the defined order of N-1 to 0. Before a pod is deleted, all its predecessors must be all Running and Ready.
  • Stable and unique network identifiers. After a pod is rescheduled to any other node, its PodName and HostName remain unchanged.
  • Stable and persistent storage implemented through a PVC. After a pod is rescheduled, it can still access the same persistent data.

Method of using a StatefulSet service

Set volumeClaimTemplates to enable the system to automatically create a PVC and a PV.

This topic describes how to:
  • Deploy a StatefulSet service
  • Scale a StatefulSet service
  • Remove a StatefulSet service
  • Persistent storage of a StatefulSet service

Prerequisites

Deploy a StatefulSet service

Note volumeClaimTemplates: indicates a template of PVCs of the same type. If you set this field, the system creates PVCs according to the number of the replicas that are set for the StatefulSet service. That is, the number of the PVCs and that of the replicas are the same. Furthermore, these PVCs share the same settings except for names.
  1. Create a statefulset.yaml file.
    Note You need to set the storageClassName parameter to alicloud-disk-ssd, indicating that an Alibaba Cloud SSD cloud disk is used.
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: nginx
    ---
    apiVersion: apps/v1beta2
    kind: StatefulSet
    metadata:
      name: web
    spec:
      selector:
        matchLabels:
          app: nginx
      serviceName: "nginx"
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: disk-ssd
              mountPath: /data
      volumeClaimTemplates:
      - metadata:
          name: disk-ssd
        spec:
          accessModes: [ "ReadWriteOnce" ]
          storageClassName: "alicloud-disk-ssd"
          resources:
            requests:
              storage: 20Gi
  2. Run the following command to deploy a StatefulSet service:
    $ kubectl create -f statefulset.yaml
  3. Open another kubectl interface and run the following command to check that the pods are deployed in order:
    $ kubectl get pod -w -l app=nginx
    NAME         READY   STATUS    RESTARTS   AGE
    web-0        0/1     Pending   0          0s
    web-0        0/1     Pending   0          0s
    web-0        0/1     ContainerCreating    0          0s
    web-0        1/1     Running   0          20s
    web-1        0/1     Pending   0          0s
    web-1        0/1     Pending   0          0s
    web-1        0/1     ContainerCreating    0          0s
    web-1        1/1     Running   0          7s
  4. Run the following command to view the deployed pod:
    $ kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    web-0                         1/1     Running   0          6m
    web-1                         1/1     Running   0          6m
  5. Run the following command to view the PVCs:
    $ kubectl get pvc
    NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
    disk-ssd-web-0   Bound    d-2zegw7et6xc96nbojuoo   20Gi       RWO            alicloud-disk-ssd   7m
    disk-ssd-web-1   Bound    d-2zefbrqggvkd10xb523h   20Gi       RWO            alicloud-disk-ssd   6m

Scale a StatefulSet service

Scale out a StatefulSet service
  1. Run the following command to scale out the StatefulSet service to three pods:
    $ kubectl scale sts web --replicas=3
    statefulset.apps/web scaled
  2. Run the following command to view the pods:
    $ kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    web-0                         1/1     Running   0          34m
    web-1                         1/1     Running   0          33m
    web-2                         1/1     Running   0          26m
  3. Run the following command to view the PVCs:
    $ kubectl get pvc
    NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
    disk-ssd-web-0   Bound    d-2zegw7et6xc96nbojuoo   20Gi       RWO            alicloud-disk-ssd   35m
    disk-ssd-web-1   Bound    d-2zefbrqggvkd10xb523h   20Gi       RWO            alicloud-disk-ssd   34m
    disk-ssd-web-2   Bound    d-2ze4jx1zymn4n9j3pic2   20Gi       RWO            alicloud-disk-ssd   27m
Scale in a StatefulSet service
  1. Run the following command to scale in the StatefulSet service to two pods:
    $ kubectl scale sts web --replicas=2
    statefulset.apps/web scaled
  2. Run the following command to view the pod and verify that the number of pods is reduced to two:
    $ kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    web-0                         1/1     Running   0          38m
    web-1                         1/1     Running   0          38m
  3. Run the following command to view the PVCs and verify that the number of PVCs and PVs remains unchanged after the number of pods is changed:
    $ kubectl get pvc
    NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
    disk-ssd-web-0   Bound    d-2zegw7et6xc96nbojuoo   20Gi       RWO            alicloud-disk-ssd   39m
    disk-ssd-web-1   Bound    d-2zefbrqggvkd10xb523h   20Gi       RWO            alicloud-disk-ssd   39m
    disk-ssd-web-2   Bound    d-2ze4jx1zymn4n9j3pic2   20Gi       RWO            alicloud-disk-ssd   31m
Rescale out a StatefulSet service
  1. Run the following command to scale out the StatefulSet service to three pods:
    $ kubectl scale sts web --replicas=3
    statefulset.apps/web scaled
  2. Run the following command to view the pods:
    $ kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    web-0                         1/1     Running   0          1h
    web-1                         1/1     Running   0          1h
    web-2                         1/1     Running   0          8s
  3. Run the following command to view the PVCs and verify that the newly created pods still use the original PVCs and PVs after the StatefulSet service is scaled out:
    $ kubectl get pvc
    NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
    disk-ssd-web-0   Bound    d-2zegw7et6xc96nbojuoo   20Gi       RWO            alicloud-disk-ssd   1h
    disk-ssd-web-1   Bound    d-2zefbrqggvkd10xb523h   20Gi       RWO            alicloud-disk-ssd   1h
    disk-ssd-web-2   Bound    d-2ze4jx1zymn4n9j3pic2   20Gi       RWO            alicloud-disk-ssd   1h

Remove a StatefulSet service

  1. Run the following command to view the PVC that is used by the pod named web-1:
    $  kubectl describe pod web-1 | grep ClaimName
        ClaimName:  disk-ssd-web-1
  2. Run the following command to remove the pod named web-1:
    $ kubectl delete pod web-1
    pod "web-1" deleted
  3. Run the following command to view the pods and verify that the recreated pod shares the same name with the removed pod:
    $ kubectl get pod
    NAME                          READY   STATUS    RESTARTS   AGE
    web-0                         1/1     Running   0          1h
    web-1                         1/1     Running   0          25s
    web-2                         1/1     Running   0          9m
  4. Run the following command to view the PVCs and verify that the recreated pod uses the same PVC as removed the pod:
    $ kubectl get pvc
    NAME             STATUS   VOLUME                   CAPACITY   ACCESS MODES   STORAGECLASS        AGE
    disk-ssd-web-0   Bound    d-2zegw7et6xc96nbojuoo   20Gi       RWO            alicloud-disk-ssd   1h
    disk-ssd-web-1   Bound    d-2zefbrqggvkd10xb523h   20Gi       RWO            alicloud-disk-ssd   1h
    disk-ssd-web-2   Bound    d-2ze4jx1zymn4n9j3pic2   20Gi       RWO            alicloud-disk-ssd   1h
  5. Open a new kubectl interface and run the following command to view the process of pod removal and pod recreation:
    $ kubectl get pod -w -l app=nginx
    NAME    READY   STATUS    RESTARTS   AGE
    web-0   1/1     Running   0          102m
    web-1   1/1     Running   0          69s
    web-2   1/1     Running   0          10m
    web-1   1/1   Terminating   0     89s
    web-1   0/1   Terminating   0     89s
    web-1   0/1   Terminating   0     90s
    web-1   0/1   Terminating   0     90s
    web-1   0/1   Pending   0     0s
    web-1   0/1   Pending   0     0s
    web-1   0/1   ContainerCreating   0     0s
    web-1   1/1   Running   0     20s

Persistent storage of a StatefulSet service

  1. Run the following command to view the file in the /data path:
    $ kubectl exec web-1 ls /data
    lost+found
  2. Run the following command to create a statefulset file in the /data path:
    $ kubectl exec web-1 touch /data/statefulset
  3. Run the following command to view the files in the /data path:
    $ kubectl exec web-1 ls /data
    lost+found
    statefulset
  4. Run the following command to remove the pod named web-1:
    $ kubectl delete pod web-1
    pod "web-1" deleted
  5. Run the following command to view the files in the /data path and verify that the created file named statefulset has not been removed, indicating that data in the cloud disk can be stored persistently:
    $ kubectl exec web-1 ls /data
    lost+found
    statefulset