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.

Reconfigure FerretDB TLS/SSL (Transport Encryption)

KubeDB supports reconfigure i.e. add, remove, update and rotation of TLS/SSL certificates for existing FerretDB database via a FerretDBOpsRequest. This tutorial will show you how to use KubeDB to reconfigure 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.

Add TLS to a FerretDB

Here, We are going to create a FerretDB database without TLS and then reconfigure the ferretdb to use TLS.

Deploy FerretDB without TLS

In this section, we are going to deploy a FerretDB without TLS. In the next few sections we will reconfigure TLS using FerretDBOpsRequest CRD. Below is the YAML of the FerretDB CR that we are going to create,

apiVersion: kubedb.com/v1alpha2
kind: FerretDB
metadata:
  name: ferretdb
  namespace: demo
spec:
  version: "2.0.0"
  backend:
    storage:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 500Mi
  server:
    primary:
      replicas: 2

Let’s create the FerretDB CR we have shown above,

$ kubectl create -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/ferretdb.yaml
ferretdb.kubedb.com/ferretdb created

Now, wait until ferretdb has status Ready. i.e,

$ kubectl get fr -n demo
NAME       NAMESPACE   VERSION   STATUS   AGE
ferretdb   demo        2.0.0     Ready    2m6s

$ kubectl describe fr ferretdb -n demo
Name:         ferretdb
Namespace:    demo
Labels:       <none>
Annotations:  <none>
API Version:  kubedb.com/v1alpha2
Kind:         FerretDB
Metadata:
  Creation Timestamp:  2025-04-08T04:51:30Z
  Finalizers:
    kubedb.com
  Generation:        3
  Resource Version:  61420
  UID:               0593928b-faab-42e5-b507-815db33f8656
Spec:
  Auth Secret:
    Name:           ferretdb-auth
  Deletion Policy:  WipeOut
  Health Checker:
    Failure Threshold:  1
    Period Seconds:     10
    Timeout Seconds:    10
  Server:
    Primary:
      Pod Template:
        Controller:
        Metadata:
        Spec:
          Containers:
            Name:  ferretdb
            Resources:
              Limits:
                Memory:  1Gi
              Requests:
                Cpu:     500m
                Memory:  1Gi
            Security Context:
              Allow Privilege Escalation:  false
              Capabilities:
                Drop:
                  ALL
              Run As Group:     1000
              Run As Non Root:  true
              Run As User:      1000
              Seccomp Profile:
                Type:  RuntimeDefault
          Pod Placement Policy:
            Name:  default
          Security Context:
            Fs Group:  1000
      Replicas:        2
  Ssl Mode:            disabled
  Storage:
    Access Modes:
      ReadWriteOnce
    Resources:
      Requests:
        Storage:  500Mi
  Storage Type:   Durable
  Version:        2.0.0
Status:
  Conditions:
    Last Transition Time:  2025-04-08T04:51:30Z
    Message:               The KubeDB operator has started the provisioning of FerretDB: demo/ferretdb
    Observed Generation:   2
    Reason:                DatabaseProvisioningStartedSuccessfully
    Status:                True
    Type:                  ProvisioningStarted
    Last Transition Time:  2025-04-08T04:52:11Z
    Message:               All replicas are ready for FerretDB demo/ferretdb
    Observed Generation:   3
    Reason:                AllReplicasReady
    Status:                True
    Type:                  ReplicaReady
    Last Transition Time:  2025-04-08T04:52:21Z
    Message:               The FerretDB: demo/ferretdb is accepting client requests.
    Observed Generation:   3
    Reason:                DatabaseAcceptingConnectionRequest
    Status:                True
    Type:                  AcceptingConnection
    Last Transition Time:  2025-04-08T04:52:21Z
    Message:               The FerretDB: demo/ferretdb is ready.
    Observed Generation:   3
    Reason:                ReadinessCheckSucceeded
    Status:                True
    Type:                  Ready
    Last Transition Time:  2025-04-08T04:52:21Z
    Message:               The FerretDB: demo/ferretdb is successfully provisioned.
    Observed Generation:   3
    Reason:                DatabaseSuccessfullyProvisioned
    Status:                True
    Type:                  Provisioned
  Phase:                   Ready
Events:                    <none>

Create Issuer/ ClusterIssuer

