Kubernetes上配置多副本MongoDB写操作报not master错误如何解决
配置方案
方案1:使用MongoDB原生副本集连接机制(推荐)
该方案为最优解,MongoDB官方驱动原生支持副本集主节点自动发现、主从切换感知、读写请求自动路由,不需要在Kubernetes侧额外做流量拆分配置,操作步骤如下:
- 首先删除你当前创建的轮询所有副本的通用LoadBalancer Service,MongoDB Community Operator部署副本集时默认会为每个副本实例创建独立的访问Service,同时会生成Headless Service用于副本集内部域名解析。
- 如果你需要集群外访问副本集,可以为每个副本单独创建NodePort/LoadBalancer类型的Service,或者开启Operator的外部访问配置项自动生成对外访问入口。
- 修改业务端的MongoDB连接串,使用副本集模式拼接,示例如下:
./mongo "mongodb://admin:{password}@{副本1外部地址}:27017,{副本2外部地址}:27017,{副本3外部地址}:27017/admin?authSource=admin&replicaSet={你的副本集名称}&readPreference=secondaryPreferred"
参数说明:
replicaSet:替换为你部署的MongoDB副本集的实际名称,Community Operator部署的副本集名称默认和自定义资源名称一致readPreference:按业务需要配置读偏好,设为secondaryPreferred即可实现优先走从节点读、主节点可写的需求,驱动会自动将所有写请求路由到当前主节点
注意:你此前使用的连接串中
authSource=admi属于拼写错误,正确值应为authSource=admin,否则会触发认证失败报错。
这个方案的优势是完全适配MongoDB副本集的主从切换逻辑,主节点发生故障转移时驱动会自动识别新主节点,无需人工调整Kubernetes配置。
方案2:拆分Kubernetes Service实现读写路由分离
如果业务端不方便修改连接串适配副本集模式,可以通过两个独立的Service分别路由读写请求,依赖MongoDB Community Operator自动同步的节点角色标签实现流量分发:
步骤1:创建主节点专用Service(处理写请求)
该Service仅选择当前主节点,所有写请求都走这个Service的地址:
apiVersion: v1 kind: Service metadata: name: mongodb-primary-service labels: name: mongo-primary spec: ports: - port: 27017 targetPort: 27017 selector: mongodb.com/role: primary # Operator会自动为当前主节点打上该标签,主切换时自动更新 type: LoadBalancer
步骤2:创建全节点专用Service(处理读请求)
该Service选择所有可用的副本节点,所有读请求走这个Service的地址:
apiVersion: v1 kind: Service metadata: name: mongodb-read-service labels: name: mongo-read spec: ports: - port: 27017 targetPort: 27017 selector: app.kubernetes.io/component: mongodb # 匹配所有MongoDB副本实例的标签 type: LoadBalancer
配置完成后业务端写请求走mongodb-primary-service的对外地址,读请求走mongodb-read-service的对外地址即可。
内容的提问来源于stack exchange,提问作者kobra
相关产品推荐
相关产品推荐

