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.

Run Redis with TLS/SSL (Transport Encryption)

KubeDB supports providing TLS/SSL encryption for Redis. This tutorial will show you how to use KubeDB to run a Redis 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/redis folder in GitHub repository kubedb/docs.

Overview

KubeDB uses following crd fields to enable SSL/TLS encryption in Redis.

  • spec:
    • tls:
      • issuerRef
      • certificate

Read about the fields in details in redis concept,

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 Redis. 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=redis/O=kubedb"
  • Now create a ca-secret using the certificate files you have just generated.
kubectl create secret tls redis-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: redis-ca-issuer
  namespace: demo
spec:
  ca:
    secretName: redis-ca

Apply the YAML file:

$ kubectl create -f https://github.com/kubedb/docs/raw/v2023.02.28/docs/examples/redis/tls/issuer.yaml
issuer.cert-manager.io/redis-ca-issuer created

TLS/SSL encryption in Redis Standalone

Below is the YAML for Redis Standalone.

apiVersion: kubedb.com/v1alpha2
kind: Redis
metadata:
  name: rd-tls
  namespace: demo
spec:
  version: "6.2.5"
  tls:
    issuerRef:
      apiGroup: "cert-manager.io"
      kind: Issuer
      name: redis-ca-issuer
  storage:
    storageClassName: "standard"
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 1Gi

Deploy Redis Standalone

$ kubectl create -f https://github.com/kubedb/docs/raw/v2023.02.28/docs/examples/redis/tls/rd-standalone-ssl.yaml
redis.kubedb.com/rd-tls created

Now, wait until rd-tls has status Ready. i.e,

$ watch kubectl get rd -n demo
Every 2.0s: kubectl get redis -n demo
NAME      VERSION     STATUS     AGE
rd-tls    6.2.5       Ready      14s

Verify TLS/SSL in Redis Standalone

Now, connect to this database by exec into a pod and verify if tls has been set up as intended.

$ kubectl describe secret -n demo rd-tls-client-cert
Name:         rd-tls-client-cert
Namespace:    demo
Labels:       app.kubernetes.io/component=database
              app.kubernetes.io/instance=rd-tls
              app.kubernetes.io/managed-by=kubedb.com
              app.kubernetes.io/name=redises.kubedb.com
Annotations:  cert-manager.io/alt-names: 
              cert-manager.io/certificate-name: rd-tls-client-cert
              cert-manager.io/common-name: default
              cert-manager.io/ip-sans: 
              cert-manager.io/issuer-group: cert-manager.io
              cert-manager.io/issuer-kind: Issuer
              cert-manager.io/issuer-name: redis-ca-issuer
              cert-manager.io/uri-sans: 

Type:  kubernetes.io/tls

Data
====
ca.crt:   1147 bytes
tls.crt:  1127 bytes
tls.key:  1675 bytes

Now, Lets exec into a redis container and find out the username to connect in a redis shell,

$ kubectl exec -it -n demo rd-tls-0 -c redis -- bash

root@rd-tls-0:/data# ls /certs
ca.crt	client.crt  client.key	server.crt  server.key

root@rd-tls-0:/data# apt-get update; apt-get install openssl;
...

root@rd-tls-0:/data# openssl x509 -in /certs/ca.crt -inform PEM -subject -nameopt RFC2253 -noout
subject=O=kubedb,CN=redis

Now, we can connect using CN=redis,O=kubedb as root to connect to the redis and write some data

$ kubectl exec -it -n demo rd-tls-0 -c redis -- bash

# Trying to connect without tls certificates
root@rd-tls-0:/data# redis-cli
127.0.0.1:6379> 
127.0.0.1:6379> set hello world
# Can not write data 
Error: Connection reset by peer 

# Trying to connect with tls certificates
root@rd-tls-0:/data# redis-cli --tls --cert "/certs/client.crt" --key "/certs/client.key" --cacert "/certs/ca.crt"
127.0.0.1:6379> 
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> exit

Cleaning up

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

$ kubectl patch -n demo redis/rd-tls -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge"
redis.kubedb.com/rd-tls patched

$ kubectl delete -n demo redis rd-tls
redis.kubedb.com "rd-tls" deleted

$ kubectl delete issuer -n demo redis-ca-issuer
issuer.cert-manager.io "redis-ca-issuer" deleted

Next Steps