Now, We are going to create an example Issuer that will be used to enable SSL/TLS in FerretDB. Alternatively, you can follow this cert-manager tutorial to create your own Issuer.

  • Start off by generating a ca certificates using openssl.
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca/O=kubedb"
Generating a RSA private key
................+++++
........................+++++
writing new private key to './ca.key'
-----
  • Now we are going to create a ca-secret using the certificate files that we have just generated.
$ kubectl create secret tls ferretdb-ca \
     --cert=ca.crt \
     --key=ca.key \
     --namespace=demo
secret/ferretdb-ca created

Now, Let’s create an Issuer using the ferretdb-ca secret that we 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

Let’s apply the YAML file:

$ kubectl create -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/issuer.yaml
issuer.cert-manager.io/ferretdb-issuer created

Create FerretDBOpsRequest

In order to add TLS to the ferretdb, we have to create a FerretDBOpsRequest CRO with our created issuer. Below is the YAML of the FerretDBOpsRequest CRO that we are going to create,

apiVersion: ops.kubedb.com/v1alpha1
kind: FerretDBOpsRequest
metadata:
  name: frops-add-tls
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: ferretdb
  tls:
    issuerRef:
      name: ferretdb-ca-issuer
      kind: Issuer
      apiGroup: "cert-manager.io"
  timeout: 5m
  apply: IfReady

Here,

  • spec.databaseRef.name specifies that we are performing reconfigure TLS operation on mg-rs database.
  • spec.type specifies that we are performing ReconfigureTLS on our database.
  • spec.tls.issuerRef specifies the issuer name, kind and api group.
  • spec.tls.certificates specifies the certificates. You can learn more about this field from here.
  • spec.tls.sslMode is the ssl mode of the server. You can see the details here.
  • The meaning of spec.timeout & spec.apply fields will be found here

Let’s create the FerretDBOpsRequest CR we have shown above,

$ kubectl apply -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/frops-add-tls.yaml
ferretdbopsrequest.ops.kubedb.com/frops-add-tls created

Verify TLS Enabled Successfully

Let’s wait for FerretDBOpsRequest to be Successful. Run the following command to watch FerretDBOpsRequest CRO,

$ watch kubectl get ferretdbopsrequest -n demo
Every 2.0s: kubectl get ferretdbopsrequest -n demo
NAME            TYPE             STATUS       AGE
frops-add-tls   ReconfigureTLS   Successful   13m

We can see from the above output that the FerretDBOpsRequest has succeeded. If we describe the FerretDBOpsRequest we will get an overview of the steps that were followed.

$ kubectl describe ferretdbopsrequest -n demo frops-add-tls
Name:         frops-add-tls
Namespace:    demo
Labels:       <none>
Annotations:  <none>
API Version:  ops.kubedb.com/v1alpha1
Kind:         FerretDBOpsRequest
Metadata:
  Creation Timestamp:  2024-10-17T11:15:12Z
  Generation:          1
  Resource Version:    159329
  UID:                 071189ab-275f-4a25-99b9-72da3fa2fb6a
Spec:
  Apply:  IfReady
  Database Ref:
    Name:   ferretdb
  Timeout:  5m
  Tls:
    Issuer Ref:
      API Group:  cert-manager.io
      Kind:       Issuer
      Name:       ferretdb-ca-issuer
  Type:           ReconfigureTLS
Status:
  Conditions:
    Last Transition Time:  2024-10-17T11:15:12Z
    Message:               FerretDB ops-request has started to reconfigure tls for FerretDB nodes
    Observed Generation:   1
    Reason:                ReconfigureTLS
    Status:                True
    Type:                  ReconfigureTLS
    Last Transition Time:  2024-10-17T11:15:15Z
    Message:               Successfully paused database
    Observed Generation:   1
    Reason:                DatabasePauseSucceeded
    Status:                True
    Type:                  DatabasePauseSucceeded
    Last Transition Time:  2024-10-17T11:15:20Z
    Message:               get certificate; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  GetCertificate
    Last Transition Time:  2024-10-17T11:15:20Z
    Message:               ready condition; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  ReadyCondition
    Last Transition Time:  2024-10-17T11:15:20Z
    Message:               issuing condition; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  IssuingCondition
    Last Transition Time:  2024-10-17T11:15:20Z
    Message:               Successfully synced all certificates
    Observed Generation:   1
    Reason:                CertificateSynced
    Status:                True
    Type:                  CertificateSynced
    Last Transition Time:  2024-10-17T11:15:25Z
    Message:               successfully reconciled the FerretDB with tls configuration
    Observed Generation:   1
    Reason:                UpdatePetSets
    Status:                True
    Type:                  UpdatePetSets
    Last Transition Time:  2024-10-17T11:15:30Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-0
    Last Transition Time:  2024-10-17T11:15:31Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-0
    Last Transition Time:  2024-10-17T11:15:35Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-0
    Last Transition Time:  2024-10-17T11:15:40Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-1
    Last Transition Time:  2024-10-17T11:15:41Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-1
    Last Transition Time:  2024-10-17T11:15:45Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-1
    Last Transition Time:  2024-10-17T11:15:50Z
    Message:               Successfully restarted all nodes
    Observed Generation:   1
    Reason:                RestartNodes
    Status:                True
    Type:                  RestartNodes
    Last Transition Time:  2024-10-17T11:15:51Z
    Message:               Successfully completed the ReconfigureTLS for FerretDB
    Observed Generation:   1
    Reason:                Successful
    Status:                True
    Type:                  Successful
  Observed Generation:     1
  Phase:                   Successful
