New to KubeDB? Please start here.
Run MongoDB with TLS/SSL (Transport Encryption)
KubeDB supports providing TLS/SSL encryption (via, sslMode
and clusterAuthMode
) for MongoDB. This tutorial will show you how to use KubeDB to run a MongoDB database with TLS/SSL encryption.
Before You Begin
At first, you need to have a Kubernetes cluster, and the kubectl command-line tool must be configured to communicate with your cluster. If you do not already have a cluster, you can create one by using kind.
Install
cert-manger
v1.0.0 or later to your cluster to manage your SSL/TLS certificates.Now, install KubeDB cli on your workstation and KubeDB operator in your cluster following the steps here.
To keep things isolated, this tutorial uses a separate namespace called
demo
throughout this tutorial.$ kubectl create ns demo namespace/demo created
Note: YAML files used in this tutorial are stored in docs/examples/mongodb folder in GitHub repository kubedb/docs.
Overview
KubeDB uses following crd fields to enable SSL/TLS encryption in Mongodb.
spec:
sslMode
tls:
issuerRef
certificate
clusterAuthMode
Read about the fields in details in mongodb concept,
sslMode
, and tls
is applicable for all types of MongoDB (i.e., standalone
, replicaset
and sharding
), while clusterAuthMode
provides ClusterAuthMode for MongoDB clusters (i.e., replicaset
and sharding
).
When, SSLMode is anything other than disabled
, users must specify the tls.issuerRef
field. KubeDB uses the issuer
or clusterIssuer
referenced in the tls.issuerRef
field, and the certificate specs provided in tls.certificate
to generate certificate secrets. These certificate secrets are then used to generate required certificates including ca.crt
, mongo.pem
and client.pem
.
The subject of client.pem
certificate is added as root
user in $external
mongodb database. So, user can use this client certificate for MONGODB-X509
authenticationMechanism
.
Create Issuer/ ClusterIssuer
We are going to create an example Issuer
that will be used throughout the duration of this tutorial to enable SSL/TLS in MongoDB. Alternatively, you can follow this cert-manager tutorial to create your own Issuer
.
- Start off by generating you ca certificates using openssl.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=mongo/O=kubedb"
- Now create a ca-secret using the certificate files you have just generated.
kubectl create secret tls mongo-ca \
--cert=ca.crt \
--key=ca.key \
--namespace=demo
Now, create an Issuer
using the ca-secret
you have just created. The YAML
file looks like this:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: mongo-ca-issuer
namespace: demo
spec:
ca:
secretName: mongo-ca
Apply the YAML
file:
$ kubectl create -f https://github.com/kubedb/docs/raw/v2024.11.18/docs/examples/mongodb/tls/issuer.yaml
issuer.cert-manager.io/mongo-ca-issuer created
TLS/SSL encryption in MongoDB Sharding
Below is the YAML for MongoDB Sharding. Here, spec.sslMode
specifies sslMode
for sharding
and spec.clusterAuthMode
provides clusterAuthMode
for sharding servers.
apiVersion: kubedb.com/v1
kind: MongoDB
metadata:
name: mongo-sh-tls
namespace: demo
spec:
version: "4.4.26"
sslMode: requireSSL
tls:
issuerRef:
apiGroup: "cert-manager.io"
kind: Issuer
name: mongo-ca-issuer
clusterAuthMode: x509
shardTopology:
configServer:
replicas: 2
storage:
resources:
requests:
storage: 1Gi
storageClassName: standard
mongos:
replicas: 2
shard:
replicas: 2
shards: 2
storage:
resources:
requests:
storage: 1Gi
storageClassName: standard
storageType: Durable
deletionPolicy: WipeOut
Deploy MongoDB Sharding
$ kubectl create -f https://github.com/kubedb/docs/raw/v2024.11.18/docs/examples/mongodb/tls/mg-shard-ssl.yaml
mongodb.kubedb.com/mongo-sh-tls created
Now, wait until mongo-sh-tls created
has status Ready
. ie,
$ watch kubectl get mg -n demo
Every 2.0s: kubectl get mongodb -n demo
NAME VERSION STATUS AGE
mongo-sh-tls 4.4.26 Ready 4m24s
Verify TLS/SSL in MongoDB Sharding
Now, connect to mongos
component of this database through mongo-shell and verify if SSLMode
and ClusterAuthMode
has been set up as intended.
$ kubectl describe secret -n demo mongo-sh-tls-client-cert
Name: mongo-sh-tls-client-cert
Namespace: demo
Labels: <none>
Annotations: cert-manager.io/alt-names:
cert-manager.io/certificate-name: mongo-sh-tls-client-cert
cert-manager.io/common-name: root
cert-manager.io/ip-sans:
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: Issuer
cert-manager.io/issuer-name: mongo-ca-issuer
cert-manager.io/uri-sans:
Type: kubernetes.io/tls
Data
====
ca.crt: 1147 bytes
tls.crt: 1172 bytes
tls.key: 1679 bytes
Now, Let’s exec into a mongodb container and find out the username to connect in a mongo shell,
$ kubectl exec -it mongo-sh-tls-mongos-0 -n demo bash
root@mongo-sh-tls-mongos-0:/$ ls /var/run/mongodb/tls
ca.crt client.pem mongo.pem
mongodb@mgo-sh-tls-mongos-0:/$ openssl x509 -in /var/run/mongodb/tls/client.pem -inform PEM -subject -nameopt RFC2253 -noout
subject=CN=root,O=kubedb
Now, we can connect using CN=root,O=kubedb
as root to connect to the mongo shell,
root@mongo-sh-tls-mongos-0:/# mongo --tls --tlsCAFile /var/run/mongodb/tls/ca.crt --tlsCertificateKeyFile /var/run/mongodb/tls/client.pem admin --host localhost --authenticationMechanism MONGODB-X509 --authenticationDatabase='$external' -u "CN=root,O=kubedb" --quiet
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
mongos>
We are connected to the mongo shell. Let’s run some command to verify the sslMode and the user,
mongos> db.adminCommand({ getParameter:1, sslMode:1 })
{
"sslMode" : "requireSSL",
"ok" : 1,
"operationTime" : Timestamp(1599491398, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1599491398, 1),
"signature" : {
"hash" : BinData(0,"cn2Mhfy2blonon3jPz6Daen0nnc="),
"keyId" : NumberLong("6869760899591176209")
}
}
}
mongos> use $external
switched to db $external
mongos> show users
{
"_id" : "$external.CN=root,O=kubedb",
"userId" : UUID("4865dda6-5e31-4b79-a085-7d6fea51c9be"),
"user" : "CN=root,O=kubedb",
"db" : "$external",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
],
"mechanisms" : [
"external"
]
}
> exit
bye
You can see here that, sslMode
is set to requireSSL
and clusterAuthMode
is set to x509
and also an user is created in $external
with name "CN=root,O=kubedb"
.
Changing the SSLMode & ClusterAuthMode
User can update sslMode
& ClusterAuthMode
if needed. Some changes may be invalid from mongodb end, like using sslMode: disabled
with clusterAuthMode: x509
.
The good thing is, KubeDB operator will throw error for invalid SSL specs while creating/updating the MongoDB object. i.e.,
$ kubectl patch -n demo mg/mgo-sh-tls -p '{"spec":{"sslMode": "disabled","clusterAuthMode": "x509"}}' --type="merge"
Error from server (Forbidden): admission webhook "mongodb.validators.kubedb.com" denied the request: can't have disabled set to mongodb.spec.sslMode when mongodb.spec.clusterAuthMode is set to x509
To update from Keyfile Authentication to x.509 Authentication, change the sslMode
and clusterAuthMode
in recommended sequence as suggested in official documentation. Each time after changing the specs, follow the procedure that is described above to verify the changes of sslMode
and clusterAuthMode
inside the database.
Cleaning up
To cleanup the Kubernetes resources created by this tutorial, run:
kubectl delete mongodb -n demo mongo-sh-tls
kubectl delete issuer -n demo mongo-ca-issuer
kubectl delete ns demo
Next Steps
- Detail concepts of MongoDB object.
- Backup and Restore MongoDB databases using Stash.
- Initialize MongoDB with Script.
- Monitor your MongoDB database with KubeDB using out-of-the-box Prometheus operator.
- Monitor your MongoDB database with KubeDB using out-of-the-box builtin-Prometheus.
- Use private Docker registry to deploy MongoDB with KubeDB.
- Use kubedb cli to manage databases like kubectl for Kubernetes.
- Detail concepts of MongoDB object.
- Want to hack on KubeDB? Check our contribution guidelines.