StatefulSet vs. Deployment: differences and use cases
Compare Kubernetes StatefulSets and Deployments, including identity, storage, scaling, rollout behavior, and common use cases.
StatefulSet vs. Deployment: differences and use cases
Compare Kubernetes StatefulSets and Deployments, including identity, storage, scaling, rollout behavior, and common use cases.
Not every replicated workload is stateless. Deployments assume pods can be replaced freely. StatefulSets give pods stable identity and storage semantics for workloads that care about order, names, and durable state.
Choose wrong and the symptoms are ugly: data loss, broken clustering, stuck rollouts, or services that seem fine until the first restart.
What is a Deployment in Kubernetes?
A Deployment is a Kubernetes resource object that provides declarative updates for pods that encapsulate application containers. A Deployment represents a number of identical pods without unique IDs, while specifying the pods' desired state and attributes. Deployments are typically used to autoscale the number of pod replicas, perform controlled rollouts for application code, and perform rollbacks when necessary.
Kubernetes administrators rely on Deployments to manage a containerized application's lifecycle by defining the number of pods to be deployed, the image to be used for the application, and how to perform code updates. Kubernetes deployments help automate repeatable application updates, subsequently reducing the effort, time, and number of errors associated with manual updates.
Components of a Kubernetes Deployment
The primary components used to create and apply a Deployment to a cluster include:
- Deployment template: This is a JSON or YAML configuration file that is used to define the
Deployment's configuration specification. The Kubernetes Deployment controller relies on the
desired state described in the Deployment template to create, update, and scale pods. The JSON or
YAML file is static, and it includes a pod template that defines what each pod should look like,
as well as other common parameters, such as:
- Number of pod replicas
- Name of the image running in the pods
- Deployment's image tag
- Secrets, ConfigMaps, and other settings injected into the pod
- Service labels
- Service: Defines a single endpoint that is used to enable network access and expose workloads running on the pods within the Deployment. A service is a REST object that points to the Deployment pods and includes a policy to access them.
- Persistent Volume: Allows pods within the Deployment to access a portion of node storage to store data.
Deployment configuration manifest
Consider a static YAML file for a Kubernetes deployment named darwin-deployment.yaml with the following specifications:
apiVersion: apps/v1
kind: Deployment
metadata:
name: darwin-deployment
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2
maxUnavailable: 1
selector:
matchLabels:
app: darwin-app
replicas: 3
template:
metadata:
labels:
app: darwin-app
spec:
containers:
- name: web-app
image: novice
volumeMounts:
- name: counter
mountPath: /app/
volumes:
- name: darwin-volume
persistentVolumeClaim:
claimName: darwin-volume-claimThe above static file represents a Deployment named darwin-deployment that deploys three replicas of a pod to encapsulate containers running the novice image workload. The pods are attached to the darwin-volume-claim PersistentVolumeClaim with a specification similar to:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: darwin-volume-claim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Mi
storageClassName: defaultTo execute the Deployment within the cluster, it should be exposed using a service, such as the NodePort service, specified by the service.yaml file below:
apiVersion: v1
kind: Service
metadata:
name: darwin-service
spec:
ports:
- name: http
port: 80
nodePort: 30080
selector:
name: darwin-app
type: NodePort
To deploy the application, the Deployment, volume claim, and service are all applied to the cluster using the following commands:
$ kubectl apply -f service.yaml
$ kubectl apply -f darwin-volume-claim.yaml
$ kubectl apply -f darwin-deployment.yamlDiscovering Deployment details
Administrators can use the kubectl command to discover details of the Deployment and the pods they control. To check for the successful creation of the deployment, run the command:
$ kubectl get deploymentsTo check for the pods automatically created by the deployment, run the command:
$ kubectl get podsScaling deployments
The 'kubect'l command can also be used to scale the number of pods with changing patterns of an application load. To increase the number of pods for darwin-deployment to 5, run the command:
$ kubectl scale deployment/darwin-deployment --replicas=5Kubernetes deployment strategies
Kubernetes supports multiple rollout strategies for pod deployments. These include:
- Recreate: Simultaneously terminates and replaces all pods running the old version of the application with new pods.
- Ramped: Rolls out new application versions while terminating the old pods.
- Rolling update: Replaces old pods with new ones, one-by-one, with zero downtime.
- Canary deployment: Replaces a subset of existing pods with new ones, keeping both versions running, and then rolls out the new version to more pods if the test deployment is a success.
What is a StatefulSet in Kubernetes?
A StatefulSet is a Kubernetes resource object that manages a set of pods with unique identities. By assigning a persistent ID that is maintained even if the pod is rescheduled, a StatefulSet helps maintain the uniqueness and ordering of pods. With unique pod identifiers, administrators can efficiently attach cluster volumes to new pods across failures.
Although the StatefulSet controller deploys pods using similar specifications, pods are not interchangeable. As a StatefulSet does not create a ReplicaSet, the pod replicas cannot be rolled back to previous versions. StatefulSets are typically used for applications that require persistent storage for stateful workloads, and ordered, automated rolling updates.
Components of a Kubernetes StatefulSet configuration manifest
A Kubernetes StatefulSet configuration comprises the following:
- StatefulSet: The template that defines pod selectors and replicas of containers that will run on the pods.
- Headless service: The network domain controller that allows clients to connect with the pods using a DNS entry.
- Volume claim template: The template specification that allows administrators to provision stateful storage using persistent volumes.
StatefulSet configuration manifest
Consider a StatefulSet configuration named statefulset.yaml with the following specification:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: darwin
spec:
selector:
matchLabels:
app: darwin-app
serviceName: "darwin-set"
replicas: 3
template:
metadata:
labels:
app: darwin
spec:
containers:
- name: darwin-app
image: novice
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /var/log
volumes:
- name: darwin-volume
persistentVolumeClaim:
claimName: darwin-claimThe above StatefulSet can be attached to a PersistentVolume named darwin-claim.yaml as follows:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: darwin-claim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1GiTo expose the StatefulSet via a headless service named darwin-service.yaml, the following configuration can be used:
apiVersion: v1
kind: Service
metadata:
name: darwin
labels:
app: darwin #should match .spec.metadata.app in the statefulset template
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: darwinAll the above configurations can be applied to the cluster using the kubectl apply command, as follows:
$ kubectl apply -f statefulset.yaml
$ kubectl apply -f darwin-claim.yaml
$ kubectl apply -f darwin-service.yamlThe above commands create three pod replicas with ordered identities.
Discovering StatefulSet details
Pods within the StatefulSet can be verified with the get pods command:.
$ kubectl get podsKubernetes Deployment vs. StatefulSet: how to choose
The table below shows the primary differences between a StatefulSet and a Deployment:
Aspect | Deployment | StatefulSet Data persistence | Stateless | Stateful Pod name and identity | Pods are assigned an ID that consists of the deployment name and a random hash to generate a temporarily unique identity | Each pod gets a persistent identity consisting of the StatefulSet name and a sequence number Interchangeability | Pods are identical and can be interchanged | Pods in a StatefulSet are neither identical nor interchangeable Behavior | A pod can be replaced by a new replica at any time | Pods retain their identity when rescheduled on another node Volume claim | All replicas share a PVC and a volume | Each pod gets a unique volume and PVC Allowed volume access mode(s) | ReadWriteMany and ReadOnlyMany | ReadWriteOnce Pod interaction | Requires a service to interact with the pods | The headless service handles pod network identities Order of pod creation | Pods are created and deleted randomly | Pods are created in a strict sequence and cannot be deleted randomly
When to use
A StatefulSet is better suited to stateful workloads that require persistent storage on each cluster node, such as databases and other identity-sensitive workloads. A Deployment, on the other hand, is suitable for stateless workloads that use multiple replicas of one pod, such as web servers like Nginx and Apache.
This practical scenario demonstrates how a StatefulSet differs from a Deployment:
Consider a web app that uses a relational database to store data. When traffic to the application increases, administrators intend to scale up the number of pods to support the workload. A straightforward approach is simply to change the replica count within the Deployment's configuration manifest; then the Deployment controller will take care of scaling. Since new pod replicas are assigned the same set of ConfigMaps and environment variables when starting, they communicate with the backend the same way as the original pod, retaining the user experience for incoming traffic.
Similar to the web servers, the relational database may also need to be scaled up to meet the increased workload. Since the master and replica pods need to implement a leader-follower pattern, the pods of the database cannot be created or deleted randomly. In addition, while each pod needs to sync its data with the previous pod, it retains its own copy of the data stored. In such an instance, a StatefulSet helps create the database pods in an ordered sequence where every new pod acquires its copy of data from the last pod generated. If a pod fails, the StatefulSet controller automatically deploys new pod replicas incrementally with the same identity and attaches them to the same PVC.
Use cases
StatefulSet | Deployment Stateful workloads that require persistent storage on each cluster node | Stateless workloads such as web servers Ideal for key-value stores or database systems | For balancing requests between replicas Assigning ordered, unique identities | To automatically scale (creation/termination) pod replicas of a cluster For gradual rollouts | For controlled rollout and rollbacks Deploy new pod replicas incrementally | For deploying new pods with similar environment variables and ConfigMaps
Conclusion
Use Deployments for stateless replicated services. Use StatefulSets when identity, ordering, and persistent storage matter. The distinction is not academic; it changes how Kubernetes creates, names, updates, and recovers pods.
For Polyaxon users, this matters around supporting services and platform infrastructure. Training jobs and model services have different lifecycles, and the Kubernetes primitive should match the lifecycle instead of fighting it.