Events:
  Type     Reason                                                       Age   From                         Message
  ----     ------                                                       ----  ----                         -------
  Normal   Starting                                                     13m   KubeDB Ops-manager Operator  Start processing for FerretDBOpsRequest: demo/frops-add-tls
  Normal   Starting                                                     13m   KubeDB Ops-manager Operator  Pausing FerretDB database: demo/ferretdb
  Normal   Successful                                                   13m   KubeDB Ops-manager Operator  Successfully paused FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-add-tls
  Warning  get certificate; ConditionStatus:True                        13m   KubeDB Ops-manager Operator  get certificate; ConditionStatus:True
  Warning  ready condition; ConditionStatus:True                        13m   KubeDB Ops-manager Operator  ready condition; ConditionStatus:True
  Warning  issuing condition; ConditionStatus:True                      13m   KubeDB Ops-manager Operator  issuing condition; ConditionStatus:True
  Warning  get certificate; ConditionStatus:True                        13m   KubeDB Ops-manager Operator  get certificate; ConditionStatus:True
  Warning  ready condition; ConditionStatus:True                        13m   KubeDB Ops-manager Operator  ready condition; ConditionStatus:True
  Warning  issuing condition; ConditionStatus:True                      13m   KubeDB Ops-manager Operator  issuing condition; ConditionStatus:True
  Normal   CertificateSynced                                            13m   KubeDB Ops-manager Operator  Successfully synced all certificates
  Normal   UpdatePetSets                                                13m   KubeDB Ops-manager Operator  successfully reconciled the FerretDB with tls configuration
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-0            13m   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-0          13m   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-0  13m   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-0
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-1            13m   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-1          13m   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-1  13m   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-1
  Normal   RestartNodes                                                 13m   KubeDB Ops-manager Operator  Successfully restarted all nodes
  Normal   Starting                                                     13m   KubeDB Ops-manager Operator  Resuming FerretDB database: demo/ferretdb
  Normal   Successful                                                   13m   KubeDB Ops-manager Operator  Successfully resumed FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-add-tls

Now let’s connect with this ferretdb with certs. 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 ferretdb-client-cert -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt
$ kubectl get secrets -n demo ferretdb-client-cert -o jsonpath='{.data.tls\.key}' | base64 -d > client.key
$ kubectl get secrets -n demo ferretdb-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 ferretdb-auth -o jsonpath='{.data.\username}' | base64 -d
postgres
$ kubectl get secrets -n demo ferretdb-auth -o jsonpath='{.data.\\password}' | base64 -d
l*jGp8u*El8WRSDJ

$ kubectl port-forward svc/ferretdb -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?tls=true&tlsCertificateKeyFile=./client.pem&tlsCaFile=./ca.crt'
Current Mongosh Log ID:	67f4b15dae8697b1fa6b140a
Connecting to:		mongodb://<credentials>@localhost:27017/ferretdb?tls=true&tlsCertificateKeyFile=.%2Fclient.pem&tlsCaFile=.%2Fca.crt&directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.4.2
Using MongoDB:		7.0.77
Using Mongosh:		2.4.2

For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/

