Redis · 集群共享缓存(Sentinel HA)
集群级的共享 Redis 缓存,服务于 app / platform / game 等多个命名空间。
applications/data/redis/ 这个目录在 Sentinel HA 切换后已不再持有 Redis 实例本身:原先的单机 redis Deployment/ConfigMap/PVC 已下线,真正运行的实例位于 applications/data/redis-ha/(3 个 redis + 3 个 sentinel + 2 个 haproxy)。本目录现在只保留对外的共享 redis Service(指向 HAProxy)、监控、namespace 的 quota/limitrange 以及网络策略。
redis Service 的 selector 已重指向 redis-ha-haproxy,HAProxy 始终路由到当前 master,故障转移期间 redis.redis.svc:6379 端点保持不变。回滚方式是把 selector 改回 app: redis(根据 kustomization 与 Service 注释)。部署形态
下面分两部分:本目录(data/redis)实际渲染出的资源,以及它所代理的 HA 栈(data/redis-ha)。
data/redis 目录渲染出的工作负载只有监控 exporter:
- Name
- 命名空间
- Description
- redis
- Name
- 工作负载
- Description
- redis-exporter,Deployment,replicas 1
- Name
- 镜像
- Description
- oliver006/redis_exporter:v1.86.0
- Name
- 端口
- Description
- 9121 (metrics)
- Name
- 资源
- Description
- requests 10m / 32Mi,limits 100m / 128Mi
它所代理的 Sentinel HA 栈(data/redis-ha,镜像均为 redis:8.8-alpine,HAProxy 为 haproxy:3.4-alpine):
| 组件 | 类型 | 副本 | 镜像 | 端口 | 存储 |
|---|---|---|---|---|---|
| redis-ha | StatefulSet | 3 | redis:8.8-alpine | 6379 | volumeClaimTemplate 20Gi,local-path,RWO |
| redis-ha-sentinel | StatefulSet | 3 | redis:8.8-alpine | 26379 | volumeClaimTemplate 1Gi,local-path,RWO |
| redis-ha-haproxy | Deployment | 2 | haproxy:3.4-alpine | 6379 | 无(emptyDir 临时目录) |
redis 与 sentinel 两组 StatefulSet 都用 requiredDuringSchedulingIgnoredDuringExecution 的 podAntiAffinity 按 kubernetes.io/hostname 强制分散到不同节点,使单节点宕机不会带走 quorum(这正是引发本次 HA 改造的 worker3 事件);haproxy 用 preferred 反亲和尽量分散。redis 容器内存 limit 上限 2Gi,与 namespace LimitRange 的 container max 一致,也对齐了原单机 redis 的 maxmemory 2gb 上限。
data/redis-ha 尚未接入 bootstrap/,部署是一个有意为之的手动步骤,而非 ArgoCD 自动同步(见该目录的 kustomization 与 CUTOVER.md 注释)。配置与依赖
密码通过 ExternalSecret 从 Vault 注入,redis、sentinel、haproxy、exporter 四类容器都引用同一个 redis-secret。
- Name
- ExternalSecret
- Description
- redis-secret,ClusterSecretStore vault-backend,refreshInterval 1h
- Name
- remoteRef.key
- Description
- secret/database/prod/redis(property: password)
- Name
- 注入 env
- Description
- REDIS_PASSWORD,来自 redis-secret 的 REDIS_PASSWORD 键
HA 栈各组件的运行配置由 data/redis-ha 下的三个 ConfigMap 提供:redis-ha-config(redis.conf + entrypoint.sh)、redis-ha-sentinel-config(sentinel.conf + entrypoint.sh)、redis-ha-haproxy-config(haproxy.cfg + entrypoint.sh),容器以 command: ["/bin/sh", "/scripts/entrypoint.sh"] 启动。redis 探针用 redis-cli -a $REDIS_PASSWORD --no-auth-warning ping,sentinel 探针用 redis-cli -p 26379 ping,haproxy 用 6379 的 TCP 探针。
命名空间设有 ResourceQuota(按 HA 栈规模:pods 15、requests.cpu 800m、requests.memory 2Gi、limits.cpu 6、limits.memory 8Gi)和 LimitRange(container max 1 CPU / 2Gi,默认 100m / 128Mi)。
访问与监控
集群内统一通过 redis Service 访问,对外另有一个 NodePort。
- Name
- 集群内 Service
- Description
- redis,ClusterIP,6379,selector app: redis-ha-haproxy
- Name
- 外部访问
- Description
- redis-nodeport,NodePort,6379 → nodePort 30379,同样指向 HAProxy
- Name
- Sentinel Service
- Description
- redis-ha-sentinel,Headless(clusterIP None),26379,publishNotReadyAddresses
- Name
- HAProxy Service
- Description
- redis-ha-haproxy,ClusterIP,6379
监控:redis-exporter Deployment 通过 REDIS_ADDR=redis://redis:6379 连接缓存并暴露 9121 端口指标,redis-exporter Service(ClusterIP)前置之,redis ServiceMonitor 以 30s 间隔抓取 /metrics(relabel 后 service/job 均为 redis)。本目录未包含 PrometheusRule、HPA、VPA、PDB。
网络层在 namespace 上做了 default-deny-ingress(podSelector 全空),再按需放行:same-namespace、来自 app/game/platform 的访问、Prometheus 抓取、glitchtip、argo-workflows,以及 DNS egress。
注意事项
CLAUDE.md 没有针对 redis 的专门踩坑段,以下事实直接来自 manifest 注释,值得留意:
- 单机 redis 已下线但保留可回滚:切换的本质是把
redis/redis-nodeport两个 Service 的 selector 从app: redis改成app: redis-ha-haproxy,客户端端点不变;若要回滚,把 selector 改回app: redis。 - HA 栈未纳入 ArgoCD 自动同步:
data/redis-ha未接入bootstrap/,需手动部署,改动这里不会被自动 reconcile;切换流程见同目录CUTOVER.md。 - 反亲和是硬约束:3 个 redis 与 3 个 sentinel 各自必须分散到不同节点(
requiredDuringScheduling),节点数不足会导致 Pod 调度不出来。 - 存储用 local-path:redis/sentinel 的 PVC 钉在所在节点本地盘(README 的"数据库 local-path,PV 钉本节点"),Pod 漂移会受 PV 节点亲和约束。
返回 data 服务总览