Navigation
This version of the documentation is archived and no longer supported. To learn how to upgrade your version of MongoDB Kubernetes Operator, refer to the upgrade documentation.

Secure Multi-Cluster Deployments with TLS

Overview

To secure your multi-cluster deployment with TLS encryption, run the multi-cluster TLS tool provided by MongoDB to automate the TLS configuration. The tool runs OpenSSL commands on the specified central cluster to generate server certificates for each member cluster and then updates the Kubernetes Operator configuration on each member cluster.

Alternatively, you can run OpenSSL commands directly on each member cluster to generate server certificates and CSRs, and then update the Kubernetes Operator configuration on each member cluster.

Prerequisites

Before you secure your multi-cluster MongoDB deployment using TLS encryption, complete the following tasks:

Configure TLS with the Multi-Cluster TLS Tool

Run the multi-cluster TLS tool on the specified central cluster. The tool runs OpenSSL commands and takes the following actions:

  • On each member cluster, uses a CA key and root certificate that you specify, or generates a new self-signed CA certificate and key if you don’t specify a CA key and root certificate.
  • Generates each cluster’s Certificate Signing Request (CSR) and server certificates for each member cluster’s host.
  • Based on these certificates and a CSR, creates a cluster certificate secret for each member cluster. Each cluster certificate secret consists of all generated server certificates and each member cluster host’s secret key. The host’s secret key contains the server certificate concatened with the cluster certificate key.
  • Creates an issuer-ca ConfigMap in each member cluster that has the CA root certificate.
  • Updates the MongoDB multi-cluster resource with the ConfigMap’s name and TLS security settings.
1

Clone the MongoDB Enterprise Kubernetes Operator repository.

git clone https://github.com/mongodb/mongodb-enterprise-kubernetes.git
2

Run the multi-cluster TLS tool.

  1. Change to the directory to which you cloned the repository.

  2. Run the multi-cluster TLS tool. Specify the following parameters to the tool:

    • The CA key and root certificate for your organization, if you have the CA root certificate. If you don’t have a CA root certificate, specify the Common Name (CN) and the multi-cluster TLS tool generates a self-signed CA key and root certificate.
    • The MongoDB multi-cluster resource name.
    • The central cluster name and namespace.
    • The country, state, and name of the organization for the Certificate Signing Request (CSR).

    The following example shows how to run the tool if you have a CA key and root certificate:

    go run public/tools/multicluster/tls.go \
       -resource-name="multi-replica-set" \
       -central-cluster="${MDB_CENTRAL_CLUSTER_FULL_NAME}" \
       -central-cluster-namespace="mongodb" \
       -ca-key={PATH TO CA ROOT KEY} \
       -ca-crt={PATH TO CA ROOT CERT} \
       -country={ORG CERT COUNTRY} \
       -state={ORG CERT STATE} \
       -organization={ORG}
    

    The following example shows how to run the tool if you don’t have a CA key and root certificate. In this case, use the common-name parameter to specify the Common Name (CN) of the self-signed CA root certificate that the tool will generate:

    go run public/tools/multicluster/tls.go \
       -resource-name="multi-replica-set" \
       -central-cluster="${MDB_CENTRAL_CLUSTER_FULL_NAME}" \
       -central-cluster-namespace="mongodb" \
       -common-name={ORG CERT COMMON NAME} \
       -country={ORG CERT COUNTRY} \
       -state={ORG CERT STATE} \
       -organization={ORG}
    
3

Verify that the MDB resources are running.

  1. For member clusters, run the following commands to verify that the MongoDB Pods are in the running state:

    kubectl get pods \
     --context=$MDB_CLUSTER_1_FULL_NAME \
     --namespace mongodb
    
    kubectl get pods \
     --context=$MDB_CLUSTER_2_FULL_NAME \
     --namespace mongodb
    
    kubectl get pods \
     --context=$MDB_CLUSTER_3_FULL_NAME \
     --namespace mongodb
    
  2. In the central cluster, run the following commands to verify that the MongoDBMulti CustomResource is in the running state:

    kubectl --context=$MDB_CENTRAL_CLUSTER_FULL_NAME \
      --namespace mongodb \
      get mdbm multi-replica-set -o yaml -w
    

Configure TLS with OpenSSL

In this procedure you:

  • Use OpenSSL to generate member cluster’s CA root certificates and CSRs, and server certificates for each member cluster’s host.
  • Based on these certificates and CSRs, use OpenSSL to create the member cluster certificate secrets. Each cluster certificate secret consists of all generated server certificates and each member cluster host’s secret key. The host’s secret key contains the server certificate concatened with the cluster certificate key.
  • In each member cluster, create the ConfigMap that has the CA root certificate.
  • Update the MongoDB multi-cluster resource with the ConfigMap’s name and TLS security settings.
1

