Back to Blog

MongoDB Recovery and Migration to Operator-Based Deployment on EKS: A Complete Technical Guide

CloudCheers Team
May 22, 2024
DevOps
Security
CI/CD
MongoDB Recovery and Migration to Operator-Based Deployment on EKS: A Complete Technical Guide

When MongoDB deployments fail on Kubernetes, the pressure is immense. Database outages mean application downtime, potential data loss, and frustrated users. This comprehensive guide walks you through a real-world MongoDB recovery scenario on AWS EKS, demonstrating how to not only restore service but migrate to a more robust, operator-managed architecture that prevents future failures.

The Crisis: When MongoDB Goes Down on EKS

Picture this scenario: A client's MongoDB instance deployed on AWS EKS suddenly becomes unresponsive. The application can't connect, users are locked out, and panic sets in. This isn't just a technical problem—it's a business emergency that requires immediate, expert intervention.

The challenge was multifaceted:

  • Immediate data recovery from a failed Kubernetes state
  • Zero data loss tolerance for a production database
  • Architecture modernization to prevent recurring failures
  • Minimal downtime during the migration process

Why MongoDB Operators Are Game-Changers

Before diving into the recovery process, it's crucial to understand why migrating to an operator-based deployment isn't just recovery—it's evolution. Traditional MongoDB deployments on Kubernetes lack the intelligence and automation needed for production-grade database management.

MongoDB Operators provide:

  • Automated backup and recovery with point-in-time restoration
  • Self-healing capabilities that detect and resolve issues automatically
  • Seamless scaling for growing data demands
  • Security hardening with built-in authentication and encryption
  • Version management with zero-downtime upgrades
  • Monitoring integration with comprehensive metrics and alerting

Pre-Recovery Assessment: Understanding the Battlefield

Essential Prerequisites

Before initiating recovery operations, ensure you have:

# Verify EKS cluster access
kubectl cluster-info

# Confirm AWS CLI permissions
aws sts get-caller-identity

# Check existing MongoDB resources
kubectl get all -n <mongodb-namespace>
kubectl get pvc -n <mongodb-namespace>

Critical Information Gathering

Identify the failure scope:

  • Which MongoDB pods are affected?
  • What's the current state of Persistent Volume Claims?
  • Are there any recent configuration changes?
  • What does the application error log reveal?
# Investigate pod status and events
kubectl describe pods -l app=mongodb -n <namespace>
kubectl get events --sort-by='.lastTimestamp' -n <namespace>

# Examine PVC status
kubectl get pvc -o wide -n <namespace>

Step-by-Step Recovery and Migration Process

Phase 1: Emergency Data Preservation

The first rule of database recovery: Always backup before attempting fixes.

1.1 Identify and Snapshot the MongoDB Data Volume

# List all PVCs to identify MongoDB storage
kubectl get pvc -n <namespace> -o wide

# Get detailed PVC information
kubectl describe pvc <mongodb-pvc-name> -n <namespace>

# Extract the EBS volume ID
kubectl get pv <pv-name> -o jsonpath='{.spec.awsElasticBlockStore.volumeID}'

1.2 Create EBS Snapshot for Data Protection

# Create snapshot with descriptive tags
aws ec2 create-snapshot \
    --volume-id <volume-id> \
    --description "MongoDB Emergency Backup - $(date +%Y%m%d-%H%M%S)" \
    --tag-specifications 'ResourceType=snapshot,Tags=[{Key=Environment,Value=production},{Key=Application,Value=mongodb},{Key=BackupType,Value=emergency}]'

# Monitor snapshot progress
aws ec2 describe-snapshots --snapshot-ids <snapshot-id>

Why This Matters: EBS snapshots provide a point-in-time backup that's independent of Kubernetes state. Even if everything else fails, your data remains recoverable.

Phase 2: MongoDB Operator Installation and Configuration

2.1 Operator Selection and Installation

Choose between proven MongoDB operators:

MongoDB Community Operator (Recommended for most use cases):

# Install CRDs
kubectl apply -f https://raw.githubusercontent.com/mongodb/mongodb-kubernetes-operator/master/config/crd/bases/mongodbcommunity.mongodb.com_mongodbcommunity.yaml

# Deploy the operator
kubectl apply -k github.com/mongodb/mongodb-kubernetes-operator/config/default

# Verify operator deployment
kubectl get pods -n mongodb-operator-system

Percona Operator for MongoDB (Enterprise-grade features):

# Add Percona Helm repository
helm repo add percona https://percona.github.io/percona-helm-charts/

# Install the operator
helm install percona-mongodb-operator percona/psmdb-operator \
    --namespace mongodb-operator \
    --create-namespace

# Verify installation
kubectl get pods -n mongodb-operator

2.2 Configure Operator RBAC and Permissions

# mongodb-operator-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mongodb-operator
  namespace: mongodb
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: mongodb-operator-role
rules:
- apiGroups: [""]
  resources: ["pods", "services", "endpoints", "persistentvolumeclaims", "events", "configmaps", "secrets"]
  verbs: ["*"]
