Deploy MongoDB on Kubernetes with the Community Operator

This guide shows you how to deploy MongoDB on Kubernetes using the MongoDB Community Operator shipped in the repository. The deployment provides a managed replica set, a Prometheus-compatible exporter sidecar, ServiceMonitor-ready labels, and a PodDisruptionBudget for high availability.

Operator-first by design

The MongoDB Community Operator owns every aspect of the database lifecycle. You do not edit StatefulSets, config files, or replica set members directly. Update mongodb/env/config.env, then re-apply the overlay. The operator reconciles the rest.

Prerequisites

Before you begin, confirm that:

  • You have a Kubernetes cluster with kubectl configured against it.
  • You have permissions to create namespaces, custom resource definitions, and operator resources.
  • The cluster does not already have a MongoDB Community Operator running. The bundle in this repository will conflict with an existing operator.
  • Your cluster can reach quay.io to pull the operator and database images, or that the images have been mirrored into a registry that is reachable from cluster nodes.
  • Your storage class supports the disk size set in STORAGE_SIZE (default 100 Gi per member).

Reviewing config.env Before Deploying

Open mongodb/env/config.env and review the values that drive the deployment:

GroupVariablesDefault
TopologyMEMBERS, ARBITERS, MONGODB_VERSION1 / 0 / 8.0.13
ImagesMONGO_IMAGE, OPERATOR_IMAGE, AGENT_IMAGE, VERSION_UPGRADE_HOOK_IMAGE, READINESS_PROBE_IMAGE, MONGODB_EXPORTER_IMAGEPinned in config.env
StorageSTORAGE_CLASS, STORAGE_SIZEstandard / 100Gi
mongod resourcesMONGOD_CPU_REQUEST, MONGOD_CPU_LIMIT, MONGOD_MEM_REQUEST, MONGOD_MEM_LIMIT500m / 2 / 2Gi / 8Gi
Exporter resourcesEXPORTER_CPU_REQUEST, EXPORTER_CPU_LIMIT, EXPORTER_MEM_REQUEST, EXPORTER_MEM_LIMIT100m / 500m / 128Mi / 256Mi

The defaults target development

The default replica set has MEMBERS=1. This is appropriate for development only: a single member cannot survive node failure and provides no read scaling. Production deployments should use MEMBERS=3 or MEMBERS=5. Set this before the first apply if you can; scaling later is supported but causes a longer initial deployment.

Reviewing User Credentials

The default credentials are stored in mongodb/database/secrets.yaml:

  • app user: app / changeMe_S3cure!
  • metrics user: metrics / metrics_ChangeMe!

Replace these values with passwords you have generated yourself before deploying anywhere except a local evaluation cluster. The operator turns the password into SCRAM credentials automatically and emits the connection string secret app-mongodb-conn for Countly to consume.

Deploying the Stack

From the repository root, apply the MongoDB overlay. This installs the operator, the database custom resource, RBAC, the metrics service, and the PodDisruptionBudget in the mongodb namespace:

kubectl apply -k mongodb/

The operator picks up the MongoDBCommunity resource and provisions the StatefulSet, secrets, and SCRAM authentication on its own.

Verifying the Initial Deployment

Watch pods come online and confirm Ready status:

kubectl -n mongodb get pods

Expected:

  • Database pods report 3/3 Ready: mongod, the MongoDB agent, and the exporter sidecar.
  • One pod per replica set member, named app-mongodb-N.
  • The operator deployment mongodb-kubernetes-operator reports 1/1 Ready.

Quick functional check using the app user password from the secret:

APP_PASSWORD=$(kubectl get secret app-user-password -n mongodb -o jsonpath='{.data.password}' | base64 -d)

kubectl exec app-mongodb-0 -n mongodb -c mongod -- \
  mongosh "mongodb://app:${APP_PASSWORD}@localhost:27017/admin?replicaSet=app-mongodb&ssl=false" \
  --eval "rs.status().members.forEach(m => print(m.name + ' - ' + m.stateStr))" --quiet

Each member should report PRIMARY or SECONDARY, depending on the topology.

Deployment is up

With pods Ready and rs.status() returning one primary and the expected secondaries, the cluster is ready for the rest of the Countly stack. Run the full validation checklist documented separately to confirm replication, metrics, and PDB behavior before depending on the cluster in production.

Connecting Countly to This Cluster

The operator emits a connection-string secret named app-mongodb-conn in the mongodb namespace. Countly application pods run in the countly namespace and need the secret copied across. The dedicated guide on copying the MongoDB connection secret covers the recommended jq pipeline and the sed fallback.

Common Issues and Gotchas

Pods do not start

Read the operator logs first:

kubectl -n mongodb logs deployment/mongodb-kubernetes-operator

Confirm the CRD is installed:

kubectl get crd mongodbcommunity.mongodbcommunity.mongodb.com

Then confirm every image referenced in config.env is pullable from this cluster.

Authentication failures during the smoke test

The operator generates SCRAM credentials asynchronously after the database starts. If you run the smoke test too early, authentication will fail. Confirm the operator has finished by listing SCRAM secrets:

kubectl get secrets -n mongodb | grep scram

Use the connection string from app-mongodb-conn rather than constructing one by hand:

kubectl get secret app-mongodb-conn -n mongodb -o yaml
Metrics endpoint returns no data

Read the exporter sidecar logs:

kubectl logs app-mongodb-0 -n mongodb -c mongodb-exporter

The most common cause is a missing or misconfigured metrics-exporter-uri secret. Confirm the metrics service has endpoints:

kubectl get endpoints app-mongodb-metrics -n mongodb
Replica set never converges to a primary

All members must be reachable on their pod-to-pod network for replica set election to succeed. Read individual mongod logs side by side:

kubectl logs app-mongodb-0 -n mongodb -c mongod
kubectl logs app-mongodb-1 -n mongodb -c mongod

A NetworkPolicy applied to the mongodb namespace can prevent inter-pod communication. Either relax the policy or include the operator-managed labels in the policy's selectors. 

Was this page helpful?
Reach out to us for any other questions.
Helpful?

Looking For More Help?