In-cluster Redis
Please consider using Cloud Memorystore because even the standard plan on Memorystore gives high availability out of the box. Running a single redis instance in the cluster will have downtime when the instance restarts. This restart can happen any time on the cluster. Also this example of the in-cluster redis does not provide persistence, the data will be wiped on restart, it is only suitable for caching.
If you really don’t care about HA and continuity of the data the following document will show you how to create a custom redis for your application.
To do this, you will have to do the following:
- create a Redis custom resource in
gap/gap_redis.yaml - configure your client to connect to redis via the kubernetes service name of the redis instance
<my-application-name>-redis.<namespace>
This example contains
- a k8s ServiceAccount that is used by redis
- an AuthorizationPolicy to allow your application to call it through the service mesh (adapt this to specific ServiceAccounts that you are using if not default)
- an example ConfigMap to contain the redis config, that is mounted on the pod
- a k8s service resource to provide an endpoint for clients
- a k8s statefulset to run the redis container
Create a yaml file under your gap folder with the following content (do not forget to replace <my-application-name> with your app name)
# gap/gap_redis.yaml
# An example ServiceAccount to be used by the redis pods
apiVersion: v1
automountServiceAccountToken: false
kind: ServiceAccount
metadata:
labels:
applicationName: <my-application-name>-redis
app.kubernetes.io/instance: redis
name: <my-application-name>-redis
---
# An example AuthorizationPolicy to allow speicific applications (through their ServiceAccounts) to access the redis (do not forget to replace `<namespace>` with the one where the service account resides as well).
# Every GAP application has a default service account generated based on the `name` key from the gap.yaml. If you are not using that or overriding the service account for specific deployments here you need to specify that.
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
labels:
applicationName: <my-application-name>-redis
app.kubernetes.io/instance: redis
name: <my-application-name>-redis
spec:
action: ALLOW
rules:
- from:
- source:
principals:
# This should match your namespace and the ServiceAccount of the caller (default is the `name` field in the gap.yaml)
- cluster.local/ns/<namespace>/sa/<my-application-name>
selector:
matchLabels:
applicationName: <my-application-name>-redis
---
# An example ConfigMap containing the redis.conf file contents that is mounted on the pod.
apiVersion: v1
kind: ConfigMap
metadata:
labels:
applicationName: <my-application-name>-redis
app.kubernetes.io/instance: redis
name: <my-application-name>-redis
data:
redis.conf: |
maxmemory 100mb
maxmemory-policy allkeys-lru
---
# An example service to allow other pods in the cluster to call the redis via a consistent host
apiVersion: v1
kind: Service
metadata:
labels:
applicationName: <my-application-name>-redis
app.kubernetes.io/instance: redis
name: <my-application-name>-redis
spec:
ports:
- name: redis
protocol: TCP
port: 6379
targetPort: 6379
selector:
applicationName: <my-application-name>-redis
---
# An example StatefulSet to run the redis pod.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: <my-application-name>-redis
labels:
applicationName: <my-application-name>-redis
app.kubernetes.io/instance: redis
mesh: enabled
spec:
selector:
matchLabels:
applicationName: <my-application-name>-redis
serviceName: <my-application-name>-redis
replicas: 1
template:
metadata:
labels:
applicationName: <my-application-name>-redis
app.kubernetes.io/instance: redis
# this enables service mesh on the pods
istio.io/rev: default
redis: "true"
spec:
# This should match the ServiceAccount name we defined at the top of the file.
serviceAccountName: <my-application-name>-redis
containers:
- name: redis
image: redis:7
args:
- "/redis/redis.conf"
- --appendonly
- "yes"
- --port
- "6379"
ports:
- containerPort: 6379
name: web
resources:
requests:
memory: 200Mi
cpu: 200m
limits:
memory: 300Mi
cpu: 500m
volumeMounts:
- mountPath: /redis
name: redisconf
securityContext:
runAsUser: 999
volumes:
- name: redisconf
configMap:
# This should match the name of the ConfigMap defined above.
name: <my-application-name>-redis
items:
- key: redis.conf
path: redis.conf
You can exec onto the redis pod and run redis-cli
kubectl exec -n <namespace> -it <my-application-name>-redis-0 -- redis-cli
or port forward to the pod and connect locally
kubectl port-forward -n <namespace> <my-application-name>-redis-0 6379
In the cluster the process should call through the k8s service defined above
redis-cli -h <my-application-name>.<namespace> -p 6379