Configuring Kubernetes StatefulSets for stateful applications

State in containers loses identity on restart: a queue, database, or storage goes down, and recovery takes hours. We configure Kubernetes StatefulSet turnkey: design the architecture, migrate data without downtime, and hand over runbooks. The result is predictable restarts and stable names instead of manual edits.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

StatefulSet Kubernetes: what breaks without stable identities

In a stateless world, a pod is disposable: it falls, is recreated, nothing lost. With stateful it's the opposite. The Kubernetes scheduler gives the pod a new name on each recreation, while the volume remains tied to the previous name.

The database comes up with an empty disk, the cluster cheerfully reports readiness, and only application logs show there is no data.

Stable pod identities are not decoration but a contract. mysql-0, mysql-1, mysql-2 are fixed names, each has its own PersistentVolumeClaim, and on restart the pod returns exactly to its volume.

Without this binding, disk failure or pod recreation turns into data loss on restart: the application starts, but the transaction history behind it is gone.

The second layer is the order in which replicas start. The replica with the primary role must come up and report readiness before the others; otherwise the secondaries enter a reconnection loop, and the service returns errors for the entire rollout period.

The order of starting and stopping replicas is set by the management policy, and this is exactly the knob that a regular Deployment controller lacks.

The third failure is noticed last. A volume lives in a specific availability zone; binding the volume to a node fixes this at the storage level.

A node fails — the pod is rescheduled to another zone, the volume cannot be mounted there, the pod hangs for days waiting, and the on-call engineer sorts this out manually through the event chain. Let's break down how this is closed by configuring StatefulSet.

What managed state handling delivers: measurable effects

A correctly described StatefulSet in Kubernetes returns a failed replica under the same name, with the same volume and the same role in the cluster.

The readiness probe does not let traffic through until the application has caught up with the replication log, so recovery happens without manual intervention and takes tens of seconds instead of hours of troubleshooting and disk rebinding.

The update proceeds one pod at a time — from the highest index to zero, with a readiness check at each step.

If the new version does not come up, the rollout stops at a specific replica and does not take down the whole cluster: the share of successful updates grows precisely because the failure is localized rather than spread across all instances.

A separate persistent volume per replica and a ban on running two pods with the same name simultaneously remove an entire class of failures: data loss on restart, a race for the same directory, a corrupted log after a node crash. These failures usually surface at the worst possible moment — at night or during peak load.

The startup and shutdown order is set declaratively, so the rollout is reproducible: the same result in staging and production, and a rollback is a return to the previous description and a repeat pass in reverse order.

The duration of downtime for planned maintenance is agreed in advance and is not discovered during an incident.

In total, this is not 'it became more convenient' but four verifiable metrics: recovery time, share of successful updates, an eliminated class of state-loss failures, and a predictable rollout.

StatefulSet Kubernetes deployment modes: comparison table

The choice of option comes down to three questions: where the data physically resides, who is responsible for its consistency, and what happens to the pod when it moves to another node.

StatefulSet provides a stable network name, startup order, and a separate volume for each replica via volumeClaimTemplates, but it does not determine the nature of the medium — that is set by the storage class and volume access mode.

Below are the alternatives that are actually chosen between when an application holds state: a queue, a database, a search index, or a session store.

Option When it fits Limitations
Local volume on a node Maximum data access speed is needed; the volume survives pod restart The volume is tied to the node: the pod will not move without data transfer; the storage class is configured for delayed binding
Network block volume, one replica per volume A database or queue with its own disk for each replica The volume is not shared between pods; every write goes over the network
Shared file volume for multiple pods Multiple replicas read and write the same directory Consistency and locking fall to the application; write speed is lower
Distributed storage inside the cluster Data copies are needed without an external service It consumes node resources and requires separate maintenance
External managed database Data safety is more important than cluster autonomy Part of the state leaves the cluster; access and backups are configured separately

