Simple MongoDB Deployment in Kubernetes with Private Access

Mon 15 June 2020


We want to deploy a simple (read: development) instance of MongoDB in our Kubernetes cluster with as little work as possible. Additionally, we'd like to make that MongoDB deployment available to services outside the k8s cluster but not outside our VPC


Use Bitnami's MongoDB helm chart to deploy MongoDB, then expose the service via a Kubernetes service of type LoadBalancer.


We assume you:

  1. are in AWS (not EKS, just living in AWS)
  2. already have a Kubernetes and
  3. have appropriately tagged your public subnets to allow Kubernetes to create load balancers for you on your behalf.

Configure a StorageClass in Kubernetes

We want to use Dynamic Provisioning so that we don't have to create storage ahead of time (i.e. less work for us). In order for that to succeed, we need to define at least one storageClass and reference it during our helm install. Let's create a standard storageClass. We're in AWS so we'll use one that uses the EBS backend.


kind: StorageClass

  # We can use any name so long as we reference it correctly
  name: standard

  # Tell k8s this is our default storageClass
  annotations: "true"

# Use the EBS backend
  type: gp2

# Can also be 'Retain' but we choose delete so we don't accrue volumes during testing.
reclaimPolicy: Delete
allowVolumeExpansion: true
  - debug
volumeBindingMode: Immediate

Apply the file:

kubectl apply -f aws-storageClass.yml

Confirm success

 kubectl get storageclass
NAME                 PROVISIONER             AGE
standard (default)   4h1m

Gather Bitnami Helm Chart and Config File

To use Bitnami's helm chart, you'll need to add it to your helm repo listing.

helm repo add bitnami

Create the values file to override the defaults.


# We're testing, so 1Gi is fine
  size: 1Gi

# Use the initContainer to change permissions for us so Mongo can write to the volume
volumePermissions.enabled: true

# Use the storageClass we created earlier
  storageClass: standard


  # Make AWS load balancer
  type: LoadBalancer

  # Tell AWS to make our load balancer an internal LB
  annotations: {


helm install mongo bitnami/mongodb -f mongo-custom-values.yml

After a moment, Kubernetes will create the volumes, ELB, and pod. Confirm.

kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
mongo-mongodb-7b64d775b4-hb5gd   1/1     Running   0          71m

kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                   STORAGECLASS   REASON   AGE
pvc-ec937eff-2dd7-4bdc-ac88-12f78a535d70   1Gi        RWO            Delete           Bound    default/mongo-mongodb   standard                71m

kubectl get pvc
NAME            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mongo-mongodb   Bound    pvc-ec937eff-2dd7-4bdc-ac88-12f78a535d70   1Gi        RWO            standard       71m

kubectl get svc
NAME            TYPE           CLUSTER-IP       EXTERNAL-IP                                                                        PORT(S)           AGE
mongo-mongodb   LoadBalancer   27017:31634/TCP   72m

If any of the above is showing problems, something went wrong. Use kubectl describe <broken-thing> to troubleshoot.


Test success by running a pod inside your k8s cluster, using the ELB's FQDN as the host (Note: the output of helm install has helpful output to help you fetch the admin creds as well as running this test command).

kubectl run \
--namespace default \
mongo-mongodb-client \
--rm --tty -i \
--restart='Never' \
--image \
--command -- mongo admin --host mongo-mongodb --authenticationDatabase admin -u root -p $MONGODB_ROOT_PASSWORD

If you don't see a command prompt, try pressing enter.

> help                    help on db methods             help on collection methods                    sharding helpers                    replica set helpers

Success! You now have an instance of MongoDB running in your k8s cluster, accessible only to resources inside your VPC. This model applies to any service, not just MongoDB.


Credit goes to the following sites/pages for details I would have otherwise missed.