diff --git a/bitnami/redis-cluster/CHANGELOG.md b/bitnami/redis-cluster/CHANGELOG.md index 93e6e3957d999e..2e0ce209f582bc 100644 --- a/bitnami/redis-cluster/CHANGELOG.md +++ b/bitnami/redis-cluster/CHANGELOG.md @@ -1,8 +1,12 @@ # Changelog -## 13.0.4 (2025-08-23) +## 13.1.0 (2025-09-22) -* [bitnami/redis-cluster] :zap: :arrow_up: Update dependency references ([#36172](https://github.com/bitnami/charts/pull/36172)) +* [bitnami/redis-cluster]: add preStop hook that gracefully fails over master nodes on pod termination ([#36221](https://github.com/bitnami/charts/pull/36221)) + +## 13.0.4 (2025-08-23) + +* [bitnami/redis-cluster] :zap: :arrow_up: Update dependency references (#36172) ([2060aa9](https://github.com/bitnami/charts/commit/2060aa94b82bd7e0b030a310acf5c45f3b3dceda)), closes [#36172](https://github.com/bitnami/charts/issues/36172) ## 13.0.3 (2025-08-18) diff --git a/bitnami/redis-cluster/Chart.yaml b/bitnami/redis-cluster/Chart.yaml index 448bcd1117a097..91ebfabfbc5023 100644 --- a/bitnami/redis-cluster/Chart.yaml +++ b/bitnami/redis-cluster/Chart.yaml @@ -34,4 +34,4 @@ maintainers: name: redis-cluster sources: - https://github.com/bitnami/charts/tree/main/bitnami/redis-cluster -version: 13.0.5 +version: 13.1.0 diff --git a/bitnami/redis-cluster/README.md b/bitnami/redis-cluster/README.md index abf2823748afaa..506263ff606b9d 100644 --- a/bitnami/redis-cluster/README.md +++ b/bitnami/redis-cluster/README.md @@ -621,6 +621,7 @@ See [#15075](https://github.com/bitnami/charts/issues/15075) | `cluster.init` | Enable the initialization of the Redis(R) Cluster | `true` | | `cluster.nodes` | The number of master nodes should always be >= 3, otherwise cluster creation will fail | `6` | | `cluster.replicas` | Number of replicas for every master in the cluster | `1` | +| `cluster.redisShutdownWaitFailover` | Whether the Redis(R) master container waits for the failover at shutdown. | `true` | | `cluster.externalAccess.enabled` | Enable access to the Redis | `false` | | `cluster.externalAccess.hostMode` | Set cluster preferred endpoint type as hostname | `false` | | `cluster.externalAccess.service.disableLoadBalancerIP` | Disable use of `Service.spec.loadBalancerIP` | `false` | diff --git a/bitnami/redis-cluster/templates/redis-statefulset.yaml b/bitnami/redis-cluster/templates/redis-statefulset.yaml index c731327645c1b4..a5a94b05f089a4 100644 --- a/bitnami/redis-cluster/templates/redis-statefulset.yaml +++ b/bitnami/redis-cluster/templates/redis-statefulset.yaml @@ -268,6 +268,14 @@ spec: {{- end }} {{- if .Values.redis.lifecycleHooks }} lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.redis.lifecycleHooks "context" $) | nindent 12 }} + {{- else }} + lifecycle: + preStop: + exec: + command: + - /bin/bash + - -ec + - /scripts/prestop-redis-cluster.sh {{- end }} {{- end }} {{- if .Values.redis.resources }} diff --git a/bitnami/redis-cluster/templates/scripts-configmap.yaml b/bitnami/redis-cluster/templates/scripts-configmap.yaml index 4a4fbfc8d663ef..895568ee550047 100644 --- a/bitnami/redis-cluster/templates/scripts-configmap.yaml +++ b/bitnami/redis-cluster/templates/scripts-configmap.yaml @@ -105,3 +105,66 @@ data: echo "$response" exit 1 fi + prestop-redis-cluster.sh: |- + #!/bin/bash + set -e + + # redis-cli automatically consumes credentials from the REDISCLI_AUTH variable + [[ -n "$REDIS_PASSWORD" ]] && export REDISCLI_AUTH="$REDIS_PASSWORD" + [[ -f "$REDIS_PASSWORD_FILE" ]] && export REDISCLI_AUTH="$(< "${REDIS_PASSWORD_FILE}")" + + run_redis_command() { + local args=("-h" "$1") + shift + {{- if .Values.tls.enabled }} + args+=("--tls" "--cert" "{{ template "redis-cluster.tlsCert" . }}" "--key" "{{ template "redis-cluster.tlsCertKey" . }}" "--cacert" "{{ template "redis-cluster.tlsCACert" . }}" "-p" $REDIS_TLS_PORT_NUMBER) + {{- else }} + args+=("-p" $REDIS_PORT_NUMBER) + {{- end }} + redis-cli "${args[@]}" "$@" + } + + is_master() { + REDIS_ROLE=$(run_redis_command 127.0.0.1 ROLE | head -1) + [[ "$REDIS_ROLE" == "master" ]] + } + + get_cluster_node_id() { + CLUSTER_ID=$(run_redis_command 127.0.0.1 CLUSTER MYID | head -1) + echo $CLUSTER_ID + } + + get_replica_ips() { + CLUSTER_NODE_ID=$(get_cluster_node_id) + + # Get a list of replica IP addresses that could be promoted + # Use shuf to randomize the order + 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)" + echo "$REPLICAS" | sed '/^[[:space:]]*$/d' + } + + if is_master; then + # Get list of replicas of the current master + mapfile -t REPLICA_IPS < <( get_replica_ips ) + + NUM_REPLICAS=${#REPLICA_IPS[@]} + echo "Found $NUM_REPLICAS available replicas" + + # Iterate over replicas, attempting to promote one + for REPLICA_IP in "${REPLICA_IPS[@]}"; do + echo "Going to fail over to replica at $REPLICA_IP" + result=$(run_redis_command $REPLICA_IP CLUSTER FAILOVER) + + if [[ "$result" == "OK" ]]; then + {{- if .Values.cluster.redisShutdownWaitFailover }} + echo "Waiting for node to complete failover for up to {{ sub .Values.redis.terminationGracePeriodSeconds 10 }}s" + + # Wait for clients to update their topology + sleep {{ sub .Values.redis.terminationGracePeriodSeconds 10 }} + {{- end }} + break + fi + done + else + exit 0 + fi diff --git a/bitnami/redis-cluster/values.yaml b/bitnami/redis-cluster/values.yaml index 211a3f8bec4487..c54b690adecdcd 100644 --- a/bitnami/redis-cluster/values.yaml +++ b/bitnami/redis-cluster/values.yaml @@ -873,6 +873,10 @@ cluster: replicas: 1 ## Configuration to access the Redis(R) Cluster from outside the Kubernetes cluster ## + ## @param cluster.redisShutdownWaitFailover Whether the Redis(R) master container waits for the failover at shutdown. + ## + redisShutdownWaitFailover: true + externalAccess: ## @param cluster.externalAccess.enabled Enable access to the Redis ##