mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-05 03:27:07 +09:00
## What this PR does Fixes #2514. When `external: true` is set on a non-sharded `MongoDB`, Cozystack rendered a single `LoadBalancer` Service whose selector matched **all** replica-set members (`app.kubernetes.io/replset: rs0`). Round-robin balancing sent ~⅔ of writes to secondaries and they were rejected with `MongoServerError: not primary`. Drivers couldn't recover on their own either: connecting through the LB returned the in-cluster DNS names of all members from `isMaster`, none of which resolve from outside the cluster, so automatic primary discovery failed. This PR replaces the manual `external-svc.yaml` (for replica-set mode) with the Percona MongoDB operator's native `replsets[].expose` feature: ```yaml replsets: - name: rs0 expose: enabled: true type: LoadBalancer externalTrafficPolicy: Local ``` The operator then: - creates one `LoadBalancer` Service **per pod** (`<release>-rs0-0`, `-1`, `-2`) with `statefulset.kubernetes.io/pod-name` selectors, - watches `Service.status.loadBalancer.ingress` for each pod and rewrites the member `host` in `rs.conf` to the external IPs. External clients use a standard replica-set URI (`mongodb://...:27017,...:27017,...:27017/?replicaSet=rs0`) and the driver discovers the primary correctly from outside the cluster. For **sharded** mode the existing single `LoadBalancer` is preserved — it front-ends stateless `mongos`, which can route writes to the right shard primary itself. `external-svc.yaml` is now scoped to that case only. ### Tested - `helm unittest .` in `packages/apps/mongodb/`: 91/91 pass. - Applied on a dev stand: - `replsets[0].expose` is set as expected in the rendered PSMDB CR. - The Percona operator (`v1.21.1`) accepts the spec and creates 3 per-pod `LoadBalancer` Services with `statefulset.kubernetes.io/pod-name` selectors. The previous single round-robin Service is no longer rendered. - With an LB IP pool present, the operator promotes the allocated LB IPs into the PSMDB `status.host` field and into `rs.conf`. End-to-end mongosh write loop wasn't run on the dev stand because the underlying network does not advertise/route allocated LoadBalancer IPs (no working L2/BGP path), so the rewritten `rs.conf` members are unreachable in that environment. The structural change is otherwise fully verified and the issue's reproduction scenario expects a real LB-capable network. ### Release note ```release-note fix(mongodb): expose each replica-set member through its own LoadBalancer when `external: true`, so external clients can discover the primary via the standard replica-set connection string and writes no longer fail with "not primary" errors. ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * External LoadBalancer services now only render when both external and sharding are enabled. * Replica set external exposure is now conditional based on the external setting. * Service configuration now uses LoadBalancer type with Local traffic policy for external access. * Service selectors refined for proper mongos targeting in sharded deployments. <!-- end of auto-generated comment: release notes by coderabbit.ai -->