From b4935db4beee73045f99a43bd975eac223f50ac8 Mon Sep 17 00:00:00 2001 From: younsl Date: Thu, 27 Aug 2026 19:47:08 +0900 Subject: [PATCH] feat(chart): support Service trafficDistribution Add `service.trafficDistribution` and `pairingRelay.service.trafficDistribution` so operators can enable topology-aware routing on the relay and pairing relay Services. Empty (the default) omits `spec.trafficDistribution` entirely, so rendered manifests are unchanged for existing installs. The schema restricts values to the ones the API server accepts (`PreferClose`, `PreferSameZone`, `PreferSameNode`), catching typos at install time rather than at apply time. Release chart 0.1.9. Signed-off-by: younsl --- deploy/charts/buzz/Chart.yaml | 4 +-- deploy/charts/buzz/README.md | 23 +++++++++++++++ .../charts/buzz/templates/pairing-relay.yaml | 3 ++ deploy/charts/buzz/templates/service.yaml | 3 ++ deploy/charts/buzz/tests/networking_test.yaml | 28 +++++++++++++++++++ .../charts/buzz/tests/pairing_relay_test.yaml | 19 +++++++++++++ deploy/charts/buzz/values.schema.json | 6 ++-- deploy/charts/buzz/values.yaml | 4 +++ 8 files changed, 86 insertions(+), 4 deletions(-) diff --git a/deploy/charts/buzz/Chart.yaml b/deploy/charts/buzz/Chart.yaml index 49a6fafd192..5969c1f3aaa 100644 --- a/deploy/charts/buzz/Chart.yaml +++ b/deploy/charts/buzz/Chart.yaml @@ -7,7 +7,7 @@ description: | PostgreSQL and Redis. Configurable for single-node evaluation (subcharts on) and HA production (external services, existingSecret). type: application -version: 0.1.8 +version: 0.1.9 appVersion: "0.1.0" home: https://github.com/block/buzz sources: @@ -24,7 +24,7 @@ maintainers: annotations: artifacthub.io/changes: | - kind: added - description: Optional immutable relay image digest pinning with backwards-compatible tag fallback. + description: Optional Service spec.trafficDistribution for the relay and pairing relay Services. artifacthub.io/license: Apache-2.0 # Optional eval-only subcharts. Production deploys disable both and point diff --git a/deploy/charts/buzz/README.md b/deploy/charts/buzz/README.md index 8a4b0c6d665..b13dab0893e 100644 --- a/deploy/charts/buzz/README.md +++ b/deploy/charts/buzz/README.md @@ -216,6 +216,29 @@ adapter (for example Prometheus Adapter) configured to expose the relay's install or configure a cluster-wide metrics adapter. Scale-down is gradual by default so long-lived WebSocket connections have time to drain. +### Topology-aware routing + +`service.trafficDistribution` (and `pairingRelay.service.trafficDistribution`) set +the Service `spec.trafficDistribution` field, which biases routing toward +endpoints near the client instead of spreading evenly across all ready endpoints: + +```yaml +service: + trafficDistribution: PreferClose +``` + +| Value | Effect | Requires | +|---|---|---| +| `""` (default) | Field omitted — cluster default, even spread | — | +| `PreferClose` | Prefer topologically close endpoints (same zone) | Kubernetes 1.31+ (beta, on by default in 1.32+) | +| `PreferSameZone` | Same-zone preference; explicit alias of `PreferClose` | Kubernetes 1.33+ | +| `PreferSameNode` | Prefer endpoints on the same node | Kubernetes 1.33+ | + +Preference only: when no near endpoint is ready, traffic falls back to the rest, +so this is a cross-zone egress optimization, not a locality guarantee. An +unsupported value is rejected by the API server at apply time — set only what +your cluster version supports. + ## Upgrades Schema migrations are embedded in the relay binary via `sqlx::migrate!` and run at startup, gated by `BUZZ_AUTO_MIGRATE` (default `true`). Multiple replicas race-safely behind a Postgres advisory lock. `helm upgrade` is the entire upgrade procedure. diff --git a/deploy/charts/buzz/templates/pairing-relay.yaml b/deploy/charts/buzz/templates/pairing-relay.yaml index 86e362fe038..993550eac88 100644 --- a/deploy/charts/buzz/templates/pairing-relay.yaml +++ b/deploy/charts/buzz/templates/pairing-relay.yaml @@ -62,6 +62,9 @@ metadata: {{- end }} spec: type: {{ .Values.pairingRelay.service.type }} + {{- with .Values.pairingRelay.service.trafficDistribution }} + trafficDistribution: {{ . }} + {{- end }} selector: {{- include "buzz.pairingRelaySelectorLabels" . | nindent 4 }} ports: diff --git a/deploy/charts/buzz/templates/service.yaml b/deploy/charts/buzz/templates/service.yaml index 5e737543283..31ae730bf57 100644 --- a/deploy/charts/buzz/templates/service.yaml +++ b/deploy/charts/buzz/templates/service.yaml @@ -11,6 +11,9 @@ metadata: {{- end }} spec: type: {{ .Values.service.type }} + {{- with .Values.service.trafficDistribution }} + trafficDistribution: {{ . }} + {{- end }} selector: {{- include "buzz.relaySelectorLabels" . | nindent 4 }} ports: diff --git a/deploy/charts/buzz/tests/networking_test.yaml b/deploy/charts/buzz/tests/networking_test.yaml index 882679f2e6d..f8a187f0fc5 100644 --- a/deploy/charts/buzz/tests/networking_test.yaml +++ b/deploy/charts/buzz/tests/networking_test.yaml @@ -77,3 +77,31 @@ tests: path: kind value: HTTPRoute template: templates/httproute.yaml + + - it: Service omits trafficDistribution by default + set: + relayUrl: wss://buzz.example.com + ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000" + externalPostgresql.url: postgres://u:p@h:5432/d + s3.endpoint: http://minio:9000 + s3.accessKey: a + s3.secretKey: s + asserts: + - notExists: + path: spec.trafficDistribution + template: templates/service.yaml + + - it: Service sets trafficDistribution when configured + set: + relayUrl: wss://buzz.example.com + ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000" + externalPostgresql.url: postgres://u:p@h:5432/d + s3.endpoint: http://minio:9000 + s3.accessKey: a + s3.secretKey: s + service.trafficDistribution: PreferClose + asserts: + - equal: + path: spec.trafficDistribution + value: PreferClose + template: templates/service.yaml diff --git a/deploy/charts/buzz/tests/pairing_relay_test.yaml b/deploy/charts/buzz/tests/pairing_relay_test.yaml index 2ed2ef3b409..6ee77311fda 100644 --- a/deploy/charts/buzz/tests/pairing_relay_test.yaml +++ b/deploy/charts/buzz/tests/pairing_relay_test.yaml @@ -52,3 +52,22 @@ tests: name: BUZZ_PAIRING_RELAY_URL value: wss://pairing.buzz.xyz template: templates/deployment.yaml + + - it: pairing relay Service sets trafficDistribution when configured + set: + relayUrl: wss://buzz.example.com + ownerPubkey: "0000000000000000000000000000000000000000000000000000000000000000" + externalPostgresql.url: postgres://u:p@h:5432/d + externalRedis.url: redis://h:6379 + s3.endpoint: http://minio:9000 + s3.accessKey: a + s3.secretKey: s + pairingRelay.enabled: true + pairingRelay.url: wss://pairing.buzz.xyz + pairingRelay.service.trafficDistribution: PreferSameZone + asserts: + - equal: + path: spec.trafficDistribution + value: PreferSameZone + documentIndex: 1 + template: templates/pairing-relay.yaml diff --git a/deploy/charts/buzz/values.schema.json b/deploy/charts/buzz/values.schema.json index aaab848fd33..30184a8764f 100644 --- a/deploy/charts/buzz/values.schema.json +++ b/deploy/charts/buzz/values.schema.json @@ -112,7 +112,8 @@ "type": { "type": "string", "enum": ["ClusterIP", "NodePort", "LoadBalancer"] }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "healthPort": { "type": "integer", "minimum": 1, "maximum": 65535 }, - "metricsPort": { "type": "integer", "minimum": 1, "maximum": 65535 } + "metricsPort": { "type": "integer", "minimum": 1, "maximum": 65535 }, + "trafficDistribution": { "type": "string", "enum": ["", "PreferClose", "PreferSameZone", "PreferSameNode"], "description": "Service spec.trafficDistribution. Empty omits the field (cluster default)." } } }, "serviceAccount": { @@ -292,7 +293,8 @@ "properties": { "type": { "type": "string", "enum": ["ClusterIP", "NodePort", "LoadBalancer"] }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, - "annotations": { "type": "object" } + "annotations": { "type": "object" }, + "trafficDistribution": { "type": "string", "enum": ["", "PreferClose", "PreferSameZone", "PreferSameNode"], "description": "Service spec.trafficDistribution. Empty omits the field (cluster default)." } } }, "podAnnotations": { "type": "object" }, diff --git a/deploy/charts/buzz/values.yaml b/deploy/charts/buzz/values.yaml index 6c57a5c8ac9..04497505508 100644 --- a/deploy/charts/buzz/values.yaml +++ b/deploy/charts/buzz/values.yaml @@ -221,6 +221,8 @@ pairingRelay: type: ClusterIP port: 5000 annotations: {} + # Same values as service.trafficDistribution; empty → omitted + trafficDistribution: "" podAnnotations: {} podLabels: {} resources: @@ -238,6 +240,8 @@ service: healthPort: 8080 metricsPort: 9102 annotations: {} + # PreferClose | PreferSameZone | PreferSameNode; empty → omitted (cluster default) + trafficDistribution: "" serviceAccount: create: true