------
   The server generated these startup warnings when booting
   2025-04-08T05:17:18.084Z: Powered by FerretDB v2.0.0-1-g7fb2c9a8 and DocumentDB 0.102.0 (PostgreSQL 17.4).
   2025-04-08T05:17:18.084Z: Please star 🌟 us on GitHub: https://github.com/FerretDB/FerretDB and https://github.com/microsoft/documentdb.
   2025-04-08T05:17:18.084Z: The telemetry state is undecided. Read more about FerretDB telemetry and how to opt out at https://beacon.ferretdb.com.
------

ferretdb> 

So, here we have connected using the client certificate and the connection is tls secured. So, we can safely assume that tls enabling was successful.

Rotate Certificate

Now we are going to rotate the certificate of this database. First we can store the current expiration date of the certificate by exec into ferretdb-0 pod. Certs are located in /etc/certs/server/ path.

Create FerretDBOpsRequest

Now we are going to increase it using a FerretDBOpsRequest. Below is the yaml of the ops request that we are going to create,

apiVersion: ops.kubedb.com/v1alpha1
kind: FerretDBOpsRequest
metadata:
  name: frops-rotate
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: ferretdb
  tls:
    rotateCertificates: true

Here,

  • spec.databaseRef.name specifies that we are performing reconfigure TLS operation on ferretdb.
  • spec.type specifies that we are performing ReconfigureTLS on our ferretdb.
  • spec.tls.rotateCertificates specifies that we want to rotate the certificate of this ferretdb.

Let’s create the FerretDBOpsRequest CR we have shown above,

$ kubectl apply -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/frops-rotate.yaml
ferretdbopsrequest.ops.kubedb.com/frops-rotate created

Verify Certificate Rotated Successfully

Let’s wait for FerretDBOpsRequest to be Successful. Run the following command to watch FerretDBOpsRequest CRO,

$ watch kubectl get ferretdbopsrequest -n demo
Every 2.0s: kubectl get ferretdbopsrequest -n demo
NAME           TYPE             STATUS       AGE
frops-rotate   ReconfigureTLS   Successful   113s

We can see from the above output that the FerretDBOpsRequest has succeeded. If we describe the FerretDBOpsRequest we will get an overview of the steps that were followed.

$ kubectl describe ferretdbopsrequest -n demo frops-rotate
Name:         frops-rotate
Namespace:    demo
Labels:       <none>
Annotations:  <none>
API Version:  ops.kubedb.com/v1alpha1
Kind:         FerretDBOpsRequest
Metadata:
  Creation Timestamp:  2024-10-17T11:37:29Z
  Generation:          1
  Resource Version:    161772
  UID:                 6d9acf23-2701-40f9-9187-da221f3e4158
Spec:
  Apply:  IfReady
  Database Ref:
    Name:  ferretdb
  Tls:
    Rotate Certificates:  true
  Type:                   ReconfigureTLS
Status:
  Conditions:
    Last Transition Time:  2024-10-17T11:37:29Z
    Message:               FerretDB ops-request has started to reconfigure tls for FerretDB nodes
    Observed Generation:   1
    Reason:                ReconfigureTLS
    Status:                True
    Type:                  ReconfigureTLS
    Last Transition Time:  2024-10-17T11:37:32Z
    Message:               Successfully paused database
    Observed Generation:   1
    Reason:                DatabasePauseSucceeded
    Status:                True
    Type:                  DatabasePauseSucceeded
    Last Transition Time:  2024-10-17T11:37:38Z
    Message:               get certificate; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  GetCertificate
    Last Transition Time:  2024-10-17T11:37:38Z
    Message:               ready condition; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  ReadyCondition
    Last Transition Time:  2024-10-17T11:37:38Z
    Message:               issuing condition; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  IssuingCondition
    Last Transition Time:  2024-10-17T11:37:38Z
    Message:               Successfully synced all certificates
    Observed Generation:   1
    Reason:                CertificateSynced
    Status:                True
    Type:                  CertificateSynced
    Last Transition Time:  2024-10-17T11:37:43Z
    Message:               successfully reconciled the FerretDB with tls configuration
    Observed Generation:   1
    Reason:                UpdatePetSets
    Status:                True
    Type:                  UpdatePetSets
    Last Transition Time:  2024-10-17T11:37:48Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-0
    Last Transition Time:  2024-10-17T11:37:48Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-0
    Last Transition Time:  2024-10-17T11:37:53Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-0
    Last Transition Time:  2024-10-17T11:37:58Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-1
    Last Transition Time:  2024-10-17T11:37:58Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-1
    Last Transition Time:  2024-10-17T11:38:03Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-1
    Last Transition Time:  2024-10-17T11:38:08Z
    Message:               Successfully restarted all nodes
    Observed Generation:   1
    Reason:                RestartNodes
    Status:                True
    Type:                  RestartNodes
    Last Transition Time:  2024-10-17T11:38:08Z
    Message:               Successfully completed the ReconfigureTLS for FerretDB
    Observed Generation:   1
    Reason:                Successful
    Status:                True
    Type:                  Successful
  Observed Generation:     1
  Phase:                   Successful
