Setting Up MongoDB Replication in Kubernetes with StatefulSets

Introduction

Running databases in Kubernetes comes with challenges such as maintaining persistent state, stable network identities, and automated recovery. For MongoDB, high availability and data consistency are critical, making replication a fundamental requirement.

In this guide, we’ll deploy a MongoDB Replica Set in Kubernetes using StatefulSets, ensuring that each MongoDB instance maintains a stable identity, persistent storage, and seamless failover.

Why StatefulSets for MongoDB?

Unlike Deployments, which assign dynamic pod names, StatefulSets ensure stable, ordered identities, making them ideal for running database clusters.

✅ Stable Hostnames → Essential for MongoDB replica set communication
✅ Persistent Storage → Ensures data consistency across restarts
✅ Automatic Scaling → Easily add more replica nodes
✅ Pod Ordering & Control → Ensures correct initialization sequence

Prerequisites

Before proceeding, ensure:

  • A running Kubernetes cluster (Minikube, RKE2, or any self-managed setup)
  • kubectl installed and configured
  • A StorageClass for persistent volumes

Step 1: Create a ConfigMap for MongoDB Initialization

A ConfigMap helps configure MongoDB startup settings.

apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-config
  namespace: mongo
data:
  mongod.conf: |
    storage:
      dbPath: /data/db
    net:
      bindIp: 0.0.0.0
    replication:
      replSetName: rs0
Click Here to Copy YAML

Apply the ConfigMap:

kubectl apply -f mongodb-configmap.yaml

Step 2: Define a Headless Service

A headless service ensures stable DNS resolution for MongoDB pods.

apiVersion: v1
kind: Service
metadata:
  name: mongodb
  namespace: mongo
spec:
  clusterIP: None
  selector:
    app: mongodb
  ports:
    - name: mongo
      port: 27017
Click Here to Copy YAML

Apply the Service:

kubectl apply -f mongodb-service.yaml

Step 3: Deploy MongoDB with a StatefulSet

We define a StatefulSet with three MongoDB replicas.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
  namespace: mongo
spec:
  serviceName: mongodb
  replicas: 3
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
        - name: mongo
          image: mongo:6.0
          command:
            - "mongod"
            - "--config"
            - "/config/mongod.conf"
          volumeMounts:
            - name: config-volume
              mountPath: /config
            - name: mongo-data
              mountPath: /data/db
          ports:
            - containerPort: 27017
      volumes:
        - name: config-volume
          configMap:
            name: mongodb-config
  volumeClaimTemplates:
    - metadata:
        name: mongo-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 5Gi
Click Here to Copy YAML

Apply the StatefulSet:

kubectl apply -f mongodb-statefulset.yaml

Step 4: Initialize the MongoDB Replica Set

Once all pods are running, initialize the replica set from the first MongoDB pod:

kubectl exec -it mongodb-0 -n mongo -- mongosh

Inside the MongoDB shell, run:

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongodb-0.mongodb.mongo.svc.cluster.local:27017" },
    { _id: 1, host: "mongodb-1.mongodb.mongo.svc.cluster.local:27017" },
    { _id: 2, host: "mongodb-2.mongodb.mongo.svc.cluster.local:27017" }
  ]
})

Check the replica set status:

rs.status()

Step 5: Verify Replication

To verify the secondary nodes, log into any of the replica pods:

kubectl exec -it mongodb-1 -n mongo -- mongosh

Run the following to check the node’s role:

rs.isMaster()

Conclusion

With StatefulSets, MongoDB can maintain stable identities, ensuring smooth replication and high availability in Kubernetes.

✅ Automatic failover → If a primary node fails, a secondary is promoted.
✅ Stable DNS-based discovery → Ensures seamless communication between replicas.
✅ Persistent storage → Data remains intact across pod restarts.

Want to scale your replica set? Just update the replicas count, and Kubernetes handles the rest!

Have you deployed databases in Kubernetes? Share your experience below!👇

Leave a comment