Redis 哨兵模式部署与故障切换验证

需要在 K8s 上为平台部署高可用(哨兵模式)Redis,或验证主节点故障自动切换、配置平台连接哨兵时

04-运维管理 / 中间件
Redis哨兵sentinel哨兵模式高可用HAfailover故障转移主从切换redis-clusterredis-sentinelpv-pvcmymaster26379SENTINEL_NODESREDIS_SENTINEL_PASSWORD

Redis 哨兵模式部署与故障切换验证

在 K8s 上部署一套哨兵(Sentinel)模式 Redis,实现主从高可用与主节点故障自动切换,供平台做缓存 / Celery broker 使用。相关清单在 install/kubernetes/redis/sentinel/ 目录下。

一、组件构成

清单文件 作用 关键参数(以源码为准)
pv-pvc.yaml 为 3 个 Redis Pod 各准备 1 个 PV+PVC hostPath /data/k8s/infra/redis/pv-0..2storageClassName: manual,每个 1Gi,Retain 回收策略
redis-cluster.yaml Redis 主从(StatefulSet,3 副本) 镜像 redis:6.0-alpine,端口 6379;redis-0 为主,其余 replicaof redis-0.redis 6379
redis-sentinel.yaml 哨兵(Deployment,3 副本) 镜像 redis:6.0-alpine,端口 26379;ConfigMap sentinel monitor mymaster redis-0.redis 6379 2
test-sentinel.py Python 连通性与故障切换测试脚本 需改 SENTINEL_NODESSERVICE_NAME=mymaster

要点:

  • Redis 主从用 StatefulSet(稳定网络标识 redis-0/1/2),主节点固定为 redis-0,其余 Pod 启动时 replicaof redis-0.redis 6379;Service 名为 redis(headless,clusterIP: None)。
  • 哨兵用 Deployment(3 副本),监听 26379,配置 sentinel monitor mymaster redis-0.redis 6379 2(quorum=2)、down-after-milliseconds 5000failover-timeout 60000。哨兵配置从只读 ConfigMap 复制到可写 /data 后再启动,运行态数据用 emptyDir(Pod 重启会丢,但状态可重建)。
  • 如果 Redis 设了密码,需在哨兵 ConfigMap 里放开 sentinel auth-pass mymaster <密码>requirepass <密码>

二、部署步骤

# 1) 部署 pv-pvc 存储
kubectl apply -f pv-pvc.yaml

# 2) 部署 redis-cluster 主从
kubectl apply -f redis-cluster.yaml
# 查看 redis-cluster pod 是否 running
kubectl get pod

# 3) 部署 redis-sentinel 哨兵
kubectl apply -f redis-sentinel.yaml
# 查看 redis-sentinel pod 是否 running
kubectl get pod

三、连通性测试(Python 哨兵客户端)

# 修改 test-sentinel.py 中 SENTINEL_NODES 的主机列表,改为 redis-sentinel pod 的 IP 地址
python test-sentinel.py

test-sentinel.py 行为(见 install/kubernetes/redis/sentinel/test-sentinel.py):

  • redis.sentinel.Sentinel 连接哨兵列表,SERVICE_NAME='mymaster'
  • 每 5 秒(WRITE_INTERVAL)向主节点写一次 sentinel_test:data,并分别从主、从节点读取,演示读写分离;
  • 通过 sentinel.discover_master('mymaster') 打印当前主节点地址;写失败时自动用 master_for(...) 重新发现新主节点(验证自动切换)。

注意:脚本里 PASSWORD = 'None' 是字符串 'None' 而非 Python None;如果你的 Redis 无密码,按脚本默认即可,有密码则改成真实口令。

四、主节点故障切换验证

# 1) 获取一个哨兵 Pod 名称
SENTINEL_POD=$(kubectl get pods -l app=redis-sentinel -o jsonpath='{.items[0].metadata.name}')

# 2) 通过哨兵查询当前主节点地址
kubectl exec -it $SENTINEL_POD -- redis-cli -p 26379 sentinel get-master-addr-by-name mymaster

# 3) 找到该 IP 对应的 Pod 并删除,模拟主节点宕机
kubectl get pod -owide
kubectl delete pod redis-x        # 把 redis-x 换成上一步主节点 IP 对应的 pod

删除主节点 Pod 后,哨兵应在 down-after-milliseconds(5s) + 选举时间内把某个从节点提升为新主;再次执行第 2 步的 get-master-addr-by-name 应返回新的主节点地址,test-sentinel.py 也会自动写入新主节点。

五、平台侧连接哨兵

平台默认连单实例 Redis(REDIS_HOST/REDIS_PORT/REDIS_PASSWORD)。切换到哨兵模式需在配置里改用哨兵相关项(myapp/config.py:495-504,默认被注释):

# 哨兵模式 redis 配置
REDIS_PASSWORD = 'wenwang'              # Redis 没有密码则填 None
REDIS_SENTINEL_PASSWORD = 'wenwangsentinel'   # 哨兵没有密码填 None
SENTINEL_SERVICE_NAME = 'mymaster'      # Sentinel master 名称,与上面 monitor 的名字一致
SENTINEL_NODES = [                      # 哨兵节点列表
    ('10.42.0.88', 26379),
    ('10.42.0.89', 26379),
    ('10.42.0.90', 26379),
]

单实例与哨兵两套配置项是互斥的:启用 SENTINEL_NODES 等哨兵项时,确保 SENTINEL_SERVICE_NAME 与哨兵 ConfigMap 里 sentinel monitor <name> 的名字(示例为 mymaster)一致。具体生效逻辑以 myapp/config.py 及读取该配置的代码为准。

相关

最后更新 2026-06-30完整文档以官方仓库为准:GitHub Wiki