Skip to content

feat(api): set trafficDistribution on the client Service - #376

Merged
Andrei Kvapil (kvaps) merged 4 commits into
mainfrom
feat/client-service-traffic-distribution
Oct 17, 2026
Merged

Andrei Kvapil (kvaps) merged 4 commits into
mainfrom
feat/client-service-traffic-distribution

Conversation

@kvaps

@kvaps Andrei Kvapil (kvaps) commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

What

Adds an optional spec.clientService.trafficDistribution to EtcdCluster. When set, the operator writes it to spec.trafficDistribution of the <cluster>-client Service on create and reconciles drift back to it. Allowed values mirror the core Service API: PreferClose, PreferSameZone, PreferSameNode, validated by an enum on the CRD.

Why

Clusters stretched across zones (e.g. two sites plus a witness) want clients to prefer an etcd member in their own zone. The client Service has a selector, so with trafficDistribution: PreferClose the EndpointSlice controller writes zone hints and proxies that honour them (kube-proxy, Cilium) keep traffic zone-local. Today this can only be done by patching the Service by hand, which survives reconcile but is lost when the Service is recreated.

Behaviour

  • Unset (no clientService, or no trafficDistribution in it) means no change from today: the operator does not touch the field, so a value set on the Service by hand is preserved.
  • Only the client Service is affected; the headless Service never gets a traffic distribution.
  • The setting is not latched through status.observed — the Service carries no consensus state, so a change applies on the next reconcile.
  • clientService is a struct so further client-Service settings can land next to it.

Compatibility

PreferClose needs Kubernetes 1.31+ (GA in 1.33); PreferSameZone / PreferSameNode need 1.34+. Documented on the field and in docs/concepts.md.

Testing

  • Controller tests: create, drift reconciled back to the spec, unset field leaves a hand-set value alone, headless Service untouched.
  • envtest: CRD enum accepts the three values and rejects others; the envtest apiserver persists trafficDistribution on a Service.
  • make test passes; make generate manifests produces no drift.

Summary by CodeRabbit

  • New Features
    • Added optional traffic distribution settings for the client Service: PreferClose, PreferSameZone, and PreferSameNode.
    • Configured values are applied and reconciled on the next update. When unset, existing Service settings are preserved; the headless Service is unaffected.
  • Documentation
    • Added guidance on client Service configuration and its behavior.

Clusters stretched across zones want clients of the <cluster>-client
Service to prefer a member in their own zone. Add an optional
clientService block with a trafficDistribution field whose allowed
values mirror the core Service API. Unset leaves today's behaviour.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Set spec.trafficDistribution on <cluster>-client from
spec.clientService and reconcile drift back to it. The field is only
owned when the EtcdCluster sets it, so a value patched onto the Service
by hand survives when the spec leaves it unset. The headless Service is
never touched.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Controller tests for create, drift back to the spec, an unset field
leaving a hand-set value alone, and the headless Service never being
touched. envtest cases for the enum on spec.clientService and for the
apiserver persisting the field on a Service.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
Document the client Service, which fields the operator owns on it, and
the new trafficDistribution setting for zone-local clients in clusters
stretched across zones, including apiserver version requirements.

Assisted-by: LLM
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
@github-actions github-actions Bot added api-change controllers documentation Improvements or additions to documentation feature New feature or request labels Oct 14, 2026
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a1fa196a-2853-44f7-a94f-6724e2ea0806
📥 Commits

Reviewing files that changed from the base of the PR and between e6c1314 and 7da403d.

📒 Files selected for processing: 8
  • README.md
  • api/v1alpha2/client_service_envtest_test.go
  • api/v1alpha2/etcdcluster_types.go
  • api/v1alpha2/zz_generated.deepcopy.go
  • charts/etcd-operator/crd-bases/etcd-operator.cozystack.io_etcdclusters.yaml
  • controllers/client_service_test.go
  • controllers/etcdcluster_controller.go
  • docs/concepts.md

Included review availability: This review used your included allowance. Your plan provides up to 2 included reviews per hour; 1 remain after this review.

📝 Walkthrough

The API adds optional traffic distribution settings for the client Service. The controller applies configured values and reconciles drift. When the setting is absent, the controller preserves the Service’s existing value. The headless Service is not changed by this configuration.

Changes: Client Service traffic distribution

Layer / File(s) Summary
Client Service configuration contract
api/v1alpha2/etcdcluster_types.go, api/v1alpha2/zz_generated.deepcopy.go, charts/etcd-operator/crd-bases/etcd-operator.cozystack.io_etcdclusters.yaml, api/v1alpha2/client_service_envtest_test.go
Adds the optional clientService.trafficDistribution field with three allowed values, deep-copy support, the CRD schema, and API-server tests for accepted values and persistence.
Client Service reconciliation
controllers/etcdcluster_controller.go, controllers/client_service_test.go, docs/concepts.md, README.md
The controller applies configured values to the client Service and preserves existing values when configuration is absent. Tests cover creation, drift, and headless Service behavior. Documentation describes the option and its Kubernetes version requirements.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Merge Risk: ⚪ Minimal · up to 7da40

The client Service configuration appears ready to merge after normal checks; no actionable issue is established.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 5 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: adding support for setting trafficDistribution on the client Service.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 72.73% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 5 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sircthulhu Kirill Ilin (sircthulhu) left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, two minor comments inline.

Comment thread controllers/etcdcluster_controller.go
Comment thread controllers/etcdcluster_controller.go
@kvaps
Andrei Kvapil (kvaps) merged commit eccc4fb into main Oct 17, 2026
11 checks passed
@kvaps
Andrei Kvapil (kvaps) deleted the feat/client-service-traffic-distribution branch October 17, 2026 07:16
Timofei Larkin (lllamnyp) added a commit that referenced this pull request Oct 17, 2026
This reverts commit eccc4fb, removing
spec.clientService.trafficDistribution from the EtcdCluster API. The
capability returns in the next commit as an annotation on the
EtcdCluster, so the API does not change for now.

Assisted-By: LLM
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
Timofei Larkin (lllamnyp) added a commit that referenced this pull request Oct 17, 2026
…otation

The etcd-operator.cozystack.io/client-service-traffic-distribution
annotation on an EtcdCluster sets spec.trafficDistribution on the
<cluster>-client Service (PreferClose, PreferSameZone or PreferSameNode),
so clients of a cluster stretched across zones prefer a nearby member.
It stands in for a typed spec field without changing the API for now.

The field is written with server-side apply under its own field manager,
so removing the annotation clears it unless another manager also set it,
and a value someone else set without the annotation is left alone. A
value outside that set, one the apiserver rejects (PreferSameZone and
PreferSameNode before 1.34) or one it drops (no support before 1.31) is
reported as a Warning Event and leaves the field unset; the rest of the
reconcile carries on. The headless Service is not touched.

Builds on the controller tests and docs of #376 by Andrei Kvapil.

Assisted-By: LLM
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-change controllers documentation Improvements or additions to documentation feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants