Overview
Redis Cluster is the native distributed mode of Redis: the keyspace is split into 16384 hash slots and spread across several primary nodes, each with its own replica, so a dataset can outgrow a single node and a failed primary is replaced by its replica without an external coordinator. This template deploys a six-node cluster — three primaries and three replicas — on persistent volumes, with optional password authentication and scheduled backups. Oneengine knob runs every node on Valkey, the BSD-licensed fork of Redis, instead; leaving it alone changes nothing.
What Gets Created
Prerequisites
None for a default install. Scheduled backups need an S3 or GCS bucket, a Control Plane cloud account and, on AWS, a bucket-scoped IAM policy before they can be enabled — see Backing Up.Installation
A default install needs no values:UI
CLI
Terraform
Pulumi
Configuration
Engine
engine: valkey runs every cluster node on valkeyImage. Nothing else changes: the Valkey image ships redis-server, redis-cli, redis-sentinel, redis-check-rdb and redis-check-aof compatibility symlinks, so the cluster bootstrap, the config directives, the readiness probe and the backup job all run unmodified, and every command on this page applies to both engines. Valkey reports redis_version:7.2.4 in INFO server for client compatibility and carries its real identity in server_name:valkey and valkey_version; check that before switching if your client library gates features on redis_version.
dual-channel-replication-enabled on Valkey; a known upstream defect confuses replica accounting. The marketplace card shows the Redis version even for a Valkey install, because a chart’s appVersion is a constant.
Image
engine is redis. A Redis tag left here has no effect under engine: valkey.
Cluster Size and Resources
replicas— 6 is the only supported value. The cluster is always created with one replica per primary, so six nodes form three primaries and three replicas. Fewer cannot form a cluster, which needs three primaries for quorum; more is rejected at install, because a built-in platform quota caps replica-direct workloads at 6 replicas (exceed the autoscaling.maxScale of 6 (quota: replicas-per-replica-direct-workload)).port— the port every node listens on. Redis derives the cluster bus asport + 10000and the template declares both ports, so a customportneeds no further configuration — but any client or firewall rule expecting16379must move with it.cpu/memory— per node. The default250Miis a floor, not a recommendation: a cache left at the default begins evicting almost immediately under real load.
Internal Access
internalAccess is the only access control on the cluster. Firewall changes take a few minutes to take effect; re-check before concluding a rule is not working.
Storage
/data) on its own volume in the volume set, so data and cluster state survive restarts and upgrades. The nodes run with AOF persistence on (appendonly yes).
Authentication
redis.password creates the RELEASE_NAME-redis-cluster-auth secret and injects the value into both requirepass and masterauth in redis.conf, so clients and the nodes themselves authenticate with it. The password is a Helm value and is stored in the release. Add --no-auth-warning -a PASSWORD to every redis-cli call on this page when it is set.
Backup
Connecting
The template exposes no public endpoint. Reach the cluster from workloads in the same GVC, or from your machine throughcpln port-forward.
redis-cli -c): a plain client pointed at one node receives MOVED redirects it does not follow, which is the most common cause of “it does not work” with this template.
To verify the cluster, ask any node for its cluster state. ready on the workload only means the node answers; the cluster itself is created by replica 0 once every node is up, so during first boot a node can report ready for up to about a minute before the cluster exists.
cluster_state:ok with cluster_slots_assigned:16384 and cluster_known_nodes:6 means the cluster is formed. A write and read through the cluster protocol confirms redirects are followed (-c follows them):
redis-cli -p 6379 INFO server the same way: Valkey answers with server_name:valkey and a valkey_version line, Redis has neither.
From your own machine, cpln port-forward RELEASE_NAME-redis-cluster 6379:6379 --gvc GVC_NAME gives a local redis-cli -p 6379 a connection to one node — good for cluster info and inspecting that node’s keys, but not for cluster-mode use, because the redirect hostnames do not resolve outside the GVC.
Operations
Backing Up
Backups are off by default. Whenbackup.enabled is true, a cron workload runs on backup.schedule, finds the current primary of each shard, takes an RDB snapshot of each one and uploads them to your bucket as PREFIX/redis-YYYY-MM-DDTHH-MM-SSZ-node-N.rdb.gz, where N is the index of the node that was the primary at the time. A full run therefore produces three files. The job authenticates to the bucket through the workload identity’s cloud account binding — no static keys — and uses the cluster password automatically when redis.password is set.
backup.provider between aws and gcp on an existing release leaves the previous provider’s cloud binding on RELEASE_NAME-redis-cluster-identity: the rendered manifest is correct, but identity updates are merged rather than replaced. If least privilege matters to you, inspect the identity after a provider switch and remove the stale binding, or reinstall the release.AWS S3
- Create an S3 bucket. Set
backup.aws.bucketto its name andbackup.aws.regionto its region. - Create a cloud account for your AWS account if you do not have one. Set
backup.aws.cloudAccountNameto its name. - Create an IAM policy with the following JSON, replacing
YOUR_BUCKET_NAME, and setbackup.aws.policyNameto its name:
- Set
backup.aws.prefixto the folder path where backups will be stored, then setbackup.enabled: trueandbackup.provider: aws.
GCS
- Create a GCS bucket. Set
backup.gcp.bucketto its name. - Create a cloud account for your GCP project if you do not have one. Set
backup.gcp.cloudAccountNameto its name. - Grant the Storage Admin role to the GCP service account associated with the cloud account.
- Set
backup.gcp.prefixto the folder path where backups will be stored, then setbackup.enabled: trueandbackup.provider: gcp.
Restoring a Backup
What the backup is: three standard, gzipped RDB files, one per shard, and RDB files are portable. The upstream-documented way to read one is to start a standalone Redis or Valkey server with AOF disabled and the decompressed file in place as itsdump.rdb — for example on a local machine with Docker — and inspect or replay the data from there. Redis documents redis-cli --cluster import for moving keys from a standalone instance into a cluster; that path has not been tested against this template. If you need to load a backup into a running cluster, test the procedure against a throwaway release before relying on it.
Upgrading from an Earlier Version
- From 1.4.3 or earlier with AWS backups — permissions narrowed. Version 1.4.4 removed the AWS managed policy
ReadOnlyAccessfrom the backup identity. It granted read access to every bucket in your account and had been silently supplying any read action your own policy omitted. Update your IAM policy to the full action list under Backing Up before upgrading; if it already matches, nothing changes. The identity now carriescpln-connectorand your bucket-scoped policy only. - From 1.5.0 or earlier — a non-default
portnow works. In earlier versions any value other than6379crash-looped every node permanently, because the readiness probe and the start script always targeted the default port and the cluster bus was fixed at16379. Version 1.6.0 passes the configured port everywhere and derives the bus from it. At the default port nothing about the deployment changes. - From 1.5.0 or earlier — the readiness probe requires a real
PONG. Earlier versions ran a bareredis-cli ping, which exits 0 even when the server answersNOAUTH Authentication required, so a password-protected cluster could report ready without being usable. From 1.6.0 a node that cannot authenticate is not ready, and because the nodes roll in order, a bad credential stalls the rollout at the first replica instead of rolling all six into a broken state. - From 1.5.0 or earlier — cluster creation retries transient DNS failures. During first boot the cluster create step re-resolves every peer hostname, and a name that briefly stops resolving used to restart the container. From 1.6.0 creation retries in place and still fails loudly (
FATAL: cluster create did not succeed after 12 attempts) if it genuinely cannot succeed. - 1.6.0 adds
engine. The defaultredisdeploys exactly as before; see Engine before settingvalkey.
nodes.conf as the nodes come back.
Scaling and Availability
- The shape is fixed at six nodes: three primaries, each with exactly one replica.
replicasmust stay at6— see Cluster Size and Resources. Scale vertically withcpu,memoryandvolumeset.capacity(orvolumeset.autoscaling) instead. - Primary failure is handled by the cluster itself. The nodes run with
cluster-node-timeout 5000: when a primary stops responding for 5 seconds the other primaries agree it is down and its replica is promoted. Writes to that shard pause for the election; the other two shards keep serving. When the old primary returns it rejoins as a replica. - A cluster-aware client follows failovers automatically by refreshing its slot map from the
MOVEDredirects it receives. A client pinned to a single node does not. - Data survives restarts and upgrades, not an uninstall:
cpln helm uninstallremoves the volume set with the release. Take a backup first if the data matters.
Troubleshooting
MOVED errors, or keys that appear and disappear depending on the node
MOVED errors, or keys that appear and disappear depending on the node
(error) MOVED 12182 RELEASE_NAME-redis-cluster-1.RELEASE_NAME-redis-cluster:6379, or a key written through one node cannot be read through another.Cause: the client is not cluster-aware. Redis Cluster places each key on one of three primaries and answers requests for a key held elsewhere with a redirect that a plain client does not follow.Fix: use a cluster-aware client, or redis-cli -c. The client must run inside the same GVC, because the hostnames in the redirects (RELEASE_NAME-redis-cluster-N.RELEASE_NAME-redis-cluster) resolve only there.Workload is ready but cluster info reports cluster_state:fail or cluster_known_nodes:1
Workload is ready but cluster info reports cluster_state:fail or cluster_known_nodes:1
redis-cli -p 6379 cluster info on a node shows cluster_state:fail, cluster_slots_assigned:0 or cluster_known_nodes:1.Cause: ready means the node answers a PING, not that the cluster exists. Replica 0 creates the cluster only after all six nodes are up, and retries if a peer hostname briefly fails to resolve; during first boot this can take about a minute after the last node is ready. If it never settles, the nodes cannot reach each other — most often internalAccess.type: none.Fix: wait a minute and run cluster info again. If it still fails, check replica 0’s log for the create attempts and their outcome:FATAL: cluster create did not succeed after 12 attempts means creation was genuinely impossible: confirm internalAccess.type is not none, and that replicas is 6.Install rejected with exceed the autoscaling.maxScale of 6 (quota: replicas-per-replica-direct-workload)
Install rejected with exceed the autoscaling.maxScale of 6 (quota: replicas-per-replica-direct-workload)
cpln helm install or cpln helm upgrade fails while applying the workload with this message.Cause: replicas was set above 6. The cluster nodes are a replica-direct workload, and a built-in platform quota caps those at 6 replicas.Fix: set replicas: 6, the only supported value, and install again.NOAUTH Authentication required
NOAUTH Authentication required
redis-cli call answers (error) NOAUTH Authentication required.Cause: redis.password is set and the client did not authenticate.Fix: pass the password — redis-cli --no-auth-warning -a PASSWORD, or your client library’s password option. Read it back with cpln secret reveal RELEASE_NAME-redis-cluster-auth -o yaml.A node never becomes ready after changing engine, and cpln logs shows nothing
A node never becomes ready after changing engine, and cpln logs shows nothing
cpln helm upgrade that changed engine, the first replaced node never reports ready, cpln logs returns no lines for it and the deployment message is empty.Cause: the node’s data directory was written by a Redis release whose on-disk format Valkey cannot read (Can't handle RDB format version 15); the server exits immediately, and the start script discards its output, so nothing reaches the logs.Fix: set engine and image back to the values the data was written with and upgrade again. Migrate between engines with dump/restore or replication, never by switching engine on a release that holds data.Backup job restarts with reason OOMKilled
Backup job restarts with reason OOMKilled
cpln workload get-deployments RELEASE_NAME-redis-cluster-backup --gvc GVC_NAME -o yaml shows restarts with reason OOMKilled.Cause: the job dumps every primary in turn and the upload step needs more memory than backup.resources.memory allows; lowering it to 128Mi is known to fail during GCS uploads.Fix: keep backup.resources.memory at the default 512Mi or raise it.Clients can still connect after tightening internalAccess
Clients can still connect after tightening internalAccess
internalAccess.type or internalAccess.workloads, previously allowed clients keep connecting.Cause: firewall changes take a few minutes to propagate.Fix: wait and re-test before concluding the rule is not applied.Important Notes
- Your client must speak the Redis Cluster protocol and run inside the same GVC. A plain client gets
MOVEDredirects it will not follow, and the redirect hostnames resolve only inside the GVC. - Authentication is off by default. Anything
internalAccessadmits has full access until you setredis.password. - Keep
replicasat 6. Fewer cannot form a cluster; more is rejected by a platform quota. - Never set
internalAccess.type: none. The nodes stop reaching each other and the cluster breaks. - Choose
engineat install time. Switching it on a release that holds data is unsupported, and the failure leaves no log output. - Changing
portmoves the cluster bus too (port + 10000); clients and firewall rules that expect16379must move with it. - The default
250Miper node is a floor. Sizememoryfor your dataset before putting real load on the cluster. - This is not interchangeable with the Redis template. That one is primary/replica with Sentinel and a single write endpoint; this one shards the keyspace. Moving between them is a data migration, not a values change.
- Bucket backups have no verified in-place restore. Treat them as portable RDB files; see Restoring a Backup.
cpln helm uninstalldeletes the volume set and with it the data. Back up first.