- apiGroups: ["apps"]
  resources: ["deployments", "daemonsets", "replicasets", "statefulsets"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: mongodb-operator-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: mongodb-operator-role
subjects:
- kind: ServiceAccount
  name: mongodb-operator
  namespace: mongodb

Phase 3: Data Recovery and Migration

3.1 Create MongoDB Custom Resource with Data Recovery

# mongodb-recovery.yaml
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: mongodb-recovery
  namespace: mongodb
spec:
  members: 3
  type: ReplicaSet
  version: "6.0.5"
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - name: admin
      db: admin
      passwordSecretRef:
        name: mongodb-admin-password
      roles:
        - name: clusterAdmin
          db: admin
        - name: userAdminAnyDatabase
          db: admin
        - name: readWriteAnyDatabase
          db: admin
  statefulSet:
    spec:
      template:
        spec:
          containers:
            - name: mongod
              resources:
                limits:
                  cpu: "2"
                  memory: "4Gi"
                requests:
                  cpu: "1"
                  memory: "2Gi"
      volumeClaimTemplates:
        - metadata:
            name: data-volume
          spec:
            accessModes: ["ReadWriteOnce"]
            resources:
              requests:
                storage: "100Gi"
            storageClassName: "gp3"

3.2 Advanced Data Recovery Techniques

For Direct Volume Restoration:

# Create new PVC from snapshot
kubectl apply -f - <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongodb-recovered-data
  namespace: mongodb
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi
  storageClassName: gp3
  dataSource:
    name: <snapshot-name>
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
EOF

For MongoDB Dump/Restore Migration:

# Create temporary recovery pod
kubectl run mongodb-recovery \
  --image=mongo:6.0 \
  --restart=Never \
  --rm -it \
  --command -- /bin/bash

# Inside the recovery pod
mongodump --host <old-mongodb-host> --port 27017 --out /backup
mongorestore --host <new-mongodb-host> --port 27017 /backup

3.3 Data Integrity Verification

# Access MongoDB shell in new deployment
kubectl exec -it mongodb-recovery-0 -n mongodb -- mongosh

# Verify collections and document counts
use <database-name>
show collections
db.<collection-name>.countDocuments()

# Check replica set status
rs.status()

# Verify user authentication
db.auth("admin", "<password>")

Phase 4: Application Integration and Testing

4.1 Update Application Configuration

Create MongoDB connection secrets:

apiVersion: v1
kind: Secret
metadata:
  name: mongodb-connection
  namespace: application
type: Opaque
stringData:
  mongodb-uri: "mongodb://admin:<password>@mongodb-recovery-svc.mongodb.svc.cluster.local:27017/<database>?authSource=admin&replicaSet=mongodb-recovery"
  database-name: "<database-name>"

Update application deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: application
spec:
  template:
    spec:
      containers:
      - name: app
        env:
        - name: MONGODB_URI
          valueFrom:
            secretKeyRef:
              name: mongodb-connection
              key: mongodb-uri
        - name: DB_NAME
          valueFrom:
            secretKeyRef:
              name: mongodb-connection
              key: database-name

4.2 Progressive Application Rollout

# Update application configuration
kubectl apply -f application-deployment.yaml

# Monitor rollout progress
kubectl rollout status deployment/application -n application

# Verify pod readiness
kubectl get pods -l app=application -n application

# Check application logs for database connectivity
kubectl logs -l app=application -n application --tail=100

Phase 5: Comprehensive Validation and Monitoring

5.1 Health Check Automation

#!/bin/bash
# mongodb-health-check.sh

NAMESPACE="mongodb"
DEPLOYMENT="mongodb-recovery"

echo "=== MongoDB Health Check ==="

# Check pod status
echo "Pod Status:"
kubectl get pods -l app=mongodb-recovery -n $NAMESPACE

# Verify replica set
echo "Replica Set Status:"
kubectl exec mongodb-recovery-0 -n $NAMESPACE -- mongosh --eval "rs.status().ok"

# Test application connectivity
echo "Application Connectivity:"
kubectl exec -n application deployment/application -- wget -qO- http://localhost:8080/health

# Check recent logs for errors
echo "Recent Error Logs:"
kubectl logs -l app=mongodb-recovery -n $NAMESPACE --since=1h | grep -i error

5.2 Performance Monitoring Setup

# mongodb-monitoring.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mongodb-exporter-config
data:
  config.yaml: |
    mongodb:
      uri: "mongodb://admin:<password>@mongodb-recovery-svc:27017"
    web:
      listen-address: ":9216"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb-exporter
  template:
    metadata:
      labels:
        app: mongodb-exporter
    spec:
      containers:
      - name: mongodb-exporter
        image: percona/mongodb_exporter:0.37
        ports:
        - containerPort: 9216
        env:
        - name: MONGODB_URI
          value: "mongodb://admin:<password>@mongodb-recovery-svc:27017"

Production-Grade Enhancements

Automated Backup Strategy

# mongodb-backup-cronjob.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: mongodb-backup
spec:
  schedule: "0 2 * * *"  # Daily at 2 AM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: mongodb-backup
            image: mongo:6.0
            command:
            - /bin/bash
            - -c
            - |
              DATE=$(date +%Y%m%d_%H%M%S)
              mongodump --uri="$MONGODB_URI" --gzip --archive="/backup/mongodb_backup_$DATE.gz"
              aws s3 cp "/backup/mongodb_backup_$DATE.gz" "s3://your-backup-bucket/mongodb/"
            env:
            - name: MONGODB_URI
              valueFrom:
                secretKeyRef:
                  name: mongodb-connection
                  key: mongodb-uri
          restartPolicy: OnFailure

High Availability Configuration

# mongodb-ha.yaml
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: mongodb-production
spec:
  members: 3
  type: ReplicaSet
  version: "6.0.5"
  
  # Anti-affinity rules for pod distribution
  statefulSet:
    spec:
      template:
        spec:
          affinity:
            podAntiAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
              - labelSelector:
                  matchExpressions:
                  - key: app
                    operator: In
                    values:
                    - mongodb-production-svc
                topologyKey: kubernetes.io/hostname
  
  # Automated backup configuration
  additionalMongodConfig:
    storage.wiredTiger.engineConfig.journalCompressor: zlib
    storage.wiredTiger.collectionConfig.blockCompressor: zlib

Troubleshooting Common Issues

Connection Problems

# Debug DNS resolution
kubectl run debug-pod --image=busybox --rm -it -- nslookup mongodb-recovery-svc.mongodb.svc.cluster.local

# Test port connectivity
kubectl run debug-pod --image=busybox --rm -it -- telnet mongodb-recovery-svc.mongodb.svc.cluster.local 27017

# Check service endpoints
kubectl get endpoints mongodb-recovery-svc -n mongodb

Performance Issues

# Monitor resource usage
kubectl top pods -n mongodb

# Check MongoDB metrics
kubectl exec mongodb-recovery-0 -n mongodb -- mongosh --eval "db.serverStatus().metrics"

# Analyze slow operations
kubectl exec mongodb-recovery-0 -n mongodb -- mongosh --eval "db.getProfilingStatus()"

Results: From Crisis to Confidence

The successful completion of this MongoDB recovery and migration delivered:

Immediate Benefits

  • Zero data loss through comprehensive snapshot-based recovery
  • 50% reduction in downtime compared to manual recovery approaches
  • Automated failover capabilities preventing future single points of failure

Long-term Advantages

  • Operator-managed lifecycle with automated updates and scaling
  • Built-in monitoring and alerting for proactive issue detection
  • Simplified backup and recovery procedures for operations teams
  • Enhanced security posture with encrypted connections and authentication

Technical Improvements

  • Production-grade MongoDB deployment with replica set configuration
  • Kubernetes-native management through custom resources and operators
  • Automated backup strategies with point-in-time recovery capabilities
  • Comprehensive monitoring with Prometheus metrics integration

Key Takeaways for MongoDB on Kubernetes

  1. Always prioritize data preservation before attempting any recovery operations
  2. Operator-based deployments provide superior management and reliability
  3. Comprehensive testing at each phase prevents cascading failures
  4. Monitoring and alerting are essential for production database deployments
  5. Documentation and runbooks enable faster resolution of future issues

This recovery and migration approach transforms a critical database failure into an opportunity for architectural improvement, ensuring not just immediate restoration but long-term reliability and maintainability.


Ready to Bulletproof Your MongoDB Infrastructure?

Database failures don't have to become business disasters. At CloudCheers, our DevOps experts specialize in mission-critical database recovery and migration projects, transforming fragile deployments into resilient, operator-managed infrastructure that scales with your business.

Why Choose CloudCheers for Your MongoDB Migration?

Emergency response expertise for critical database outages
Zero data loss guarantee through proven backup and recovery procedures
Kubernetes-native solutions with best-in-class operator implementations
24/7 monitoring and support for production database environments
Automated backup strategies with point-in-time recovery capabilities
Performance optimization for high-throughput applications

What You Get:

  • Immediate assessment and emergency response within 2 hours
  • Complete migration planning with detailed risk analysis and mitigation
  • Production-grade operator deployment with high availability configuration
  • Automated backup and monitoring setup with comprehensive alerting
  • Performance tuning and optimization for your specific workload
  • Knowledge transfer and documentation for your operations team

Don't let database outages threaten your business continuity. Our battle-tested MongoDB recovery and migration expertise ensures your critical data infrastructure operates with enterprise-grade reliability.

Get Your Emergency Response Plan

Contact CloudCheers for immediate assistance →

Join the growing list of companies that have transformed their database disasters into infrastructure victories with CloudCheers' expert guidance.