Skip to content

Commit 75ff4fa

Browse files
committed
[bitnami/redis-cluster]: add preStop hook that gracefully fails over master nodes on pod termination
1 parent 1380a26 commit 75ff4fa

File tree

5 files changed

+77
-1
lines changed

5 files changed

+77
-1
lines changed

bitnami/redis-cluster/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ maintainers:
3535
name: redis-cluster
3636
sources:
3737
- https://github.com/bitnami/charts/tree/main/bitnami/redis-cluster
38-
version: 13.0.4
38+
version: 13.1.0

bitnami/redis-cluster/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,7 @@ See [#15075](https://github.com/bitnami/charts/issues/15075)
621621
| `cluster.init` | Enable the initialization of the Redis(R) Cluster | `true` |
622622
| `cluster.nodes` | The number of master nodes should always be >= 3, otherwise cluster creation will fail | `6` |
623623
| `cluster.replicas` | Number of replicas for every master in the cluster | `1` |
624+
| `cluster.redisShutdownWaitFailover` | Whether the Redis(R) master container waits for the failover at shutdown. | `true` |
624625
| `cluster.externalAccess.enabled` | Enable access to the Redis | `false` |
625626
| `cluster.externalAccess.hostMode` | Set cluster preferred endpoint type as hostname | `false` |
626627
| `cluster.externalAccess.service.disableLoadBalancerIP` | Disable use of `Service.spec.loadBalancerIP` | `false` |

bitnami/redis-cluster/templates/redis-statefulset.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ spec:
268268
{{- end }}
269269
{{- if .Values.redis.lifecycleHooks }}
270270
lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.redis.lifecycleHooks "context" $) | nindent 12 }}
271+
{{- else }}
272+
lifecycle:
273+
preStop:
274+
exec:
275+
command:
276+
- /bin/bash
277+
- -ec
278+
- /opt/bitnami/scripts/start-scripts/prestop-redis-cluster.sh
271279
{{- end }}
272280
{{- end }}
273281
{{- if .Values.redis.resources }}

bitnami/redis-cluster/templates/scripts-configmap.yaml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,66 @@ data:
105105
echo "$response"
106106
exit 1
107107
fi
108+
prestop-redis-cluster.sh: |-
109+
#!/bin/bash
110+
set -e
111+
112+
# redis-cli automatically consumes credentials from the REDISCLI_AUTH variable
113+
[[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD"
114+
[[ -f "$REDIS_PASSWORD_FILE" ]] && export REDISCLI_AUTH="$(< "${REDIS_PASSWORD_FILE}")"
115+
116+
run_redis_command() {
117+
local args=("-h" "$1")
118+
shift
119+
{{- if .Values.tls.enabled }}
120+
args+=("--tls" "--cert" "{{ template "redis-cluster.tlsCert" . }}" "--key" "{{ template "redis-cluster.tlsCertKey" . }}" "--cacert" "{{ template "redis-cluster.tlsCACert" . }}" "-p" $REDIS_TLS_PORT_NUMBER)
121+
{{- else }}
122+
args+=("-p" $REDIS_PORT_NUMBER)
123+
{{- end }}
124+
redis-cli "${args[@]}" "$@"
125+
}
126+
127+
is_master() {
128+
REDIS_ROLE=$(run_redis_command 127.0.0.1 ROLE | head -1)
129+
[[ "$REDIS_ROLE" == "master" ]]
130+
}
131+
132+
get_cluster_node_id() {
133+
CLUSTER_ID=$(run_redis_command 127.0.0.1 CLUSTER MYID | head -1)
134+
echo $CLUSTER_ID
135+
}
136+
137+
get_replica_ips() {
138+
CLUSTER_NODE_ID=$(get_cluster_node_id)
139+
140+
# Get a list of replica IP addresses that could be promoted
141+
# Use shuf to randomize the order
142+
REPLICAS="$(run_redis_command 127.0.0.1 CLUSTER REPLICAS $CLUSTER_NODE_ID | grep -Ev "(disconnected|nofailover|noaddr|handshake)" | cut -d " " -f 2 | cut -d ":" -f 1 | shuf)"
143+
echo "$REPLICAS"
144+
}
145+
146+
if is_master; then
147+
# Get list of replicas of the current master
148+
mapfile -t REPLICA_IPS < <( get_replica_ips )
149+
150+
NUM_REPLICAS=${#REPLICA_IPS[@]}
151+
echo "Found $NUM_REPLICAS available replicas"
152+
153+
if (( $NUM_REPLICAS > 0 )); then
154+
# Iterate over replicas, attempting to promote one
155+
for REPLICA_IP in "${REPLICA_IPS[@]}"; do
156+
echo "Going to fail over to replica at $REPLICA_IP"
157+
result=$(run_redis_command $REPLICA_IP CLUSTER FAILOVER)
158+
159+
if [[ "$result" == "OK" ]]; then
160+
{{- if .Values.cluster.redisShutdownWaitFailover }}
161+
# Wait for clients to update their topology
162+
sleep 10
163+
break
164+
{{- end }}
165+
fi
166+
done
167+
fi
168+
else
169+
exit 0
170+
fi

bitnami/redis-cluster/values.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,10 @@ cluster:
873873
replicas: 1
874874
## Configuration to access the Redis(R) Cluster from outside the Kubernetes cluster
875875
##
876+
## @param cluster.redisShutdownWaitFailover Whether the Redis(R) master container waits for the failover at shutdown.
877+
##
878+
redisShutdownWaitFailover: true
879+
876880
externalAccess:
877881
## @param cluster.externalAccess.enabled Enable access to the Redis
878882
##

0 commit comments

Comments
 (0)