StatefulSets (Pods with Persistent Volumes)
Like a Deployment, a StatefulSet manages Pods that are based on an identical container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier (UID) that it maintains across any rescheduling. It also provides guarantees on the ordering and uniqueness of the Pods. StatefulSets also require a headless service to manage network identities for pods. Each Pod gets a sticky network sub-domain and SRV record that does not change if a Pod is deleted and recreated.
You can see an example below where a Pod is deleted, but then recreated with the same
name using the StatefulSet spec.
kubectl get pods NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 3d web-1 1/1 Running 0 3d kubectl delete pod web-0 pod "web-0" deleted kubectl get pods NAME READY STATUS RESTARTS AGE web-0 0/1 ContainerCreating 0 7s web-1 1/1 Running 0 3d
As mentioned above, a headless service is required for StatefulSets, where the network type
clusterIP has a value of
None. This does not predefine an IP for the service.
apiVersion: v1 kind: Service metadata: name: nginx-service #Name of Service labels: app: nginx # Pod label spec: ports: - port: 8080 # Mapped port used by service name: web # Named port clusterIP: None # Headless service setting selector: app: nginx # Selector should match the name of the app being deployed as the Statefulset
Below is an example of a StatefulSet definition:
apiVersion: apps/v1 kind: StatefulSet metadata: name: web # Name of StatefulSet spec: selector: matchLabels: app: nginx # defines a set of pods to be managed by the StatefulSet serviceName: "nginx-service" # The name of the headless service replicas: 3 template: metadata: labels: app: nginx # This should be the same of selector:matchLabels:app spec: containers: # Container images with their corresponding settings - name: nginx image: bitnami/nginx:latest ports: - containerPort: 8080 name: web volumeMounts: - name: www mountPath: "/usr/share/nginx/html" securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "gp2-expand" # StorageClass name used to create PV resources: requests: storage: 4Gi # Storage resource request size
Please use StorageClass
gp2-expand to be able to expand PersistentVolumes in the future.
Once all pods are created for the StatefulSet, they have a unique identity based on the metadata name of the StatefulSet. The pods are named using the following: [StatefulSet_Name]-[Ordinal_Index] e.g. web-0
kubectl get pods NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 22m web-1 1/1 Running 0 22m web-2 1/1 Running 0 21m web-3 1/1 Running 0 21m web-4 1/1 Running 0 20m web-5 1/1 Running 0 20m web-6 1/1 Running 0 20m
All PersistentVolumeClaims would have all been created also. The PersistentVolumeClaims are named using the following: [VolumeClaim_Name]-[StatefulSet_Name]-[Ordinal_Index]
kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE www-web-0 Bound pvc-0ca662d1-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 29m www-web-1 Bound pvc-1cc800d2-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 28m www-web-2 Bound pvc-2abbbeb6-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 28m www-web-3 Bound pvc-40e2bc95-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 27m www-web-4 Bound pvc-4ebb8afd-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 27m www-web-5 Bound pvc-641f5a61-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 26m www-web-6 Bound pvc-6c2a187c-9299-11e9-b4c5-0a5b8815a91e 4Gi RWO gp2-expand 26m
If a Pod is deleted, it will be rescheduled, with the same name, and the corresponding above PersistentVolumeClaims will be attached. The Pod also has and will keep a network ID that persists through restarts.
If a StatefulSet is deleted, the PersistentVolumeClaims (PVCs) remain along with PersistentVolumes (PVs). PVCs and PVs have to be deleted separately.
Advisory note: Expanding Persistent Volumes
It is currently not possible to expand PVs using the StatefulSet template. There is a manual way to do this, which the Cloud Platform team can help with if required.