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..2,storageClassName: 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_NODES,SERVICE_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 5000、failover-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'而非 PythonNone;如果你的 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及读取该配置的代码为准。
相关
- 哨兵 Redis 的 PV 落在
/data/k8s/infra/redis/pv-*,目录约定见「分布式存储目录.md」。