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 以及网络策略。

部署形态

下面分两部分:本目录(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-haStatefulSet3redis:8.8-alpine6379volumeClaimTemplate 20Gi,local-path,RWO
redis-ha-sentinelStatefulSet3redis:8.8-alpine26379volumeClaimTemplate 1Gi,local-path,RWO
redis-ha-haproxyDeployment2haproxy:3.4-alpine6379无(emptyDir 临时目录)

redis 与 sentinel 两组 StatefulSet 都用 requiredDuringSchedulingIgnoredDuringExecution 的 podAntiAffinity 按 kubernetes.io/hostname 强制分散到不同节点,使单节点宕机不会带走 quorum(这正是引发本次 HA 改造的 worker3 事件);haproxy 用 preferred 反亲和尽量分散。redis 容器内存 limit 上限 2Gi,与 namespace LimitRange 的 container max 一致,也对齐了原单机 redis 的 maxmemory 2gb 上限。

配置与依赖

密码通过 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 服务总览

评论