The state management mode is set separately from the medium: podManagementPolicy determines whether replicas come up sequentially or in parallel, updateStrategy determines how the update proceeds, and a headless Service provides predictable names for communication between replicas.

These parameters are more important than disk choice when the application can assemble the cluster itself: it needs stable addresses and a guarantee that the next replica starts after the previous one is ready.

The limitation of an option almost always shows up during node failure: local volumes require manual or operator-driven transfer, shared ones require application-side consistency, and an external database requires a separate access environment.

That is why the analysis starts not with choosing a storage class, but with how the application behaves when one replica is lost.

Work sequence: audit, design, migration, validation, handover

A cluster audit begins with inventory: which applications actually store state, which one needs a stable network address and startup order, and which will survive a regular controller without guarantees.

Next we record the load profile and data durability requirements — the storage class, number of replicas, and zone placement design depend on this.

  1. Inventory and cluster audit. We collect a list of stateful applications, current controllers, volume claims, available storage classes, quotas, and the availability zone breakdown.
  2. Deployment design. We describe the target StatefulSet: a headless Service for predictable DNS names, volumeClaimTemplates with the required storage class, pod startup order, and placement rules across nodes and zones.
  3. Data transfer and first launch. We verify the key property: when a pod is recreated, its volume and network name are preserved, and the application comes up on the same data without manual operations.
  4. High availability configuration. Readiness and liveness probes, pod disruption budget, resource limits, update one pod at a time — so that quorum is not lost mid-rollout.
  5. Failover testing. We take nodes and zones down on schedule, remove a node from quorum, measure leader re-election time and recovery from backup.
  6. Handover to operations. We hand over the design, standard and emergency operation procedures, alerts on volume and replication status, and scaling limits.

Each stage is closed with an artifact — an inventory table, a design, a rehearsed rollback scenario — so the next step relies on something verified, not on an assumption.

What the customer receives: designs, manifests, procedures

We hand over not a 'working cluster' but a set of artifacts that your team can use to change configuration, deploy an environment from scratch, and bring data back after a failure.

Everything is stored in a repository with a change history: you can see who changed a parameter and why, and rolling back to the previous revision takes minutes.

  • StatefulSet manifests: a headless Service for stable network names, volume templates with disk claims, node placement rules, readiness and liveness probes, a pod disruption budget, an update strategy with phased rollout capability, and a data retention policy when a resource is deleted.
  • Parameterized environment templates: development, pre-production, and production are assembled from a single set of descriptions, with differences only in variable values, without manually copying configurations.
  • Interaction designs: how instances find each other by persistent names, how replication between leader and follower nodes is arranged, in what order pods start, and where application connection points are.
  • Access policies: roles and service accounts with minimal sufficient permissions, network isolation rules, and procedures for storing and rotating secrets and certificates.
  • Backup procedure: a schedule of volume snapshots and consistent dumps, retention periods, recovery validation in a separate environment, and the target recovery time after an incident.
  • Team instructions: how to scale the cluster, replace a failed instance, update an image, roll back, and what to do when a node is lost — step-by-step scenarios with the expected result at each step.
  • Observability kit: dashboards and alerts on replication lag, free space on volumes, number of ready instances, and startup duration, so degradation is visible before service failure.

Case study: migrating queues and storage to stable identities

Before: identity was lost on every restart

Queues and two storage services ran as regular Deployments: pods received random names, and volumes were attached in startup order.

When evicted to another node, a pod could not reclaim its volume, while a neighboring pod came up on someone else's — the RabbitMQ broker started with out-of-sync queues and duplicate messages.

Recovery took an average of 40 minutes and six manual operations: detach the stuck volume, wait for it to be released, bring up the pod in the right order, and reconcile mirrors.

This recurred twice a month, and any node maintenance turned into a night watch for the on-call engineer.

What was changed

Queues and storage were migrated to StatefulSet with a headless Service: a pod receives a predictable name and DNS record, and the volume is created from a template and remains bound to its replica.

Startup and shutdown order became strict — first the leader comes up, then the followers, and eviction does not begin until the replica has confirmed readiness.

