New to KubeDB? Please start here.
Run FerretDB with TLS/SSL (Transport Encryption)
KubeDB supports providing TLS/SSL encryption (via, sslMode
) for FerretDB. This tutorial will show you how to use KubeDB to run a FerretDB 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/ferretdb folder in GitHub repository kubedb/docs.
Overview
KubeDB uses following crd fields to enable SSL/TLS encryption in Mongodb.
spec:
sslMode
tls:
issuerRef
certificate
Read about the fields in details in ferretdb concept,
sslMode
enables TLS/SSL or mixed TLS/SSL used for all network connections. The value of sslMode
field can be one of the following:
Value | Description |
---|---|
disabled | The server does not use TLS/SSL. |
requireSSL | The server uses and accepts only TLS/SSL encrypted connections. |
The specified ssl mode will be used by health checker and exporter of FerretDB.
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.pem
, tls.crt
and tls.key
.
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 FerretDB. 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=ferretdb/O=kubedb"
- Now create a ca-secret using the certificate files you have just generated.
kubectl create secret tls ferretdb-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: ferretdb-ca-issuer
namespace: demo
spec:
ca:
secretName: ferretdb-ca
Apply the YAML
file:
$ kubectl create -f https://github.com/kubedb/docs/raw/v2024.12.18/docs/examples/ferretdb/tls/issuer.yaml
issuer.cert-manager.io/ferretdb-ca-issuer created
TLS/SSL encryption in FerretDB
Below is the YAML for FerretDB with TLS enabled. Backend Postgres will automatically managed by KubeDB:
apiVersion: kubedb.com/v1alpha2
kind: FerretDB
metadata:
name: fr-tls
namespace: demo
spec:
version: "1.23.0"
authSecret:
externallyManaged: false
storage:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 500Mi
backend:
externallyManaged: false
deletionPolicy: WipeOut
replicas: 1
sslMode: requireSSL
tls:
issuerRef:
apiGroup: "cert-manager.io"
kind: Issuer
name: ferretdb-ca-issuer
Deploy FerretDB
$ kubectl create -f https://github.com/kubedb/docs/raw/v2024.12.18/docs/examples/ferretdb/tls/ferretdb-tls.yaml
ferretdb.kubedb.com/fr-tls created
Now, wait until fr-tls created
has status Ready
. i.e,
$ watch kubectl get fr -n demo
Every 2.0s: kubectl get ferretdb -n demo
NAME TYPE VERSION STATUS AGE
fr-tls kubedb.com/v1alpha2 1.23.0 Ready 60s
Verify TLS/SSL in FerretDB
Now, connect to this database through mongosh and verify if SSLMode
has been set up as intended (i.e, require
).
$ kubectl describe secret -n demo fr-tls-client-cert
Name: fr-tls-client-cert
Namespace: demo
Labels: app.kubernetes.io/component=database
app.kubernetes.io/instance=fr-tls
app.kubernetes.io/managed-by=kubedb.com
app.kubernetes.io/name=ferretdbs.kubedb.com
controller.cert-manager.io/fao=true
Annotations: cert-manager.io/alt-names:
cert-manager.io/certificate-name: fr-tls-client-cert
cert-manager.io/common-name: fr-tls
cert-manager.io/ip-sans:
cert-manager.io/issuer-group: cert-manager.io
cert-manager.io/issuer-kind: Issuer
cert-manager.io/issuer-name: ferretdb-ca-issuer
cert-manager.io/subject-organizationalunits: client
cert-manager.io/subject-organizations: kubedb
cert-manager.io/uri-sans:
Type: kubernetes.io/tls
Data
====
ca.crt: 1155 bytes
tls.crt: 1176 bytes
tls.key: 1679 bytes
Now we need save the client cert and key to two different files and make a pem file. Additionally, to verify server, we need to store ca.crt.
$ kubectl get secrets -n demo fr-tls-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt
$ kubectl get secrets -n demo fr-tls-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key
$ kubectl get secrets -n demo fr-tls-client-cert -o jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
$ cat client.crt client.key > client.pem
Now, we can connect to our FerretDB with these files with mongosh client.
$ kubectl get secrets -n demo fr-tls-auth -o jsonpath='{.data.\username}' | base64 -d
postgres
$ kubectl get secrets -n demo fr-tls-auth -o jsonpath='{.data.\\password}' | base64 -d
l*jGp8u*El8WRSDJ
$ kubectl port-forward svc/fr-tls -n demo 27017
Forwarding from 127.0.0.1:27017 -> 27018
Forwarding from [::1]:27017 -> 27018
Handling connection for 27017
Handling connection for 27017
Now in another terminal
$ mongosh 'mongodb://postgres:l*jGp8u*El8WRSDJ@localhost:27017/ferretdb?authMechanism=PLAIN&tls=true&tlsCertificateKeyFile=./client.pem&tlsCaFile=./ca.crt'
Current Mongosh Log ID: 65efeea2a3347fff66d04c70
Connecting to: mongodb://<credentials>@localhost:27017/ferretdb?authMechanism=PLAIN&directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.1.5
Using MongoDB: 7.0.42
Using Mongosh: 2.1.5
For mongosh info see: https://docs.mongodb.com/mongodb-shell/
------
The server generated these startup warnings when booting
2024-03-12T05:56:50.979Z: Powered by FerretDB v1.23.0 and PostgreSQL 13.13 on x86_64-pc-linux-musl, compiled by gcc.
2024-03-12T05:56:50.979Z: Please star us on GitHub: https://github.com/FerretDB/FerretDB.
2024-03-12T05:56:50.979Z: The telemetry state is undecided.
2024-03-12T05:56:50.979Z: Read more about FerretDB telemetry and how to opt out at https://beacon.ferretdb.io.
------
ferretdb>
So our connection is now tls encrypted.
Cleaning up
To clean up the Kubernetes resources created by this tutorial, run:
kubectl delete ferretdb -n demo fr-tls
kubectl delete issuer -n demo ferretdb-ca-issuer
kubectl delete ns demo
Next Steps
- Detail concepts of FerretDB object.
- Detail concepts of FerretDBVersion object.
- Monitor your FerretDB database with KubeDB using out-of-the-box Prometheus operator.
- Monitor your FerretDB database with KubeDB using out-of-the-box builtin-Prometheus.
- Want to hack on KubeDB? Check our contribution guidelines.