Stateful Services on Kubernetes, and How to Use Them

Stateful workloads, such as those that rely on a database, are highly facilitated in Kubernetes; like Deployment resources, there are reconciliation loops that wrap Pods for services like Postgres and MongoDB, that are commonly clustered, and require consistent, ordinal naming, and high-levels of automation for provisioning and locating volumes for your persistent data in these volumes.

An example I’d like to share is based on the StatefulSet resource, which like a Deployment, runs a given number of replicas, has a high level of control over resource consumption, and full access to the interfaces for storage, but also provides consistent naming for these replicas, so as in MongoDB ReplicaSets, you can anticipate the name of the adjacent replica node, and it makes spinning up a cluster of a known size easy to define in however your manifests are generated and stored (i.e. YAML generated by a CI/CD system or config management tooling).

Let’s say I have a MongoDB-backed service, and my requirement is that I be able to flexibly scale the size of the replicaSet, but at minimum I’d have 3 nodes. Each of these nodes would need a PersistentVolume, so when these Pods are recycled, I can reattach the volume, so I start by defining my PersistentVolume, in this case from my provider’s storage class:

Where, much like in our Deployment we reference the claim name, we’re creating a template for volume claims, and in our volumeMount requesting, in this case, mongo-persistent-storage, and each of these nodes is deployed with nametags like mongo-[1..Xreplicas] rather than a random Pod ID as you might see in other replication controllers, within the namespace you deployed this StatefulSet to.

As a result, apps consuming this MongoDB service, would use a resulting connection string like:

where MONGO_URL and MONGO_OPLOG_URL both refer to this replica set, and resolve it using the KubeDNS entry created with your StatefulSet-controlled MongoDB nodes, and it stores users, messages, and logging activity into MongoDB.