Kubernetes - A Step-by-Step Guide For Implementing Statefulset using MongoDB

Kubernetes - A Step-by-Step Guide For Implementing Statefulset using MongoDB

Follow this step-by-step guide to deploy a mongodb statefulset.

StatefulSets are ideal for stateful applications like MongoDB, as they provide stable network identities, ordered deployment/scaling, and persistent storage.

A StatefulSet is a Kubernetes workload API object (like a Deployment) designed specifically to manage stateful applications


Key Features of StatefulSets

1. Stable Network Identity

  • Each pod gets a stable hostname based on the pattern: <statefulset-name>-<ordinal-index> (e.g., mongodb-0, mongodb-1).
  • A headless Service (ClusterIP: None) is used to control the network domain and DNS records for the pods.

2. Persistent Storage

  • PersistentVolumeClaims (PVCs) are used to retain data even if pods are rescheduled.
  • Each pod gets its own PVC. ensures data persistence across pod restarts.

3. Ordered Operations

  • Pods are deployed, updated, or scaled in order (e.g., mongodb-0 starts before mongodb-1).
  • During scaling down, pods terminate in reverse order (e.g., mongodb-1 is deleted before mongodb-0).

4. Graceful Failures

  • If a pod fails, Kubernetes replaces it with a new pod that retains the same name, network identity, and storage.


How Data Sync Works in MongoDB:

MongoDB uses a primary-secondary replication model:

Primary:

  • Handles all write operations (inserts, updates, deletes).
  • Records changes in the oplog (operation log).

Secondary:

  • Continuously pull changes from the primary’s oplog.
  • Apply these changes to their own data sets to stay in sync.

Oplog:

  • Secondaries use the oplog to replicate changes.


We understood Statefulset and its features along with the mongodb data sync. Now lets implement.

Step 1: Create the Headless Service: mongo-svc.yml

apiVersion: v1
kind: Service
metadata:
  name: mongodb-headless
  labels:
    app: mongodb
spec:
  clusterIP: None  # Headless service
  ports:
  - port: 27017
    name: mongodb
  selector:
    app: mongodb        

Step 2: Create the Statefulset Service: mongo-statefulset.yml

Note:

--replSet: Each pod would act as a standalone MongoDB server, If this flag is not mentioned

--bind_ip_all: This flag enables inter-pod communication else pods would only listen on localhost,

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
spec:
  serviceName: mongodb-headless
  replicas: 3  
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo:6.0
        command: ["mongod", "--replSet", "rs0", "--bind_ip_all"]
        ports:
        - containerPort: 27017
        volumeMounts:
        - name: mongodb-data
          mountPath: /data/db
  volumeClaimTemplates:
  - metadata:
      name: mongodb-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "standard"  # Adjust based on your cluster
      resources:
        requests:
          storage: 10Gi        

Step 3: Create the secrets file: mongo-secrets.yml

apiVersion: v1
kind: Secret
metadata:
  name: mongodb-secrets
type: Opaque
data:
  username: cm9vdAo=
  password: cGFzc3dvcmQK        

Step 4: Deploy Service, Statefulset and Secrets

kubectl apply -f mongo-secrets.yaml
kubectl apply -f mongo-svc.yaml
kubectl apply -f mongo-statefulset.yaml        

Step 5: Connect to Mongodb and intialize the replicaset.

kubectl exec -it mongodb-0 -- mongosh         
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongodb-0.mongodb-headless.default.svc.cluster.local:27017" },
    { _id: 1, host: "mongodb-1.mongodb-headless.default.svc.cluster.local:27017" },
    { _id: 2, host: "mongodb-2.mongodb-headless.default.svc.cluster.local:27017" }
  ]
});        

Step 6: Connect to Mongodb and create the user

kubectl exec -it mongodb-0 -- mongosh
use admin
db.createUser({ user: "root", pwd: "password", roles: ["root"] })        

Step 7: Once the user is created you can login to the Primary database.

Note: This command is getting the user details from the secrets file - mongo-secrets.yml

kubectl exec -it mongodb-0 -- mongosh -u $(kubectl get secret mongodb-secrets -o jsonpath='{.data.username}' | base64 -d) -p $(kubectl get secret mongodb-secrets -o jsonpath='{.data.password}' | base64 -d) --authenticationDatabase admin        

Step 9: If we delete the pod the pod should be automatically created with the same name.

Kubectl get pods        
Kubectl delete pod mongodb-0        
kubectl get pods -o wide --watch        

Summary:

  • MongoDB replica sets automatically sync data between instances using the oplog.
  • The primary instance handles writes, and secondary replicate changes.
  • If the replicaset is not initialised all instances will behave as a standalone instances.
  • If the pod is deleted Pods are recreated with the same identity and storage.
  • Data is preserved across pod restarts.


要查看或添加评论,请登录

Kiran Kulkarni的更多文章

社区洞察

其他会员也浏览了