To put it simply, a StatefulSet should be used to govern one or more related pods that need to track state in some way. A StatefulSet would be what you use instead of a Deployment.
StatefulSets are a particularly cool implementation detail among Kubernetes workload APIs. It works very similarly to a Deployment, but it has additional constraints that it must apply to ensure that its pods are both stable and ordered. In other words, the pods in a StatefulSet must be consistently accessible via unique network identifiers instead of IP addresses and they must have a graceful and ordered way of deploying and scaling. Let's take a look at how this is all accomplished.
StatefulSets depend on the implementation of a Service, currently, to map network identities to pods. The service definition itself is, unfortunately, not created by the StatefulSet, but it isn't too difficult to add into your manifest. Here's an example of a service definition that can be used for a StatefulSet:
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx
This service will be referenced by the Stateful set under
.spec.template.metadata.labels. This will allow the StatefulSet to make use of the service for mapping to the pods. But the main reason I wanted to share it is to express how similar it is to the services you are already familiar with.
Deploying and Scaling
While there are some caveats, these are pretty cut and dry. Here are the highlights:
- Pods are created in a sequential order. (Think of a stack)
- Pods are terminated in reverse order. (Like popping off the stack)
- Scaling up or down can only happen if all previous pods are in the
Readystates. (We can't push onto nor pop off of the stack unless everything is completely healthy and capable of serving requests – i.e. all data has been cloned in the case of a database)
- A pod cannot be terminated unless it is the oldest one (Again, like popping off a stack)