These instructions will demonstrate how to configure API Portal to use Redis for high availability session storage. The instructions were created with TAP in mind, but should also work for any cluster with the Cluster Essentials for VMware Tanzu installed. These instructions will:
api-portal
namespace using SecretExport and SecretImportNote: To use Redis for session storage you will need to have API Portal configured to use SSO. For more details see [Configure Single Sign-On](configuring-k8s-sso.html#configure-sso-k8s))
Installing the Redis operator is a relatively simple task as all the necessary resource definitions are contained in a single yaml file that is available at public URL. You will use the Redis Enterprise Cluster operator in this guide. To install the Redis operator, run the following commands:
kubectl create ns service-instances
kubectl apply -f https://raw.githubusercontent.com/RedisLabs/redis-enterprise-k8s-docs/v6.2.10-45/bundle.yaml -n service-instances
Validate the operator is installed with the following command:
kubectl get pods -l name=redis-enterprise-operator -n service-instances
You should see an output similar to the following:
NAME READY STATUS RESTARTS AGE
redis-enterprise-operator-74849d8c69-pnqvq 2/2 Running 0 39s
Now that the operator is deployed, you can create a Redis cluster and database. To deploy the cluster and database copy the instructions to a file named ha-setup.yml
, run the command below. The configuration referenced in the following command, using some Carvel tools, creates a kubernetes service binding compliant secret and moves that secret to the api-portal namespace so your api-portal deployment can access it. It also deploys a SecretTemplate resource to convert the subsequent Redis configuration into a service binding compliant secret.
Note: These instructions assume you have API Portal installed in the namespace `api-portal`. If you are using a different namespace then substitute that value in where `api-portal` is mentioned.
(
cat <<'EOF'
#@ load("@ytt:data", "data")
---
apiVersion: "app.redislabs.com/v1"
kind: RedisEnterpriseCluster
metadata:
name: #@ data.values.instance_name + "-cluster"
namespace: #@ data.values.service_namespace
spec:
nodes: 1
redisEnterpriseNodeResources:
limits:
cpu: "2000m"
memory: 4Gi
requests:
cpu: "100m"
memory: 1Gi
persistentSpec:
enabled: true
volumeSize: 10Gi
---
apiVersion: app.redislabs.com/v1alpha1
kind: RedisEnterpriseDatabase
metadata:
name: #@ data.values.instance_name + "-db"
namespace: #@ data.values.service_namespace
spec:
memorySize: 1GB
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: redis-enterprise-cluster-secret-template-reader
namespace: #@ data.values.service_namespace
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: redis-enterprise-cluster-secret-template-reader
namespace: #@ data.values.service_namespace
rules:
- apiGroups:
- ""
resources:
- secrets
- services
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: redis-enterprise-cluster-secret-template-reader
namespace: #@ data.values.service_namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: redis-enterprise-cluster-secret-template-reader
subjects:
- kind: ServiceAccount
name: redis-enterprise-cluster-secret-template-reader
---
apiVersion: secretgen.carvel.dev/v1alpha1
kind: SecretTemplate
metadata:
name: #@ data.values.instance_name + "-redis-secret"
namespace: #@ data.values.service_namespace
spec:
serviceAccountName: redis-enterprise-cluster-secret-template-reader
inputResources:
- name: redis-service
ref:
apiVersion: v1
kind: Service
name: #@ data.values.instance_name + "-db"
- name: creds
ref:
apiVersion: v1
kind: Secret
name: #@ "redb-" + data.values.instance_name + "-db"
template:
metadata:
labels:
app.kubernetes.io/component: redis
app.kubernetes.io/instance: #@ data.values.instance_name
services.apps.tanzu.vmware.com/class: redis-enterprise-cluster
stringData:
host: "$(.redis-service.metadata.name).$(.redis-service.metadata.namespace)"
provider: redis_enterprise
type: redis
data:
password: $(.creds.data.password)
port: $(.creds.data.port)
---
apiVersion: secretgen.carvel.dev/v1alpha1
kind: SecretExport
metadata:
name: #@ data.values.instance_name + "-redis-secret"
namespace: #@ data.values.service_namespace
spec:
toNamespace: api-portal
---
apiVersion: secretgen.carvel.dev/v1alpha1
kind: SecretImport
metadata:
name: #@ data.values.instance_name + "-redis-secret"
namespace: api-portal
spec:
fromNamespace: #@ data.values.service_namespace
EOF
) | ytt -v service_namespace=service-instances -v instance_name=redis-test -f- | kubectl apply -f-
This will create a cluster and database named redis-test. Once the cluster is ready, its configuration is written to a secret and service resource.
First validate that the cluster has been created and is operational by running the following command:
kubectl get sts redis-test-cluster -n service-instances
You should see an output similar to the following:
NAME READY AGE
redis-test-cluster 1/1 108s
Next, validate that the database is operational by running the following command:
kubectl get redisenterprisedatabase redis-test-db -n service-instances
You should see an output similar to the following:
NAME VERSION PORT CLUSTER SHARDS STATUS SPEC STATUS AGE
redis-test-db 6.0.13 10745 redis-test-cluster 1 active Valid 5m55s
Next, validate the SecretTemplate was able to reconcile the Redis configuration into a service binding compliant secret by running the following command:
kubectl get secrettemplate redis-test-redis-secret -n service-instances
You should see an output similar to the following:
NAME DESCRIPTION AGE
redis-test-redis-secret Reconcile succeeded 8m57s
Validate that the service binding compliant secret exists by running the following command:
kubectl get secret redis-test-redis-secret -n service-instances
Validate that the SecretExport was created by running the following command:
kubectl get secretexport.secretgen.carvel.dev/redis-test-redis-secret -n service-instances
You should see an output similar below. This might take a couple of minutes to reconcile.
NAME DESCRIPTION AGE
redis-test-redis-secret Reconcile succeeded 8m46s
Validate that the SecretImport was created in the api-portal namespace by running the following command:
kubectl get secretimport.secretgen.carvel.dev/redis-test-redis-secret -n api-portal
You should see an output similar to the following:
NAME DESCRIPTION AGE
redis-test-redis-secret Reconcile succeeded 12m
Finally make sure the service binding compliant secret was copied over to the api-portal namespace by running the following command:
kubectl get secret redis-test-redis-secret -n api-portal
You should see an output similar to the following:
NAME DESCRIPTION AGE
redis-test-redis-secret Reconcile succeeded 8m57s
If you inspect the secret further, you will see it incorporates all the necessary fields to describe the binding as well as provides necessary connectivity and authentication information
kubectl describe secret redis-test-redis-secret -n api-portal
You should see an output similar to the following:
Name: redis-test-redis-secret
Namespace: api-portal
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
host: 31 bytes
password: 8 bytes
port: 5 bytes
provider: 16 bytes
type: 5 bytes
Note: The following instructions are TAP specific.
Update the api_portal
section of your tap values to include the sso.session.redisCredentialSecret
. Below is an example
api_portal:
sso:
enabled: true
secretName: sso-credentials
session:
redisCredentialSecret: redis-test-redis-secret
Once you have updated your values file you can refresh your tap installation. First you will need to find the version of TAP you are using. If you are unsure you can locate the version by running the following command:
tanzu package installed list -n tap-install
and look for a the line with the name of tap
NAME PACKAGE-NAME PACKAGE-VERSION STATUS
tap tap.tanzu.vmware.com 1.5.1 Reconcile succeeded
Now you can update your installation by running the command below and replacing <TAP_VERSION> with the appropriate version and <VALUES.yaml> with your updated values file.
tanzu package install tap -p tap.tanzu.vmware.com -v <TAP_VERSION> --values-file <VALUES.yaml> -n tap-install
It might take a couple of minutes for the changes to propagate through. You can check the status of api portal by running the following command:
tanzu package installed get api-portal -n tap-install
Now your API Portal installation should be configured to use redis to store your sessions! If you want to double check you can look for a cookie by the name of API-PORTAL-SESSION
, If you are not using redis you would only see SESSION