Use OpenSSL to generate CA certificates, CSRs, and server certificates.

  1. (Optional). If you don’t have a CA key and root certificate for your organization, generate a CA key with genrsa. Skip this step if you already have a CA key.

    openssl genrsa -out ./certs/ca.key 2048
    
  2. (Optional). Run openssl req to generate a CA root certificate signed by the CA key generated in the previous step. Skip this step if your organization already has a CA root certificate that you can use to secure your multi-cluster deployment.

    openssl req -x509 -new -nodes \
       -key ./certs/ca.key \
       -subj /CN={org cert common name} \
       -days 3650 \
       -reqexts v3_req \
       -extensions v3_ca \
       -out ./certs/ca.crt
    
  3. For each member cluster, generate a key for the Certificate Signing Request (CSR) with genrsa:

    openssl genrsa -out ./certs/{cluster-X-cert-key}.key 2048
    
  4. For each member cluster, generate a CSR using its key with openssl req.

    openssl req -new -sha256 \
       -key ./certs/{cluster-X-cert-key}.key \
       -subj /C={cert country}/ST={cert state}/O={organization} \
       -out ./certs/{cluster-X-cert-signing}.csr
    
  5. For each member cluster, using the generated CA key, root certificate, and the CSR, generate a server certificate. The following procedure uses openssl req in combination with bash -extfile and printf to first contstruct a subjectAltName parameter, and then inject it via printf as the value into bash -extfile.

    bash -c openssl x509 -req \
         -extfile <(printf "subjectAltName=DNS:{resource name}-{cluster index}-{host index}-svc.mongodb.svc.cluster.local") \
         -days 365 \
         -in ./certs/{cluster-X-cert-signing}.csr \
         -CA ./certs/ca.crt \
         -CAkey ./certs/ca.key \
         -CAcreateserial \
         -out ./certs/{resource name}-{cluster index}-{host index}.crt
    
2

Create a ConfigMap that contains the CA root certificate.

Run the following command on each member cluster to create a ConfigMap that contains the CA root certificate:

kubectl \
  --context=$MDB_CLUSTER_1_FULL_NAME \
  --namespace=mongodb \
  create configmap issuer-ca \
    --from-literal ca-pem="$(< ./certs/ca.crt)" \
    --from-literal mms-ca.crt="$(< ./certs/ca.crt)"
kubectl \
  --context=$MDB_CLUSTER_2_FULL_NAME \
  --namespace=mongodb \
  create configmap issuer-ca \
    --from-literal ca-pem="$(< ./certs/ca.crt)" \
    --from-literal mms-ca.crt="$(< ./certs/ca.crt)"
kubectl \
  --context=$MDB_CLUSTER_3_FULL_NAME \
  --namespace=mongodb \
  create configmap issuer-ca \
    --from-literal ca-pem="$(< ./certs/ca.crt)" \
    --from-literal mms-ca.crt="$(< ./certs/ca.crt)"
3

Create a certificate secret for each member cluster.

For each member cluster, create a cluster certificate secret of the type generic named clustercert-{resource name}-cert with all server certificates generated in step 2 of this procedure.

For example, if the first and third member clusters are three-node MongoDB replica sets, and the second member cluster has two MongoDB nodes, to to create a cluster certificate secret on $MDB_CLUSTER_1_FULL_NAME, run the following command:

kubectl \
  --context=$MDB_CLUSTER_1_FULL_NAME \
  --namespace=mongodb \
  create secret clustercert-{resource name}-cert \
  --from-literal {resource name}-0-0-pem="$(< ./certs/{cluster-0-cert-key}.key)\$(< ./certs/{resource name}-0-0.crt)" \
  --from-literal {resource name}-0-1-pem="$(< ./certs/{cluster-0-cert-key}.key)\$(< ./certs/{resource name}-0-1.crt)" \
  --from-literal {resource name}-0-2-pem="$(< ./certs/{cluster-0-cert-key}.key)\$(< ./certs/{resource name}-0-2.crt)" \
  --from-literal {resource name}-1-0-pem="$(< ./certs/{cluster-1-cert-key}.key)\$(< ./certs/{resource name}-1-0.crt)" \
  --from-literal {resource name}-1-1-pem="$(< ./certs/{cluster-1-cert-key}.key)\$(< ./certs/{resource name}-1-1.crt)" \
  --from-literal {resource name}-2-0-pem="$(< ./certs/{cluster-2-cert-key}.key)\$(< ./certs/{resource name}-2-0.crt)" \
  --from-literal {resource name}-2-1-pem="$(< ./certs/{cluster-2-cert-key}.key)\$(< ./certs/{resource name}-2-1.crt)" \
  --from-literal {resource name}-2-2-pem="$(< ./certs/{cluster-2-cert-key}.key)\$(< ./certs/{resource name}-2-2.crt)"

The commands in this step lead to the following results:

  • The cluster certificate secret contains all server certificates generated in Step 2 of this procedure.

  • Each member cluster’s host contains a corresponding secret key, resource name-cluster index-host index-pem.

    This key contains a server certificate generated for that host in Step 2, resource name-cluster index-host index.crt, concatenated with the cluster certificate key, cluster-X-cert-key.key, also generated in Step 2.

Run the same command as in the previous step for two other clusters in the example multi-cluster deployment, $MDB_CLUSTER_2_FULL_NAME and $MDB_CLUSTER_3_FULL_NAME.

4

Update the MongoDB multi-cluster resource and configure TLS options in it.

Update the MongoDB multi-cluster resource with security settings from the Kubernetes Operator MongoDB resource specification. The resulting configuration should look as follows:

spec.security:
 tls:
  ca: issuer-ca
  enabled: true
  secretRef:
   prefix: clustercert
5

Verify that the MDB resources are running.

  1. For member clusters, run the following commands to verify that the MongoDB Pods are in the running state:

    kubectl get pods \
     --context=$MDB_CLUSTER_1_FULL_NAME \
     --namespace mongodb
    
    kubectl get pods \
     --context=$MDB_CLUSTER_2_FULL_NAME \
     --namespace mongodb
    
    kubectl get pods \
     --context=$MDB_CLUSTER_3_FULL_NAME \
     --namespace mongodb
    
  2. In the central cluster, run the following commands to verify that the MongoDBMulti CustomResource is in the running state:

    kubectl --context=$MDB_CENTRAL_CLUSTER_FULL_NAME \
      --namespace mongodb \
      get mdbm multi-replica-set -o yaml -w