You are looking at the documentation of a prior release. To read the documentation of the latest release, please
visit here.
New to KubeDB? Please start here.
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.
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 minikube.
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.
KubeDB uses following fields to set SSLMode
& ClusterAuthMode
in Mongodb to achieve SSL/TLS encryption.
spec:
sslMode
clusterAuthMode
Read about the fields in details in mongodb concept,
sslMode
is applicable for all kind 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
, kubedb will create a certificate secret where all the required certificates are given including ca.cert
, ca.key
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
.
Below is the YAML for MongoDB Standalone. Here, spec.sslMode
specifies sslMode
for standalone
(which is requireSSL
).
apiVersion: kubedb.com/v1alpha1
kind: MongoDB
metadata:
name: mgo-tls
namespace: demo
spec:
version: "3.6-v4"
sslMode: requireSSL
storage:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
$ kubectl create -f ./docs/examples/mongodb/tls-ssl-encryption/tls-standalone.yaml
mongodb.kubedb.com/mgo-tls created
Now, wait until mgo-tls created
has status Running
. i.e,
$ kubectl get mg -n demo
NAME VERSION STATUS AGE
mgo-tls 3.6-v4 Running 20s
Now, connect to this database through mongo-shell and verify if SSLMode
has been set up as intended (i.e, requireSSL
).
$ kubectl describe secret -n demo mgo-tls-cert
Name: mgo-tls-cert
Namespace: demo
Labels: app.kubernetes.io/component=database
app.kubernetes.io/instance=mgo-tls
app.kubernetes.io/managed-by=kubedb.com
app.kubernetes.io/name=mongodb
app.kubernetes.io/version=3.6-v4
kubedb.com/kind=MongoDB
kubedb.com/name=mgo-tls
Annotations: <none>
Type: Opaque
Data
====
ca.cert: 1058 bytes
ca.key: 1679 bytes
client.pem: 2859 bytes
key.txt: 1008 bytes
mongo.pem: 2863 bytes
$ kubectl exec -it mgo-tls-0 -n demo bash
mongodb@mgo-tls-0: # you are into container
mongodb@mgo-tls-0:/$ ls /data/configdb/
ca.cert ca.key client.pem key.txt mongo.pem mongod.conf
mongodb@mgo-tls-0:/$ openssl x509 -in /data/configdb/client.pem -inform PEM -subject -nameopt RFC2253 -noout
subject= CN=root,O=kubedb:client
# Now use CN=root,O=kubedb:client as root
mongodb@mgo-tls-0:/$ mongo --ssl --sslCAFile /data/configdb/ca.cert --sslPEMKeyFile /data/configdb/client.pem admin --host localhost --authenticationMechanism MONGODB-X509 --authenticationDatabase='$external' -u "CN=root,O=kubedb:client"
MongoDB shell version v3.6.13
connecting to: mongodb://localhost:27017/admin?authMechanism=MONGODB-X509&authSource=%24external&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("67cc3683-89ac-4198-9a93-a793c257e838") }
MongoDB server version: 3.6.13
Welcome to the MongoDB shell.
> #you are connected to mongo cli
> db.adminCommand({ getParameter:1, sslMode:1 })
{ "sslMode" : "requireSSL", "ok" : 1 }
> use $external
switched to db $external
> show users
{
"_id" : "$external.CN=root,O=kubedb:client",
"userId" : UUID("3c0a008e-f1db-4412-b993-996eb0937554"),
"user" : "CN=root,O=kubedb:client",
"db" : "$external",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
> exit
bye
You can see here that, sslMode
is set to requireSSL
and also an user is created in $external
with name "CN=root,O=kubedb:client"
.
Below is the YAML for MongoDB Replicaset. Here, spec.sslMode
specifies sslMode
for replicaset
(which is requireSSL
) and spec.clusterAuthMode
provides clusterAuthMode
for mongodb replicaset nodes (which is x509
).
apiVersion: kubedb.com/v1alpha1
kind: MongoDB
metadata:
name: mgo-rs-tls
namespace: demo
spec:
version: "3.6-v4"
sslMode: requireSSL
clusterAuthMode: x509
replicas: 4
replicaSet:
name: rs0
storage:
storageClassName: "standard"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
$ kubectl create -f ./docs/examples/mongodb/tls-ssl-encryption/tls-replicaset.yaml
mongodb.kubedb.com/mgo-rs-tls created
Now, wait until mgo-rs-tls created
has status Running
. i.e,
$ kubectl get mg -n demo
NAME VERSION STATUS AGE
mgo-rs-tls 3.6-v4 Running 2m31s
Now, connect to this database through mongo-shell and verify if SSLMode
and ClusterAuthMode
has been set up as intended.
$ kubectl describe secret -n demo mgo-rs-tls-cert
Name: mgo-rs-tls-cert
Namespace: demo
Labels: app.kubernetes.io/component=database
app.kubernetes.io/instance=mgo-rs-tls
app.kubernetes.io/managed-by=kubedb.com
app.kubernetes.io/name=mongodb
app.kubernetes.io/version=3.6-v4
kubedb.com/kind=MongoDB
kubedb.com/name=mgo-rs-tls
Annotations: <none>
Type: Opaque
Data
====
ca.cert: 1058 bytes
ca.key: 1675 bytes
client.pem: 2867 bytes
key.txt: 1008 bytes
$ kubectl exec -it mgo-rs-tls-0 -n demo bash
mongodb@mgo-rs-tls-0: # you are into container
mongodb@mgo-rs-tls-0:/$ ls /data/configdb/
ca.cert ca.key ca.srl client.pem key.txt mongo.pem mongod.conf
mongodb@mgo-rs-tls-0:/$ openssl x509 -in /data/configdb/client.pem -inform PEM -subject -nameopt RFC2253 -noout
subject= CN=root,O=kubedb:client
# Now use CN=root,O=kubedb:client as root
mongodb@mgo-rs-tls-0:/$ mongo --ssl --sslCAFile /data/configdb/ca.cert --sslPEMKeyFile /data/configdb/client.pem admin --host localhost --authenticationMechanism MONGODB-X509 --authenticationDatabase='$external' -u "CN=root,O=kubedb:client"
MongoDB shell version v3.6.13
connecting to: mongodb://localhost:27017/admin?authMechanism=MONGODB-X509&authSource=%24external&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("c93e3e52-4b35-4d45-8c42-2d6ed3eb0ed8") }
MongoDB server version: 3.6.13
Welcome to the MongoDB shell.
rs0:PRIMARY> #you are connected to mongo cli
rs0:PRIMARY> db.adminCommand({ getParameter:1, sslMode:1 })
{
"sslMode" : "requireSSL",
"ok" : 1,
"operationTime" : Timestamp(1564746095, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1564746095, 1),
"signature" : {
"hash" : BinData(0,"29XpLUr5ZaWhAjadOvzosW2CMsU="),
"keyId" : NumberLong("6720531552222052354")
}
}
}
rs0:PRIMARY> db.adminCommand({ getParameter:1, clusterAuthMode:1 })
{
"clusterAuthMode" : "x509",
"ok" : 1,
"operationTime" : Timestamp(1564746155, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1564746155, 1),
"signature" : {
"hash" : BinData(0,"D2kt9g/RsktDNJf0qM7NP9CUdX0="),
"keyId" : NumberLong("6720531552222052354")
}
}
}
rs0:PRIMARY> use $external
switched to db $external
rs0:PRIMARY> show users
{
"_id" : "$external.CN=root,O=kubedb:client",
"userId" : UUID("a7f56f70-cd90-4ea8-846a-1a64736d44c8"),
"user" : "CN=root,O=kubedb:client",
"db" : "$external",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
rs0:PRIMARY> exit
bye
You can see here that, sslMode
is set to requireSSL
& clusterAuthMode
is set to x509
and also an user is created in $external
with name "CN=root,O=kubedb:client"
.
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/v1alpha1
kind: MongoDB
metadata:
name: mongo-sh-tls
namespace: demo
spec:
version: 3.6-v4
sslMode: requireSSL
clusterAuthMode: x509
shardTopology:
configServer:
replicas: 3
storage:
resources:
requests:
storage: 1Gi
storageClassName: standard
mongos:
replicas: 2
strategy:
type: RollingUpdate
shard:
replicas: 3
shards: 3
storage:
resources:
requests:
storage: 1Gi
storageClassName: standard
updateStrategy:
type: RollingUpdate
storageType: Durable
terminationPolicy: WipeOut
$ kubectl create -f ./docs/examples/mongodb/tls-ssl-encryption/tls-sharding.yaml
mongodb.kubedb.com/mongo-sh-tls created
Now, wait until mongo-sh-tls created
has status Running
. ie,
$ kubectl get mg -n demo
NAME VERSION STATUS AGE
mongo-sh-tls 3.6-v4 Running 9m34s
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-cert
Name: mongo-sh-tls-cert
Namespace: demo
Labels: app.kubernetes.io/component=database
app.kubernetes.io/instance=mongo-sh-tls
app.kubernetes.io/managed-by=kubedb.com
app.kubernetes.io/name=mongodb
app.kubernetes.io/version=3.6-v4
kubedb.com/kind=MongoDB
kubedb.com/name=mongo-sh-tls
Annotations: <none>
Type: Opaque
Data
====
ca.cert: 1058 bytes
ca.key: 1675 bytes
client.pem: 2879 bytes
key.txt: 1008 bytes
$ kubectl get po -n demo -l mongodb.kubedb.com/node.mongos=mongo-sh-tls-mongos
NAME READY STATUS RESTARTS AGE
mongo-sh-tls-mongos-5958559b5d-5vrjm 1/1 Running 0 87s
mongo-sh-tls-mongos-5958559b5d-hckn7 1/1 Running 0 87s
$ kubectl exec -it mongo-sh-tls-mongos-5958559b5d-5vrjm -n demo bash
mongodb@mongo-sh-tls-mongos-5958559b5d-5vrjm: # you are into container
mongodb@mongo-sh-tls-mongos-5958559b5d-5vrjm:/$ ls /data/configdb/
ca.cert ca.key ca.srl client.pem key.txt mongo.pem mongod.conf
mongodb@mongo-sh-tls-mongos-5958559b5d-5vrjm:/$ openssl x509 -in /data/configdb/client.pem -inform PEM -subject -nameopt RFC2253 -noout
subject= CN=root,O=kubedb:client
# Now use CN=root,O=kubedb:client as root
mongodb@mongo-sh-tls-mongos-5958559b5d-5vrjm:/$ mongo --ssl --sslCAFile /data/configdb/ca.cert --sslPEMKeyFile /data/configdb/client.pem admin --host localhost --authenticationMechanism MONGODB-X509 --authenticationDatabase='$external' -u "CN=root,O=kubedb:client"
MongoDB shell version v3.6.13
connecting to: mongodb://localhost:27017/admin?authMechanism=MONGODB-X509&authSource=%24external&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("2294dbeb-58f1-4a52-8087-f5216e45ae81") }
MongoDB server version: 3.6.13
Welcome to the MongoDB shell.
mongos> #you are connected to mongo cli
mongos> db.adminCommand({ getParameter:1, sslMode:1 })
{
"sslMode" : "requireSSL",
"ok" : 1,
"operationTime" : Timestamp(1564746593, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1564746593, 1),
"signature" : {
"hash" : BinData(0,"YdSBHQ7MzeOSu3gGkfEkY72s9O4="),
"keyId" : NumberLong("6720534043303084058")
}
}
}
mongos> db.adminCommand({ getParameter:1, clusterAuthMode:1 })
{
"clusterAuthMode" : "x509",
"ok" : 1,
"operationTime" : Timestamp(1564746603, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1564746603, 1),
"signature" : {
"hash" : BinData(0,"SnyfGLtvJE7v+64VOcOGk35cIMM="),
"keyId" : NumberLong("6720534043303084058")
}
}
}
mongos> use $external
switched to db $external
mongos> show users
{
"_id" : "$external.CN=root,O=kubedb:client",
"userId" : UUID("37703dcf-a71f-4611-b15f-7a2726921a25"),
"user" : "CN=root,O=kubedb:client",
"db" : "$external",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
mongos> exit
bye
You can see here that, sslMode
is set to requireSSL
& clusterAuthMode
is set to x509
and also an user is created in $external
with name "CN=root,O=kubedb:client"
.
User can update sslMode
& ClusterAuthMode
if needed. Some changes may be invalid from mongodb end, like using sslMode: disabled
with clusterAuthMode: x509
.
Good thing is, KubeDB webhook will throw error for invalid SSL specs while creating/updating the mongodb crd object. i.e.,
$ kubectl patch -n demo mg/mgo-rs-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 Upgrade 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.
To cleanup the Kubernetes resources created by this tutorial, run:
kubectl patch -n demo mg/mgo-rs-tls mg/mgo-tls mg/mongo-sh-tls -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge"
kubectl delete -n demo mg/mgo-rs-tls mg/mgo-tls mg/mongo-sh-tls
kubectl patch -n demo drmn/mgo-rs-tls drmn/mgo-tls drmn/mongo-sh-tls -p '{"spec":{"wipeOut":true}}' --type="merge"
kubectl delete -n demo drmn/mgo-rs-tls drmn/mgo-tls drmn/mongo-sh-tls
kubectl delete ns demo