Events:
  Type     Reason                                                       Age   From                         Message
  ----     ------                                                       ----  ----                         -------
  Normal   Starting                                                     55s   KubeDB Ops-manager Operator  Start processing for FerretDBOpsRequest: demo/frops-rotate
  Normal   Starting                                                     55s   KubeDB Ops-manager Operator  Pausing FerretDB database: demo/ferretdb
  Normal   Successful                                                   55s   KubeDB Ops-manager Operator  Successfully paused FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-rotate
  Warning  get certificate; ConditionStatus:True                        46s   KubeDB Ops-manager Operator  get certificate; ConditionStatus:True
  Warning  ready condition; ConditionStatus:True                        46s   KubeDB Ops-manager Operator  ready condition; ConditionStatus:True
  Warning  issuing condition; ConditionStatus:True                      46s   KubeDB Ops-manager Operator  issuing condition; ConditionStatus:True
  Warning  get certificate; ConditionStatus:True                        46s   KubeDB Ops-manager Operator  get certificate; ConditionStatus:True
  Warning  ready condition; ConditionStatus:True                        46s   KubeDB Ops-manager Operator  ready condition; ConditionStatus:True
  Warning  issuing condition; ConditionStatus:True                      46s   KubeDB Ops-manager Operator  issuing condition; ConditionStatus:True
  Normal   CertificateSynced                                            46s   KubeDB Ops-manager Operator  Successfully synced all certificates
  Normal   UpdatePetSets                                                41s   KubeDB Ops-manager Operator  successfully reconciled the FerretDB with tls configuration
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-0            36s   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-0          36s   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-0  31s   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-0
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-1            26s   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-1          26s   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-1  21s   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-1
  Normal   RestartNodes                                                 16s   KubeDB Ops-manager Operator  Successfully restarted all nodes
  Normal   Starting                                                     16s   KubeDB Ops-manager Operator  Resuming FerretDB database: demo/ferretdb
  Normal   Successful                                                   16s   KubeDB Ops-manager Operator  Successfully resumed FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-rotate

As we can see from the above output, the certificate has been rotated successfully.

Change Issuer/ClusterIssuer

Now, we are going to change the issuer of this database.

  • Let’s create a new ca certificate and key using a different subject CN=ca-update,O=kubedb-updated.
$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./ca.key -out ./ca.crt -subj "/CN=ca-updated/O=kubedb-updated"
Generating a RSA private key
..............................................................+++++
......................................................................................+++++
writing new private key to './ca.key'
-----
  • Now we are going to create a new ca-secret using the certificate files that we have just generated.
$ kubectl create secret tls ferretdb-new-ca \
     --cert=ca.crt \
     --key=ca.key \
     --namespace=demo
secret/ferretdb-new-ca created

Now, Let’s create a new Issuer using the ferretdb-new-ca secret that we have just created. The YAML file looks like this:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: fr-new-issuer
  namespace: demo
spec:
  ca:
    secretName: ferretdb-new-ca

Let’s apply the YAML file:

$ kubectl create -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/new-issuer.yaml
issuer.cert-manager.io/fr-new-issuer created

Create FerretDBOpsRequest

In order to use the new issuer to issue new certificates, we have to create a FerretDBOpsRequest CRO with the newly created issuer. Below is the YAML of the FerretDBOpsRequest CRO that we are going to create,

apiVersion: ops.kubedb.com/v1alpha1
kind: FerretDBOpsRequest
metadata:
  name: frops-change-issuer
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: ferretdb
  tls:
    issuerRef:
      name: fr-new-issuer
      kind: Issuer
      apiGroup: "cert-manager.io"

Here,

  • spec.databaseRef.name specifies that we are performing reconfigure TLS operation on ferretdb.
  • spec.type specifies that we are performing ReconfigureTLS on our ferretdb.
  • spec.tls.issuerRef specifies the issuer name, kind and api group.

Let’s create the FerretDBOpsRequest CR we have shown above,

