EKS部署Bitnami Redis(哨兵+LB):写入报错解决方案及主节点访问疑问
问题场景
我在Amazon EKS中部署了Bitnami Redis,并配置了哨兵(Sentinel)与LoadBalancer(AWS内部NLB)以实现集群外部访问,部分配置如下:
sentinel: enabled: true ... service: type: LoadBalancer ... annotations: service.beta.kubernetes.io/aws-load-balancer-scheme: "internal" service.beta.kubernetes.io/aws-load-balancer-name: "eks-redis" service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxx,subnet-yyy
当前NLB返回两个IP,分别指向主节点和副本节点。应用有时会连接到副本节点,执行写入操作时触发报错READONLY You can't write against a read only replica.,且我无法修改应用代码。请问该场景下的最佳解决方案是什么?目前我仅了解HAproxy方案,是否有更简便的实现方式?
另外想问:Redis默认Service是否始终指向主节点,还是会随机选择到从节点?
解决方案
更简便的实现方式:利用Bitnami Redis自带的主节点专属Service
Bitnami Redis Chart在启用Sentinel后,会自动创建一个仅指向当前主节点的Service,命名规则为{RELEASE_NAME}-redis-master(例如Release名为eks-redis时,对应Service为eks-redis-redis-master)。无需额外部署HAproxy,只需调整LoadBalancer的关联对象即可解决问题:
- 将原绑定到Redis集群Service的LoadBalancer配置,转移到这个主节点专属Service上
- 修改后的配置示例:
sentinel: enabled: true # 保留集群默认Service为ClusterIP,供内部节点访问 service: type: ClusterIP # 单独为主节点配置LoadBalancer master: service: type: LoadBalancer annotations: service.beta.kubernetes.io/aws-load-balancer-scheme: "internal" service.beta.kubernetes.io/aws-load-balancer-name: "eks-redis-master" service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxx,subnet-yyy
配置完成后,NLB只会指向当前的Redis主节点,Sentinel会在主节点故障切换时自动更新该Service的Endpoint,确保流量始终路由到可写入的主节点,彻底解决写入报错问题。
关于Redis默认Service的指向问题
- Redis默认的集群Service(不带
-master后缀),其Pod selector会匹配所有Redis节点(主+从),Kubernetes会以随机负载均衡的方式将流量分发到所有节点,并非始终指向主节点。 - 而
{RELEASE_NAME}-redis-masterService的selector仅匹配当前主节点的Pod,Sentinel会实时监控主节点状态,一旦发生故障切换,会自动更新该Service的Endpoint,保证始终指向新的主节点。
内容的提问来源于stack exchange,提问作者prosto.vint
相关产品推荐
相关产品推荐

