DocumentDB Kubernetes Operator¶
The DocumentDB Kubernetes Operator is an open-source operator that runs and manages DocumentDB on Kubernetes.
DocumentDB is the engine powering vCore-based Azure Cosmos DB for MongoDB. Built on PostgreSQL, it provides a native document-oriented NoSQL database with support for CRUD operations on BSON data types.
When you deploy a DocumentDB cluster, the operator creates and manages PostgreSQL instances, the DocumentDB Gateway, and supporting Kubernetes resources. The gateway enables you to connect with MongoDB-compatible drivers, APIs, and tools, while PostgreSQL serves as the underlying storage engine.
Note
This project is under active development but not yet recommended for production use. We welcome your feedback and contributions!
Quickstart¶
Follow these steps to install the operator, deploy a DocumentDB cluster, and connect using mongosh.
Prerequisites¶
- Helm installed.
- kubectl installed.
- A Kubernetes 1.35+ cluster. The operator uses the ImageVolume feature (GA in K8s 1.35) to mount the DocumentDB extension. A local cluster such as minikube or kind (v0.31+) works for this quickstart.
- mongosh installed to connect to the DocumentDB cluster.
Start a local Kubernetes cluster¶
If you're using minikube:
If you are using kind (v0.31+), use the following command:
Install cert-manager¶
The operator uses cert-manager to manage TLS certificates for the DocumentDB cluster.
Tip
If you already have cert-manager installed, skip this step.
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
Verify that cert-manager is running:
NAMESPACE NAME READY STATUS RESTARTS
cert-manager cert-manager-6794b8d569-d7lwd 1/1 Running 0
cert-manager cert-manager-cainjector-7f69cd69f7-pd9bc 1/1 Running 0
cert-manager cert-manager-webhook-6cc5dccc4b-7jmrh 1/1 Running 0
Install the DocumentDB operator¶
The operator Helm chart automatically installs the CloudNativePG operator as a dependency in the cnpg-system namespace.
Warning
If CloudNativePG is already installed in your cluster, you may experience conflicts. See the Helm chart documentation for options to skip the CNPG dependency.
# Add the Helm repository
helm repo add documentdb https://documentdb.github.io/documentdb-kubernetes-operator
helm repo update
# Install the operator
helm install documentdb-operator documentdb/documentdb-operator \
--namespace documentdb-operator \
--create-namespace \
--wait
Verify the operator is running:
Confirm the DocumentDB CRDs are installed:
Store DocumentDB credentials in a Kubernetes Secret¶
Before deploying a cluster, create a Secret with the credentials that the DocumentDB gateway will use. The operator's sidecar injector automatically projects these values as environment variables into the gateway container.
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Namespace
metadata:
name: documentdb-preview-ns
---
apiVersion: v1
kind: Secret
metadata:
name: documentdb-credentials
namespace: documentdb-preview-ns
type: Opaque
stringData:
username: k8s_secret_user
password: K8sSecret100
EOF
Verify the Secret:
Note
By default, the operator expects a Secret named documentdb-credentials with username and password keys. To use a different Secret name, set spec.documentDbCredentialSecret in your DocumentDB resource.
Deploy a DocumentDB cluster¶
Create a single-node DocumentDB cluster:
cat <<EOF | kubectl apply -f -
apiVersion: documentdb.io/preview
kind: DocumentDB
metadata:
name: documentdb-preview
namespace: documentdb-preview-ns
spec:
nodeCount: 1
instancesPerNode: 1
documentDbCredentialSecret: documentdb-credentials
resource:
storage:
pvcSize: 10Gi
exposeViaService:
serviceType: ClusterIP
EOF
Wait for the cluster to initialize, then verify it's running:
Check the DocumentDB resource status:
Connect to the DocumentDB cluster¶
Choose a connection method based on your service type. For more details on service types, load balancers, and Network Policies, see Networking. For TLS certificate configuration, see TLS.
Option 1: ClusterIP service (default — for local development)¶
Step 1: Set up port forwarding (keep this terminal open):
Step 2: In a new terminal, connect with mongosh:
mongosh 127.0.0.1:10260 \
-u k8s_secret_user \
-p K8sSecret100 \
--authenticationMechanism SCRAM-SHA-256 \
--tls --tlsAllowInvalidCertificates
Or use a connection string:
mongosh "mongodb://k8s_secret_user:K8sSecret100@127.0.0.1:10260/?directConnection=true&authMechanism=SCRAM-SHA-256&tls=true&tlsAllowInvalidCertificates=true&replicaSet=rs0"
Option 2: LoadBalancer service (for cloud deployments)¶
For direct external access in cloud environments (AKS, EKS, GKE), deploy with a LoadBalancer service type:
Step 1: Deploy DocumentDB with LoadBalancer:
cat <<EOF | kubectl apply -f -
apiVersion: documentdb.io/preview
kind: DocumentDB
metadata:
name: documentdb-preview
namespace: documentdb-preview-ns
spec:
nodeCount: 1
instancesPerNode: 1
documentDbCredentialSecret: documentdb-credentials
resource:
storage:
pvcSize: 10Gi
exposeViaService:
serviceType: LoadBalancer
EOF
Step 2: Wait for the external IP:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
documentdb-service-documentdb-preview LoadBalancer 10.0.228.243 52.149.56.216 10260:30312/TCP 2m
Step 3: Connect using the external IP:
# Get the connection string
kubectl get documentdb documentdb-preview -n documentdb-preview-ns -o jsonpath='{.status.connectionString}'
# Connect with mongosh
mongosh "<connection-string>"
Note
LoadBalancer services are supported in cloud environments (AKS, EKS, GKE) and in local development with minikube and kind.
Work with data¶
Once connected, create a database, a collection, and insert some documents:
use testdb
db.createCollection("test_collection")
db.test_collection.insertMany([
{ name: "Alice", age: 30 },
{ name: "Bob", age: 25 },
{ name: "Charlie", age: 35 }
])
db.test_collection.find()
[direct: mongos] test> use testdb
switched to db testdb
[direct: mongos] testdb> db.createCollection("test_collection")
{ ok: 1 }
[direct: mongos] testdb> db.test_collection.insertMany([
... { name: "Alice", age: 30 },
... { name: "Bob", age: 25 },
... { name: "Charlie", age: 35 }
... ])
{
acknowledged: true,
insertedIds: {
'0': ObjectId('682c3b06491dc99ae02b3fed'),
'1': ObjectId('682c3b06491dc99ae02b3fee'),
'2': ObjectId('682c3b06491dc99ae02b3fef')
}
}
[direct: mongos] testdb> db.test_collection.find()
[
{ _id: ObjectId('682c3b06491dc99ae02b3fed'), name: 'Alice', age: 30 },
{ _id: ObjectId('682c3b06491dc99ae02b3fee'), name: 'Bob', age: 25 },
{
_id: ObjectId('682c3b06491dc99ae02b3fef'),
name: 'Charlie',
age: 35
}
]
Try the sample Python app¶
You can also connect using the sample Python program (PyMongo) in the repository. It inserts a document into a movies collection in the sample_mflix database.
git clone https://github.com/documentdb/documentdb-kubernetes-operator
cd documentdb-kubernetes-operator/operator/src/scripts/test-scripts
pip3 install pymongo
python3 mongo-python-data-pusher.py
Inserted document ID: 682c54f9505b85fba77ed154
{'_id': ObjectId('682c54f9505b85fba77ed154'),
'cast': ['Olivia Colman', 'Emma Stone', 'Rachel Weisz'],
'directors': ['Yorgos Lanthimos'],
'genres': ['Drama', 'History'],
'rated': 'R',
'runtime': 121,
'title': 'The Favourite MongoDB Movie',
'type': 'movie',
'year': 2018}
Verify using mongosh:
[direct: mongos] testdb> use sample_mflix
switched to db sample_mflix
[direct: mongos] sample_mflix>
[direct: mongos] sample_mflix> db.movies.find()
[
{
_id: ObjectId('682c54f9505b85fba77ed154'),
title: 'The Favourite MongoDB Movie',
genres: [ 'Drama', 'History' ],
runtime: 121,
rated: 'R',
year: 2018,
directors: [ 'Yorgos Lanthimos' ],
cast: [ 'Olivia Colman', 'Emma Stone', 'Rachel Weisz' ],
type: 'movie'
}
]
Tip
Update the script's host variable to match your service type (127.0.0.1 for ClusterIP with port-forward, or the external IP for LoadBalancer). Use environment variables for credentials instead of hardcoding them.
Configuration and advanced topics¶
Sidecar injector plugin configuration¶
The operator uses a sidecar injector plugin to automatically inject the DocumentDB Gateway container into PostgreSQL pods. You can customize the gateway image, pod labels, and annotations.
For details, see Sidecar Injector Plugin Configuration.
Local high-availability (HA)¶
Deploy multiple DocumentDB instances with automatic failover by setting instancesPerNode to a value greater than 1.
Enable local HA¶
cat <<EOF | kubectl apply -f -
apiVersion: documentdb.io/preview
kind: DocumentDB
metadata:
name: documentdb-ha
namespace: <your-namespace>
spec:
nodeCount: 1
instancesPerNode: 3
documentDbCredentialSecret: documentdb-credentials
resource:
storage:
pvcSize: 10Gi
exposeViaService:
serviceType: LoadBalancer
EOF
This configuration creates:
- 1 primary instance — handles all write operations
- 2 replica instances — provide read scalability and automatic failover
Multi-cloud deployment¶
The operator supports deployment across multiple cloud environments and Kubernetes distributions. For guidance, see the Multi-Cloud Deployment Guide.
Clean up¶
Delete the DocumentDB cluster¶
Verify the pod is terminated:
Uninstall the operator¶
These resources were kept due to the resource policy:
[CustomResourceDefinition] poolers.postgresql.cnpg.io
[CustomResourceDefinition] publications.postgresql.cnpg.io
[CustomResourceDefinition] scheduledbackups.postgresql.cnpg.io
[CustomResourceDefinition] subscriptions.postgresql.cnpg.io
[CustomResourceDefinition] backups.postgresql.cnpg.io
[CustomResourceDefinition] clusterimagecatalogs.postgresql.cnpg.io
[CustomResourceDefinition] clusters.postgresql.cnpg.io
[CustomResourceDefinition] databases.postgresql.cnpg.io
[CustomResourceDefinition] imagecatalogs.postgresql.cnpg.io
release "documentdb-operator" uninstalled
Delete the namespace and CRDs¶
kubectl delete namespace documentdb-operator
kubectl delete crd backups.postgresql.cnpg.io \
clusterimagecatalogs.postgresql.cnpg.io \
clusters.postgresql.cnpg.io \
databases.postgresql.cnpg.io \
imagecatalogs.postgresql.cnpg.io \
poolers.postgresql.cnpg.io \
publications.postgresql.cnpg.io \
scheduledbackups.postgresql.cnpg.io \
subscriptions.postgresql.cnpg.io \
dbs.documentdb.io