Skip to content

Deployment of the MongoDB Operator

MongoDB Operator Requirements

To function properly, some requirements in the Kubernetes deployment must be met, and a MongoDB database instance dedicated to the Kubernetes cluster must be set up.

The MongoDB Operator expects a strict 1 to 1 relation of Kubernetes Cluster and MongoDB database instance. Exactly one MongoDB Operator replica must be deployed in one Kubernetes Cluster watching all namespaces. This MongoDB Operator is the only one managing users of the MongoDB database instance dedicated to the Kubernetes cluster. Database names and usernames are created based on namespace name and MongoDB resource name to avoid naming conflicts. A database instance managed by multiple MongoDB Operators for multiple clusters would cause name conflicts and access to the same database from multiple clusters.

Deployment with Kustomize

The easiest way to deploy the MongoDB Operator is to use the remote base with Kustomize. The kustomization.yaml must include the versioned remote base and provide a secret for the MongoDB connection with a user granting the required privileges. The remote bases enable Json logging by default.

Deployment with Kustomize

In default namespace mongodb-operator:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Namespace mongodb-operator is created by the remote base
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - https://github.com/SDA-SE/mongodb-operator//kustomize/release?ref=1.0.54
secretGenerator:
  - name: mongodb-operator
    namespace: mongodb-operator
    literals:
      - mongodbConnectionString=mongodb://user:s3cr3t@mongodb.mongodb:27017

In custom namespace:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: custom-namespace
resources:
  - custom-namespace-ns.yaml
  - https://github.com/SDA-SE/mongodb-operator//kustomize/release/no-namespace?ref=1.0.54
secretGenerator:
  - name: mongodb-operator
    literals:
      - mongodbConnectionString=mongodb://user:s3cr3t@mongodb.mongodb:27017

# custom-namespace-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: custom-namespace

Plain Secrets

Do not use plain secrets in GitOps repositories! Consider tools like Sealed Secrets or External Secrets to provide secrets for GitOps deployments securely.

Don't reference the default branch

Never use a remote base from the default branch (without ?ref=x.y.z). Due to the release process, it is possible that the image referenced in the default branch does not exist yet. Deployments will fail. Also breaking releases may be deployed unexpectitly when not referencing a defined tag.

TLS connections

To connect to MongoDB or DocumentDB using TLS, add the query param tls=true to the secret MONGODB_CONNECTION_STRING and reference the CA in PEM format in a configMapGenerator like this:

1
2
3
4
5
configMapGenerator:
  - name: mongodb-operator-ca-pem
    behavior: merge
    files:
      - ca-of-my-mongo-server.pem

Manual Deployment

Kubernetes

An example deployment of the MongoDB Operator that covers the following requirements is available in the GitHub Repository of the MongoDB Operator.

Service Account

The MongoDB Operator requires a ServiceAccount with some privileges for the Kubernetes API from a ClusterRole:

  • For the resource mongodbs the following verbs are required:
    • watch
    • list
    • get
    • update
  • For the resource mongodbs/status the following verbs are required:
    • watch
    • list
    • get
    • update
  • For the resource secrets the following verbs are required:
    • create
    • update
  • For the resource customresourcedefinitions with the resource name mongodbs.persistence.sda-se.com the following verbs are required:
    • get

Custom Resource Definition

The CRD mongodbs must be applied.

Database

A MongoDB database instance or an AWS DocumentDB cluster must be set up separately from the deployment of the MongoDB Operator.

A user for MongoDB Operator must be created.

The user of the MongoDB Operator must be granted userAdminAnyDatabase to function properly.

dbAdminAnyDatabase is needed to support spec.database.pruneAfterDelete: true of the MongoDB custom resource. pruneAfterDelete is suggested for develop and test environments only where pull request or temporary test deployments could create a big amount of temporary used databases.

MongoDB Operator Image

The image is hosted at quay.io/sdase/mongodb-operator.

Base Image

This container is based on the distroless Java image by Google. The base image provides both manual and automatic ways to configure memory limits of the JVM.

Environment Variables

The following environment variables can be used to configure the Docker container:

Java

  • JAVA_TOOL_OPTIONS string
    • Set options for the JVM. If Java options are set, you will find Picked up JAVA_TOOL_OPTIONS: "-Xmx340m" or similar in the log.
    • Example: -Xmx340m to set the max heap size

MongoDB

When connecting to the MongoDB, the configured hosts are checked. If any ends with .docdb.amazonaws.com, a connection to AWS DocumentDB is assumed, and the behavior slightly changes. While users for requested databases are created in the database when using MongoDB, all users will be created in the admin database when AWS DocumentDB is used.

  • MONGODB_CONNECTION_STRING string
    • The connection String that covers all configuration to access the MongoDB database.
    • Example: mongodb://username:password@mongodb.mongodb:27017
  • TRUSTED_CERTIFICATES_DIR
    • Directory in the container where CA certificates or certificate bundles in PEM format can be mounted. These certificates are used to verify SSL connections to the database. The configuration is ignored if no files are mounted. To consider, the mounted certifaces, the MONGODB_CONNECTION_STRING must contain the query parameter tls=true. Startup will fail if the directory is not readable.
    • Default: /var/trust/certificates

Logging

  • ENABLE_JSON_LOGGING boolean
    • Enables logging as Json if true (case-insensitive). Configuration errors are never logged as Json. Each log will be one line of Json, containing the keys:
      • level: "INFO", "WARN" or "ERROR".
      • message: The log message.
      • exception: The exception, if any.
      • mdc: Object with additional key-value information, if any.
    • Default: none, effectively false

Endpoints

The image exposes port 8081 for monitoring purposes.

It provides the following endpoints:

  • Readiness: http://{serviceUrl}:8081/health/readiness
  • Liveness: http://{serviceUrl}:8081/health/liveness
  • Metrics in prometheus format: http://{serviceUrl}:8081/metrics/prometheus

    The provided metrics should be compatible with the JVM Micrometer Dashboard