We added a pod disruption budget and a readiness probe that looks at storage write availability rather than process liveness.

After: metrics

  • Replica recovery — from 40 minutes to 4 minutes, with no manual steps.
  • Failures due to lost volumes — zero over six months of observation.
  • Node maintenance happens during business hours: no nighttime on-call calls.

The cause is gone, not the symptom: identity substitution no longer reproduces, so failures that recurred every month no longer require quick treatment.

What to do if persistent volumes are already deployed manually?

Migrating a running system to StatefulSet can be done without service downtime — provided that volumes are not recreated but adopted as-is. In Kubernetes, StatefulSet maps a volume to a pod by name: the template name plus the ordinal number.

If existing PVCs are named according to this rule and the new object is declared as the owner, the controller will pick up the already populated data instead of sending a request to create a clean volume from the StorageClass.

We build the work sequence from data consistency, not from manifests. First, a rollback point — a volume snapshot using storage tools or a full copy; then the application is switched to a no-write mode: we stop intake at the service level or switch the node to read-only.

Only after that are the old pods removed, and StatefulSet brings up a pod with the same claimed volume — the data remains the same files on the same medium.

For databases with replication, direct pod replacement is not suitable: the node pointing to the existing volume must remain a group member, and the switch happens by changing the leader.

First, the new pod on the adopted volume catches up with the log, then the leader role is transferred to it, and only then is the old one shut down — the cluster answers requests the whole time.

Insurance against an irreversible outcome is a retention policy: automatic claim collection is disabled, and the old manifests and backup environment are kept until checksums are verified.

If a discrepancy is found, rollback means returning the previous controller and claims to the old owner, not restoring from a copy.

Technical concerns: failover, migrations, rollbacks

Before work starts, the same concerns come up: what will happen to data during node failure, how to move state between clusters, how to roll back a release that has already written an incompatible format. We answer directly — these same points become acceptance criteria.

A node with the database went down — is data lost?

No. Each StatefulSet instance is tied to its own persistent volume and ordinal number: when the pod is recreated, it returns to the same volume and with the same network name.

If the node is unavailable, the instance comes up on another node, and leader election prevents traffic from going to a lagging copy.

How to move state to another cluster?

A volume snapshot, restoration in the target cluster, replica catch-up, traffic switchover. The procedure fixes the write window and application stop moment in advance — we reduce the discrepancy to minutes, not to "however it turns out."

A release broke state — how do we roll back?

Images are pinned by digest, so rollback is switching to the previous manifest.

We change the data schema with backward-compatible steps: first we add fields, then switch reads, and only then remove the old ones — so rolling back the application does not drag along a database rollback.

Backups — scheduled or on demand?

Both modes. The schedule provides a recovery point for every hour, and before a risky schema change we take a copy manually. Copies are stored in a separate storage with a lifecycle policy, and we test recovery itself in a training environment — not during an incident.

Let's discuss the task: we'll assemble a design and come back with an estimate

The final step is to agree on the scope of work and the rollout order.

For the estimate to be specific rather than 'by eye,' we need a short input: a list of stateful services, availability and acceptable data loss requirements, current manifests, and how updates currently proceed. This is enough to see bottlenecks and propose a working design.

Then we follow a clear route:

  • we review the current configuration: manifests, namespace breakdown, where data resides, and how backup is arranged;
  • we record requirements: how many replicas are needed for node failure, whether a short interruption during update is acceptable, and who gets access to volumes;
  • we design the StatefulSet object: stable names, volume binding, replica startup and shutdown order, and update rules;
  • we agree on the scope of work and responsibility boundaries — what we do and what remains on your side;
  • we test the plan in a test environment: update, node failure, recovery from backup;
  • we come back with an estimate and plan: stages, rollout order, rollback points, and environment requirements.

To discuss the task, it is enough to describe the services and their data durability requirements. Describe the situation — we will come back with an estimate and work plan and propose the next step.