|
| 1 | +## Redis Sentinel |
| 2 | + |
| 3 | +Creates a Redis Sentinel cluster on Control Plane with automatic leader election, failover, and an optional backup configuration. |
| 4 | + |
| 5 | +### Configuration |
| 6 | + |
| 7 | +**Redis and Sentinel** — set replicas, resources, and timeouts for each. Sentinel replicas must be an odd number for quorum: |
| 8 | +```yaml |
| 9 | +redis: |
| 10 | + replicas: 2 |
| 11 | + resources: |
| 12 | + minCpu: 80m |
| 13 | + minMemory: 128Mi |
| 14 | + cpu: 200m |
| 15 | + memory: 256Mi |
| 16 | + |
| 17 | +sentinel: |
| 18 | + replicas: 3 |
| 19 | + quorumAutoCalculation: true # calculates as (replicas/2)+1 |
| 20 | +``` |
| 21 | +
|
| 22 | +**Authentication** — enable one method. Apply the same config under both `redis.auth` and `sentinel.auth`: |
| 23 | +```yaml |
| 24 | +redis: |
| 25 | + auth: |
| 26 | + password: |
| 27 | + enabled: true |
| 28 | + value: your-password |
| 29 | + # fromSecret: |
| 30 | + # enabled: true |
| 31 | + # name: my-redis-secret |
| 32 | + # passwordKey: password |
| 33 | +``` |
| 34 | + |
| 35 | +**Persistence** — disabled by default. Enable to attach a persistent volume to Redis: |
| 36 | +```yaml |
| 37 | +redis: |
| 38 | + persistence: |
| 39 | + enabled: true |
| 40 | + volumes: |
| 41 | + data: |
| 42 | + initialCapacity: 10 |
| 43 | + performanceClass: general-purpose-ssd # or high-throughput-ssd (min 1000 GiB) |
| 44 | + fileSystemType: ext4 |
| 45 | +``` |
| 46 | + |
| 47 | +When persistence is enabled, lifecycle hooks are automatically added to clean up orphaned temp RDB and AOF rewrite files on every container start and stop. These files are left behind when a pod is terminated mid-sync and can fill the volume over time if not removed. |
| 48 | + |
| 49 | +**Probe tuning for large datasets** — the startup probe window is derived from the readiness probe: |
| 50 | +``` |
| 51 | +startup window = initialDelaySeconds + (30 × periodSeconds) |
| 52 | +``` |
| 53 | +The default (`10 + 30×5 = 160s`) is sufficient for small datasets. With persistence enabled and a large dataset, replicas must load their local AOF before syncing — which can take 60–120s or more — leaving little time for the actual RDB transfer. Increase `periodSeconds` to extend the window: |
| 54 | +```yaml |
| 55 | +redis: |
| 56 | + probes: |
| 57 | + readiness: |
| 58 | + initialDelaySeconds: 35 # clears the AOF load window |
| 59 | + periodSeconds: 20 # startup window = 35 + (30×20) = 635s (~10 min) |
| 60 | +``` |
| 61 | + |
| 62 | +**Metrics exporter** — disabled by default. When enabled, a `redis_exporter` sidecar is added to each Redis pod. Control Plane scrapes `:9121/metrics` automatically every 30 seconds and makes the metrics available in the console: |
| 63 | +```yaml |
| 64 | +redis: |
| 65 | + exporter: |
| 66 | + enabled: true |
| 67 | +``` |
| 68 | +Use `dropMetrics` to filter high-cardinality series before they are stored (regex patterns matched against metric names): |
| 69 | +```yaml |
| 70 | +redis: |
| 71 | + exporter: |
| 72 | + dropMetrics: |
| 73 | + - "redis_commands_latencies_usec_bucket" |
| 74 | + - "redis_latency_percentiles_usec" |
| 75 | +``` |
| 76 | + |
| 77 | +**Firewall** — set the internal access scope for both Redis and Sentinel: |
| 78 | +```yaml |
| 79 | +firewall: |
| 80 | + internal_inboundAllowType: same-gvc # same-gvc, same-org, or workload-list |
| 81 | +``` |
| 82 | + |
| 83 | +### Public Access (External TCP) |
| 84 | + |
| 85 | +Redis and Sentinel can be exposed over the internet via TCP using Control Plane's domain resource with per-replica port routing. |
| 86 | + |
| 87 | +#### Prerequisites |
| 88 | + |
| 89 | +1. **A domain you control** with DNS managed by your registrar (e.g. Cloudflare) |
| 90 | +2. **Dedicated Load Balancer** enabled on your GVC — required for arbitrary TCP port routing. Enable this under your GVC settings in the Control Plane console. |
| 91 | +3. **DNS records added before deploying** — Control Plane will reject the domain resource on first deploy if ownership has not been proven. Add the following records in your DNS provider for each address before running the deployment. **Disable proxying** (e.g. Cloudflare's orange cloud) — TCP traffic must pass through directly: |
| 92 | + |
| 93 | +| Type | Name | Value | |
| 94 | +|------|------|-------| |
| 95 | +| TXT | `_cpln-<subdomain>` | your Control Plane org name or org ID (either is accepted) | |
| 96 | +| CNAME | `<subdomain>` | `<gvc-alias>.cpln.app` | |
| 97 | + |
| 98 | +Your GVC alias is visible in the Control Plane console under GVC settings. The TXT record proves domain ownership — without it, the first deploy will fail with an `Unable to apply domain` error. |
| 99 | + |
| 100 | +#### Configuration |
| 101 | + |
| 102 | +Enable `publicAccess` for Redis and/or Sentinel and set a subdomain you own: |
| 103 | + |
| 104 | +```yaml |
| 105 | +redis: |
| 106 | + publicAccess: |
| 107 | + enabled: true |
| 108 | + address: redis.your-domain.com |
| 109 | + firewall: |
| 110 | + internal_inboundAllowType: same-gvc |
| 111 | + external_inboundAllowCIDR: "0.0.0.0/0" # or restrict to specific CIDRs |
| 112 | +
|
| 113 | +sentinel: |
| 114 | + publicAccess: |
| 115 | + enabled: true |
| 116 | + address: redis-sentinel.your-domain.com |
| 117 | + firewall: |
| 118 | + internal_inboundAllowType: same-gvc |
| 119 | + external_inboundAllowCIDR: "0.0.0.0/0" |
| 120 | +``` |
| 121 | + |
| 122 | +When enabled, a Control Plane `domain` resource is created for each address. Port mapping is one port per replica: |
| 123 | +- **Redis**: ports `6380`, `6381`, ... (replica 0, 1, ...) |
| 124 | +- **Sentinel**: ports `26380`, `26381`, `26382`, ... (replica 0, 1, 2, ...) |
| 125 | + |
| 126 | +After DNS propagates, the domain status in Control Plane will show **Ready**. You can verify the full DNS chain resolves correctly with: |
| 127 | + |
| 128 | +```bash |
| 129 | +dig <subdomain>.your-domain.com CNAME # should return <gvc-alias>.cpln.app |
| 130 | +dig <gvc-alias>.cpln.app # should return an IP address |
| 131 | +``` |
| 132 | + |
| 133 | +#### Connecting Externally (Public Access Enabled) |
| 134 | + |
| 135 | +```bash |
| 136 | +# add -a <password> if auth is enabled |
| 137 | +
|
| 138 | +# Redis replica 0 |
| 139 | +redis-cli -h redis.your-domain.com -p 6380 ping |
| 140 | +
|
| 141 | +# Redis replica 1 |
| 142 | +redis-cli -h redis.your-domain.com -p 6381 ping |
| 143 | +
|
| 144 | +# Sentinel replica 0 |
| 145 | +redis-cli -h redis-sentinel.your-domain.com -p 26380 ping |
| 146 | +``` |
| 147 | + |
| 148 | +### Connecting |
| 149 | + |
| 150 | +Redis is accessible internally on port 6379: |
| 151 | +``` |
| 152 | +RELEASE_NAME-redis.GVC_NAME.cpln.local:6379 |
| 153 | +``` |
| 154 | + |
| 155 | +Sentinel is accessible on port 26379: |
| 156 | +``` |
| 157 | +RELEASE_NAME-sentinel.GVC_NAME.cpln.local:26379 |
| 158 | +``` |
| 159 | + |
| 160 | +To route writes to the current master: |
| 161 | +```bash |
| 162 | +MASTER_INFO=$(redis-cli -h RELEASE_NAME-sentinel.GVC_NAME.cpln.local -p 26379 SENTINEL get-master-addr-by-name mymaster) |
| 163 | +MASTER_HOST=$(echo $MASTER_INFO | cut -d' ' -f1) |
| 164 | +MASTER_PORT=$(echo $MASTER_INFO | cut -d' ' -f2) |
| 165 | +redis-cli -h $MASTER_HOST -p $MASTER_PORT SET my-key "value" |
| 166 | +``` |
| 167 | + |
| 168 | +### Backing Up |
| 169 | + |
| 170 | +Set `backup.enabled` to `true`, configure your provider, and set your desired schedule. The backup image is compatible with all Redis versions. |
| 171 | + |
| 172 | +```yaml |
| 173 | +backup: |
| 174 | + enabled: true |
| 175 | + schedule: "0 2 * * *" # daily at 2am UTC |
| 176 | + provider: aws # Options: aws or gcp |
| 177 | +``` |
| 178 | + |
| 179 | +#### AWS S3 |
| 180 | + |
| 181 | +For the backup cron job to access an S3 bucket, complete the following in your AWS account first: |
| 182 | + |
| 183 | +1. Create your bucket. Set `backup.aws.bucket` to its name and `backup.aws.region` to its region. |
| 184 | + |
| 185 | +2. If you do not have a Cloud Account set up, refer to the docs to [Create a Cloud Account](https://docs.controlplane.com/guides/create-cloud-account). Set `backup.aws.cloudAccountName` to its name. |
| 186 | + |
| 187 | +3. Create a new IAM policy with the following JSON (replace `YOUR_BUCKET_NAME`) and set `backup.aws.policyName` to match: |
| 188 | + |
| 189 | +```json |
| 190 | +{ |
| 191 | + "Version": "2012-10-17", |
| 192 | + "Statement": [ |
| 193 | + { |
| 194 | + "Effect": "Allow", |
| 195 | + "Action": [ |
| 196 | + "s3:GetObject", |
| 197 | + "s3:PutObject", |
| 198 | + "s3:DeleteObject", |
| 199 | + "s3:ListBucket", |
| 200 | + "s3:GetObjectVersion", |
| 201 | + "s3:DeleteObjectVersion" |
| 202 | + ], |
| 203 | + "Resource": [ |
| 204 | + "arn:aws:s3:::YOUR_BUCKET_NAME", |
| 205 | + "arn:aws:s3:::YOUR_BUCKET_NAME/*" |
| 206 | + ] |
| 207 | + } |
| 208 | + ] |
| 209 | +} |
| 210 | +``` |
| 211 | + |
| 212 | +#### GCS |
| 213 | + |
| 214 | +For the backup cron job to access a GCS bucket, complete the following in your GCP account first: |
| 215 | + |
| 216 | +1. Create your bucket. Set `backup.gcp.bucket` to its name. |
| 217 | + |
| 218 | +2. If you do not have a Cloud Account set up, refer to the docs to [Create a Cloud Account](https://docs.controlplane.com/guides/create-cloud-account). Set `backup.gcp.cloudAccountName` to its name. |
| 219 | + |
| 220 | +**Important**: You must add the `Storage Admin` role when creating your GCP service account. |
| 221 | + |
| 222 | +### Restoring a Backup |
| 223 | + |
| 224 | +Run the following command from a client with access to the bucket (replace `aws s3 cp` with `gsutil cp` for GCS): |
| 225 | + |
| 226 | +```sh |
| 227 | +aws s3 cp s3://BUCKET_NAME/PREFIX/BACKUP_FILE.rdb /tmp/dump.rdb |
| 228 | +redis-cli \ |
| 229 | + -h RELEASE_NAME-redis.GVC_NAME.cpln.local \ |
| 230 | + -p 6379 \ |
| 231 | + --rdb /tmp/dump.rdb |
| 232 | +``` |
| 233 | + |
| 234 | +### Supported External Services |
| 235 | +- [Redis Documentation](https://redis.io/docs/) |
| 236 | +- [Redis Sentinel Documentation](https://redis.io/docs/latest/operate/oss_and_stack/management/sentinel/) |
| 237 | + |
| 238 | +### Release Notes |
| 239 | +See [RELEASES.md](https://github.com/controlplane-com/templates/blob/main/redis/RELEASES.md) |
0 commit comments