← Back to Home

Deploying MongoDB on Kubernetes

Deploying MongoDB on Kubernetes

Posted by NetworkWhois on

After spending countless hours tweaking and optimizing MongoDB deployments on K3s for various projects, I've finally nailed down a reliable approach that I wish I had known when I started. Today, I'm sharing my battle-tested method for deploying MongoDB on K3s, including all the tricks and pitfalls I've discovered along the way.

If you haven't set up K3s yet, check out my previous guide on installing K3s on Ubuntu first. Once you have that ready, let's dive into deploying MongoDB.

Why MongoDB on K3s?

Before jumping into the deployment steps, let me share why I chose this setup. For my microservices architecture, I needed a database solution that was both scalable and easy to manage. Running MongoDB on K3s gives me the best of both worlds - MongoDB's flexibility and K3s's lightweight orchestration. Plus, the automatic failover capabilities have saved me from many potential disasters!

Prerequisites

  • A running K3s cluster
  • kubectl configured and ready
  • At least 4GB RAM available for MongoDB
  • Storage space for persistent volumes

Step 1: Setting Up the Storage

First, let's create a StorageClass for MongoDB. I've learned that proper storage configuration is crucial for database performance:

cat <<EOF | kubectl apply -f -
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: mongodb-local-storage
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
EOF
create-a-StorageClass-for-MongoDB.png

I use WaitForFirstConsumer binding mode because it helps prevent scheduling issues I encountered with immediate binding. Trust me, this saves headaches later!

Step 2: Creating a Namespace

I always isolate my database deployments in their own namespace:

kubectl create namespace mongodb

Step 3: MongoDB Deployment

Here's my production-tested MongoDB deployment configuration:

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb
  namespace: mongodb
spec:
  serviceName: mongodb
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo:6.0
        ports:
        - containerPort: 27017
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: username
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: password
        volumeMounts:
        - name: mongodb-data
          mountPath: /data/db
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
  volumeClaimTemplates:
  - metadata:
      name: mongodb-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: mongodb-local-storage
      resources:
        requests:
          storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  name: mongodb
  namespace: mongodb
spec:
  clusterIP: None
  selector:
    app: mongodb
  ports:
  - port: 27017
    targetPort: 27017
EOF
MongoDB-deployment-configuration.png

Never deploy MongoDB without resource limits! I once had a runaway query that brought down my entire node because I forgot to set them.

Step 4: Creating the Secret

Create a secret for MongoDB credentials:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: mongodb-secret
  namespace: mongodb
type: Opaque
data:
  username: $(echo -n "adminuser" | base64)
  password: $(echo -n "your-secure-password" | base64)
EOF
Create-a-secret-for-MongoDB.png

Replace 'your-secure-password' with a strong password. I use a password manager to generate and store these credentials.

Step 5: Verifying the Deployment

Check if everything is running correctly:

# Check the StatefulSet
kubectl get statefulset -n mongodb

# Check the pod
kubectl get pods -n mongodb

# Check the PVC
kubectl get pvc -n mongodb
Verifying-MongoDB-Deployment.png

Step 6: Accessing MongoDB

To connect to MongoDB from within the cluster:

kubectl exec -it mongodb-0 -n mongodb -- mongosh -u adminuser -p your-secure-password
connect-to-MongoDB-kubernetes.png

For development purposes, I often set up a port-forward to access MongoDB locally:

kubectl port-forward -n mongodb svc/mongodb 27017:27017

Troubleshooting Common Issues

Here are some issues I've encountered and their solutions:

1. Pod Won't Start

kubectl describe pod mongodb-0 -n mongodb
kubectl logs mongodb-0 -n mongodb

2. Storage Issues

kubectl describe pvc mongodb-data-mongodb-0 -n mongodb

Backup Strategy

Here's the backup script I use (save it as mongodb-backup.sh):

#!/bin/bash
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup"

kubectl exec -n mongodb mongodb-0 -- mongodump \
  --username $MONGODB_USER \
  --password $MONGODB_PASSWORD \
  --out /dump

kubectl cp mongodb/mongodb-0:/dump $BACKUP_DIR/mongodb_backup_$TIMESTAMP

Production Considerations

Before going to production, consider these points I've learned the hard way:

  • Set up proper monitoring using Prometheus and Grafana
  • Implement regular backup procedures
  • Configure network policies to restrict access
  • Use anti-affinity rules if running multiple replicas
  • Regularly test your backup and restore procedures

Scaling MongoDB

When your application grows, you might want to set up a replica set. Here's a quick overview of how to modify the deployment for replication:

spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: mongodb
        command:
        - mongod
        - "--replSet"
        - "rs0"
        - "--bind_ip"
        - "0.0.0.0"

I'll cover MongoDB replication in detail in a future article. It's a topic that deserves its own deep dive!

While deploying MongoDB on K3s might seem daunting at first, it becomes quite manageable once you understand the key components. I've been running this setup in production for over a year now, and it's been rock solid. Remember to always backup your data and monitor your deployment closely.

Have you deployed MongoDB on K3s? I'd love to hear about your experience in the comments below. What challenges did you face, and how did you overcome them?