$ kubectl apply -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/frops-change-issuer.yaml
ferretdbopsrequest.ops.kubedb.com/frops-change-issuer created

Verify Issuer is changed successfully

Let’s wait for FerretDBOpsRequest to be Successful. Run the following command to watch FerretDBOpsRequest CRO,

$ watch kubectl get ferretdbopsrequest -n demo
Every 2.0s: kubectl get ferretdbopsrequest -n demo
NAME                  TYPE             STATUS       AGE
frops-change-issuer   ReconfigureTLS   Successful   87s

We can see from the above output that the FerretDBOpsRequest has succeeded. If we describe the FerretDBOpsRequest we will get an overview of the steps that were followed.

$ kubectl describe ferretdbopsrequest -n demo frops-change-issuer
Name:         frops-change-issuer
Namespace:    demo
Labels:       <none>
Annotations:  <none>
API Version:  ops.kubedb.com/v1alpha1
Kind:         FerretDBOpsRequest
Metadata:
  Creation Timestamp:  2024-10-18T10:14:38Z
  Generation:          1
  Resource Version:    423126
  UID:                 1bf730e8-603e-4f30-b9ab-5a4e75d3a4d4
Spec:
  Apply:  IfReady
  Database Ref:
    Name:  ferretdb
  Tls:
    Issuer Ref:
      API Group:  cert-manager.io
      Kind:       Issuer
      Name:       fr-new-issuer
  Type:           ReconfigureTLS
Status:
  Conditions:
    Last Transition Time:  2024-10-18T10:14:38Z
    Message:               FerretDB ops-request has started to reconfigure tls for FerretDB nodes
    Observed Generation:   1
    Reason:                ReconfigureTLS
    Status:                True
    Type:                  ReconfigureTLS
    Last Transition Time:  2024-10-18T10:14:41Z
    Message:               Successfully paused database
    Observed Generation:   1
    Reason:                DatabasePauseSucceeded
    Status:                True
    Type:                  DatabasePauseSucceeded
    Last Transition Time:  2024-10-18T10:14:46Z
    Message:               get certificate; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  GetCertificate
    Last Transition Time:  2024-10-18T10:14:46Z
    Message:               ready condition; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  ReadyCondition
    Last Transition Time:  2024-10-18T10:14:46Z
    Message:               issuing condition; ConditionStatus:True
    Observed Generation:   1
    Status:                True
    Type:                  IssuingCondition
    Last Transition Time:  2024-10-18T10:14:46Z
    Message:               Successfully synced all certificates
    Observed Generation:   1
    Reason:                CertificateSynced
    Status:                True
    Type:                  CertificateSynced
    Last Transition Time:  2024-10-18T10:14:51Z
    Message:               successfully reconciled the FerretDB with tls configuration
    Observed Generation:   1
    Reason:                UpdatePetSets
    Status:                True
    Type:                  UpdatePetSets
    Last Transition Time:  2024-10-18T10:14:56Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-0
    Last Transition Time:  2024-10-18T10:14:56Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-0
    Last Transition Time:  2024-10-18T10:15:01Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-0
    Last Transition Time:  2024-10-18T10:15:06Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-1
    Last Transition Time:  2024-10-18T10:15:06Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-1
    Last Transition Time:  2024-10-18T10:15:11Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-1
    Last Transition Time:  2024-10-18T10:15:16Z
    Message:               Successfully restarted all nodes
    Observed Generation:   1
    Reason:                RestartNodes
    Status:                True
    Type:                  RestartNodes
    Last Transition Time:  2024-10-18T10:15:16Z
    Message:               Successfully completed the ReconfigureTLS for FerretDB
    Observed Generation:   1
    Reason:                Successful
    Status:                True
    Type:                  Successful
  Observed Generation:     1
  Phase:                   Successful
