Skip to content

Commit

Permalink
Merge pull request #66 from controlplane-com/redis-cluster-dns-fix
Browse files Browse the repository at this point in the history
fixing redis cluster to use dns instead of ip
  • Loading branch information
enk21 authored Nov 22, 2024
2 parents f0184e7 + 65848ab commit b64f396
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 27 deletions.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This example creates a Redis cluster with 6 nodes on the Control Plane Platform

The [Helm CLI](https://helm.sh/docs/intro/install/#through-package-managers) and [Control Plane CLI](https://docs.controlplane.com/reference/cli#install-npm) must be installed.

1. Clone this repo and update the [values.yaml](./values.yaml) file as needed.
1. Clone this repo and update the [values.yaml](redis-clsuter/values.yaml) file as needed.

2. Run the command below from this directory.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,41 @@ set -ex


cp /usr/local/etc/redis/redis-default.conf /usr/local/etc/redis/redis.conf

ip=$(hostname -I)

# Find which member of the Stateful Set this pod is running

# e.g. "redis-cluster-0" -> "0"

PET_ORDINAL=$(echo "$POD_NAME" | rev | cut -d'-' -f 1 | rev)

WORKLOAD_NAME=$(echo $CPLN_WORKLOAD | sed 's|.*/workload/\([^/]*\)$|\1|')

NODE_LIST=""

echo "" >> /usr/local/etc/redis/redis.conf

echo "cluster-announce-ip $ip" >> /usr/local/etc/redis/redis.conf

echo "cluster-announce-ip $WORKLOAD_NAME-$PET_ORDINAL.$WORKLOAD_NAME" >> /usr/local/etc/redis/redis.conf
redis-server /usr/local/etc/redis/redis.conf > /dev/null 2>&1 &

sleep 10

# Waiting for redis to become Healthy

while true; do

response=$(redis-cli ping 2>&1)

# Check if the response is "PONG"

if [[ "$response" == *"PONG"* ]]; then
echo "Redis node is HEALTHY"
break
else
echo "Waiting for Redis node to become healthy"
fi

sleep 5
done

# Construct NODE_LIST

for (( i=0; i<CUSTOM_NUM_NODES; i++ )); do
NODE_LIST+="$WORKLOAD_NAME-$i.$WORKLOAD_NAME:$CUSTOM_REDIS_PORT "
done

# Trim the trailing space

NODE_LIST=$(echo $NODE_LIST | sed 's/ $//')

# Cluster init

cluster_status=$(redis-cli cluster info | grep "cluster_state" | cut -d':' -f2 | tr -d '\r')

if [[ "$cluster_status" == "ok" ]]; then
Expand All @@ -64,15 +48,10 @@ if [[ "$cluster_status" == "ok" ]]; then
else
while true; do
all_nodes_healthy=true

for (( i=0; i<CUSTOM_NUM_NODES; i++ )); do

# Attempt to ping the current Redis node

response=$(redis-cli -h "$WORKLOAD_NAME-$i.$WORKLOAD_NAME" -p $CUSTOM_REDIS_PORT ping 2>&1) || true

# Check if the response is "PONG"

if [[ "$response" == *"PONG"* ]]; then
echo "Node $i is HEALTHY. Received PONG."
else
Expand All @@ -83,10 +62,8 @@ else
done

# If this is replica *-0, all nodes are healthy, and the cluster is not initiated, create the cluster

if [[ $PET_ORDINAL == 0 && "$all_nodes_healthy" == true ]]; then
cluster_status=$(redis-cli cluster info | grep "cluster_state" | cut -d':' -f2 | tr -d '\r')

if [ "$cluster_status" = "ok" ]; then
echo "All nodes are healthy and cluster status is OK."
break
Expand All @@ -98,7 +75,6 @@ else
fi

# Short delay before restarting loop

sleep 5
done
fi
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ tags: {}
type: opaque
data:
encoding: plain
payload: >
payload: |-
{{ .Files.Get "scripts/redis-start.sh" | indent 4 }}
File renamed without changes.
6 changes: 6 additions & 0 deletions examples/redis/single-node/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v2
name: redis
description: A single replica Redis helm chart for Control Plan
type: application
version: 0.1.0
appVersion: "1.0.0"
51 changes: 51 additions & 0 deletions examples/redis/single-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## Redis example

This example creates a Redis cluster with 6 nodes on the Control Plane Platform and can be further customized as needed.

### Steps to run this example:

**HELM**

The [Helm CLI](https://helm.sh/docs/intro/install/#through-package-managers) and [Control Plane CLI](https://docs.controlplane.com/reference/cli#install-npm) must be installed.

1. Clone this repo and update the [values.yaml](redis-clsuter/values.yaml) file as needed.

2. Run the command below from this directory.

```bash
cpln helm install redis-cluster --gvc mygvc
```
Note: Typically, it takes 5 minutes for all replicas of the workload to become ready and for the cluster to be created.

### Accessing redis-cluster

Workloads are allowed to access Redis Cluster based on the `firewallConfig` you specify. You can learn more about in our [documentation](https://docs.controlplane.com/reference/workload#internal).

Improtant: To access workloads listening on a TCP port, the client workload must be in the same GVC. Thus, the Redis cluster is accessible to clients running within the same GVC.

#### Option 1:

Syntax: <WORKLOAD_NAME>
```
redis-cli -c -h redis-cluster -p 6379 set mykey "test"
redis-cli -c -h redis-cluster -p 6379 get mykey
```
#### Option 2: (By replica)

Syntax: <REPLICA_NAME>.<WORKLOAD_NAME>
```
redis-cli -c -h redis-cluster-0.redis-cluster -p 6379 set mykey "test"
redis-cli -c -h redis-cluster-1.redis-cluster -p 6379 get mykey
redis-cli -c -h redis-cluster-2.redis-cluster -p 6379 get mykey
redis-cli -c -h redis-cluster-3.redis-cluster -p 6379 get mykey
redis-cli -c -h redis-cluster-4.redis-cluster -p 6379 get mykey
redis-cli -c -h redis-cluster-5.redis-cluster -p 6379 get mykey
```

### Cleanup

**HELM**

```bash
cpln helm uninstall redis-cluster
```
14 changes: 14 additions & 0 deletions examples/redis/single-node/templates/volumeset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{{- if .Values.volumeset }}
kind: volumeset
name: volumeset-{{ .Values.name }}
description: volumeset-{{ .Values.name }}
tags: {}
spec:
fileSystemType: {{ .Values.volumeset.volume.fileSystemType }}
initialCapacity: {{ .Values.volumeset.volume.initialCapacity }}
performanceClass: {{ .Values.volumeset.volume.performanceClass }}
snapshots:
createFinalSnapshot: {{ .Values.volumeset.snapshots.createFinalSnapshot }}
retentionDuration: {{ .Values.volumeset.snapshots.retentionDuration }}
schedule: {{ .Values.volumeset.snapshots.schedule }}
{{- end }}
81 changes: 81 additions & 0 deletions examples/redis/single-node/templates/workload.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
kind: workload
name: {{ .Values.name }}
gvc: {{ .Values.cpln.gvc }}
description: {{ .Values.name }}
spec:
type: stateful
containers:
- name: {{ .Values.name }}
cpu: '{{ .Values.cpu }}'
memory: {{ .Values.memory }}
env:
- name: CUSTOM_REDIS_PORT
value: '{{ .Values.port }}'
image: {{ .Values.image.repository }}
livenessProbe:
exec:
command:
- /bin/bash
- '-c'
- redis-cli ping
failureThreshold: 10
initialDelaySeconds: 25
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 4
readinessProbe:
exec:
command:
- /bin/bash
- '-c'
- redis-cli ping
failureThreshold: 10
initialDelaySeconds: 20
periodSeconds: 5
successThreshold: 1
timeoutSeconds: 4
inheritEnv: {{ .Values.inheritEnv }}
ports:
- number: {{ .Values.port }}
protocol: tcp
volumes:
{{- if .Values.volumeset }}
- path: /data
recoveryPolicy: retain
uri: 'cpln://volumeset/volumeset-{{ .Values.name }}'
{{- else }}
[]
{{- end }}
defaultOptions:
autoscaling:
maxConcurrency: 0
maxScale: 1
metric: disabled
minScale: 1
scaleToZeroDelay: 300
target: 100
capacityAI: {{ .Values.capacityAI}}
debug: false
suspend: false
timeoutSeconds: 5
{{- if .Values.firewall }}
firewallConfig:
{{- if or (hasKey .Values.firewall "external_inboundAllowCIDR") (hasKey .Values.firewall "external_outboundAllowCIDR") }}
external:
inboundAllowCIDR: {{- if .Values.firewall.external_inboundAllowCIDR }}{{ .Values.firewall.external_inboundAllowCIDR | splitList "," | toYaml | nindent 8 }}{{- else }} []{{- end }}
outboundAllowCIDR: {{- if .Values.firewall.external_outboundAllowCIDR }}{{ .Values.firewall.external_outboundAllowCIDR | splitList "," | toYaml | nindent 8 }}{{- else }} []{{- end }}
{{- end }}
{{- if hasKey .Values.firewall "internal_inboundAllowType" }}
internal:
inboundAllowType: {{ default "[]" .Values.firewall.internal_inboundAllowType }}
{{- end }}
{{- end }}
localOptions: []
rolloutOptions:
maxSurgeReplicas: 25%
maxUnavailableReplicas: '1'
minReadySeconds: 0
scalingPolicy: OrderedReady
securityOptions:
filesystemGroupId: 1001
supportDynamicTags: {{ .Values.supportDynamicTags }}
29 changes: 29 additions & 0 deletions examples/redis/single-node/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Default values for redis-cluster.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

image:
repository: docker.io/redis:7.2

name: redis-dev-empty
port: 6379
diskCapacity: 20 # In Gigabytes
memory: 250Mi # EX. 3000Mi = 3Gi
cpu: 200m # vCPU or milicores with; EX. 1.5 = 1500m
inheritEnv: false
capacityAI: false
firewall:
internal_inboundAllowType: "same-org" # Options: same-org / same-gvc(Recommended)
# external_inboundAllowCIDR: 0.0.0.0/0 # Provide a comma-separated list
# external_outboundAllowCIDR: "0.0.0.0/0" # "111.222.333.444/16,111.222.444.333/32" # Provide a comma-separated list
supportDynamicTags: false
timeoutSeconds: 30
volumeset: {}
# volume:
# initialCapacity: 25 # In Gigabytes. For high-throughput-ssd minimum is '1000'
# fileSystemType: ext4 # ext4 / xfs
# performanceClass: general-purpose-ssd # high-throughput-ssd / general-purpose-ssd
# snapshots:
# createFinalSnapshot: 'true'
# retentionDuration: 7d
# schedule: '0 1 * * *'

0 comments on commit b64f396

Please sign in to comment.