Events:
  Type     Reason                                                       Age   From                         Message
  ----     ------                                                       ----  ----                         -------
  Normal   Starting                                                     88s   KubeDB Ops-manager Operator  Start processing for FerretDBOpsRequest: demo/frops-change-issuer
  Normal   Starting                                                     88s   KubeDB Ops-manager Operator  Pausing FerretDB database: demo/ferretdb
  Normal   Successful                                                   88s   KubeDB Ops-manager Operator  Successfully paused FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-change-issuer
  Warning  get certificate; ConditionStatus:True                        80s   KubeDB Ops-manager Operator  get certificate; ConditionStatus:True
  Warning  ready condition; ConditionStatus:True                        80s   KubeDB Ops-manager Operator  ready condition; ConditionStatus:True
  Warning  issuing condition; ConditionStatus:True                      80s   KubeDB Ops-manager Operator  issuing condition; ConditionStatus:True
  Warning  get certificate; ConditionStatus:True                        80s   KubeDB Ops-manager Operator  get certificate; ConditionStatus:True
  Warning  ready condition; ConditionStatus:True                        80s   KubeDB Ops-manager Operator  ready condition; ConditionStatus:True
  Warning  issuing condition; ConditionStatus:True                      80s   KubeDB Ops-manager Operator  issuing condition; ConditionStatus:True
  Normal   CertificateSynced                                            80s   KubeDB Ops-manager Operator  Successfully synced all certificates
  Normal   UpdatePetSets                                                75s   KubeDB Ops-manager Operator  successfully reconciled the FerretDB with tls configuration
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-0            70s   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-0          70s   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-0  65s   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-0
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-1            60s   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-1          60s   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-1  55s   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-1
  Normal   RestartNodes                                                 50s   KubeDB Ops-manager Operator  Successfully restarted all nodes
  Normal   Starting                                                     50s   KubeDB Ops-manager Operator  Resuming FerretDB database: demo/ferretdb
  Normal   Successful                                                   50s   KubeDB Ops-manager Operator  Successfully resumed FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-change-issuer

Now, If exec ferretdb and find out the ca subject in /etc/certs/server location, we can see that the CN and O is updated according to out new ca.crt.

We can see that subject name of this ca.crt matches the subject name of the new ca certificate that we have created. So, the issuer is changed successfully.

Remove TLS from the ferretdb

Now, we are going to remove TLS from this ferretdb using a FerretDBOpsRequest.

Create FerretDBOpsRequest

Below is the YAML of the FerretDBOpsRequest CRO that we are going to create,

apiVersion: ops.kubedb.com/v1alpha1
kind: FerretDBOpsRequest
metadata:
  name: frops-remove
  namespace: demo
spec:
  type: ReconfigureTLS
  databaseRef:
    name: ferretdb
  tls:
    remove: true

Here,

  • spec.databaseRef.name specifies that we are performing reconfigure TLS operation on ferretdb.
  • spec.type specifies that we are performing ReconfigureTLS on our ferretdb.
  • spec.tls.remove specifies that we want to remove tls from this ferretdb.

Let’s create the FerretDBOpsRequest CR we have shown above,

$ kubectl apply -f https://github.com/kubedb/docs/raw/v2025.7.30-rc.0/docs/examples/ferretdb/reconfigure-tls/frops-remove.yaml
ferretdbopsrequest.ops.kubedb.com/frops-remove created

Verify TLS Removed Successfully

Let’s wait for FerretDBOpsRequest to be Successful. Run the following command to watch FerretDBOpsRequest CRO,

$ wacth kubectl get ferretdbopsrequest -n demo
Every 2.0s: kubectl get ferretdbopsrequest -n demo
NAME           TYPE             STATUS       AGE
frops-remove   ReconfigureTLS   Successful   65s

We can see from the above output that the FerretDBOpsRequest has succeeded. If we describe the FerretDBOpsRequest we will get an overview of the steps that were followed.

$ kubectl describe ferretdbopsrequest -n demo frops-remove
Name:         frops-remove
Namespace:    demo
Labels:       <none>
Annotations:  <none>
API Version:  ops.kubedb.com/v1alpha1
Kind:         FerretDBOpsRequest
Metadata:
  Creation Timestamp:  2024-10-18T11:11:55Z
  Generation:          1
  Resource Version:    428244
  UID:                 28a6ba72-0a2d-47f1-97b0-1e9609845acc
Spec:
  Apply:  IfReady
  Database Ref:
    Name:  ferretdb
  Tls:
    Remove:  true
  Type:      ReconfigureTLS
Status:
  Conditions:
    Last Transition Time:  2024-10-18T11:11:55Z
    Message:               FerretDB ops-request has started to reconfigure tls for FerretDB nodes
    Observed Generation:   1
    Reason:                ReconfigureTLS
    Status:                True
    Type:                  ReconfigureTLS
    Last Transition Time:  2024-10-18T11:11:58Z
    Message:               Successfully paused database
    Observed Generation:   1
    Reason:                DatabasePauseSucceeded
    Status:                True
    Type:                  DatabasePauseSucceeded
    Last Transition Time:  2024-10-18T11:12:04Z
    Message:               successfully reconciled the FerretDB with tls configuration
    Observed Generation:   1
    Reason:                UpdatePetSets
    Status:                True
    Type:                  UpdatePetSets
    Last Transition Time:  2024-10-18T11:12:09Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-0
    Last Transition Time:  2024-10-18T11:12:09Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-0
    Last Transition Time:  2024-10-18T11:12:14Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-0
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-0
    Last Transition Time:  2024-10-18T11:12:19Z
    Message:               get pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  GetPod--ferretdb-1
    Last Transition Time:  2024-10-18T11:12:19Z
    Message:               evict pod; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  EvictPod--ferretdb-1
    Last Transition Time:  2024-10-18T11:12:24Z
    Message:               check pod running; ConditionStatus:True; PodName:ferretdb-1
    Observed Generation:   1
    Status:                True
    Type:                  CheckPodRunning--ferretdb-1
    Last Transition Time:  2024-10-18T11:12:29Z
    Message:               Successfully restarted all nodes
    Observed Generation:   1
    Reason:                RestartNodes
    Status:                True
    Type:                  RestartNodes
    Last Transition Time:  2024-10-18T11:12:29Z
    Message:               Successfully completed the ReconfigureTLS for FerretDB
    Observed Generation:   1
    Reason:                Successful
    Status:                True
    Type:                  Successful
  Observed Generation:     1
  Phase:                   Successful
Events:
  Type     Reason                                                       Age   From                         Message
  ----     ------                                                       ----  ----                         -------
  Normal   Starting                                                     87s   KubeDB Ops-manager Operator  Start processing for FerretDBOpsRequest: demo/frops-remove
  Normal   Starting                                                     87s   KubeDB Ops-manager Operator  Pausing FerretDB database: demo/ferretdb
  Normal   Successful                                                   87s   KubeDB Ops-manager Operator  Successfully paused FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-remove
  Normal   UpdatePetSets                                                78s   KubeDB Ops-manager Operator  successfully reconciled the FerretDB with tls configuration
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-0            73s   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-0          73s   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-0
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-0  68s   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-0
  Warning  get pod; ConditionStatus:True; PodName:ferretdb-1            63s   KubeDB Ops-manager Operator  get pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  evict pod; ConditionStatus:True; PodName:ferretdb-1          63s   KubeDB Ops-manager Operator  evict pod; ConditionStatus:True; PodName:ferretdb-1
  Warning  check pod running; ConditionStatus:True; PodName:ferretdb-1  58s   KubeDB Ops-manager Operator  check pod running; ConditionStatus:True; PodName:ferretdb-1
  Normal   RestartNodes                                                 53s   KubeDB Ops-manager Operator  Successfully restarted all nodes
  Normal   Starting                                                     53s   KubeDB Ops-manager Operator  Resuming FerretDB database: demo/ferretdb
  Normal   Successful                                                   53s   KubeDB Ops-manager Operator  Successfully resumed FerretDB database: demo/ferretdb for FerretDBOpsRequest: frops-remove

Now, Let’s try to connect with ferretdb without TLS certs.

$ kubectl get secrets -n demo ferret-auth -o jsonpath='{.data.\username}' | base64 -d
postgres
$ kubectl get secrets -n demo ferret-auth -o jsonpath='{.data.\\password}' | base64 -d
l*jGp8u*El8WRSDJ

$ kubectl port-forward svc/ferret -n demo 27017
Forwarding from 127.0.0.1:27017 -> 27017
Forwarding from [::1]:27017 -> 27017
Handling connection for 27017
Handling connection for 27017

Now in another terminal

$ mongosh 'mongodb://postgres:l*jGp8u*El8WRSDJ@localhost:27017/ferretdb'
Current Mongosh Log ID:	65efeea2a3347fff66d04c70
Connecting to:		mongodb://<credentials>@localhost:27017/ferretdb?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.18.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>

We can see that we can now connect without providing TLS certs. So TLS connection is successfully disabled

Cleaning up

To clean up the Kubernetes resources created by this tutorial, run:

kubectl delete ferretdb -n demo ferretdb
kubectl delete issuer -n demo ferretdb-issuer fr-new-issuer
kubectl delete ferretdbopsrequest -n demo frops-add-tls frops-remove frops-rotate frops-change-issuer
kubectl delete ns demo

Next Steps