Skip to content

feat(worker): reconcile direct local routing EndpointSlices - #798

Merged
thxCode merged 5 commits into
mainfrom
local-worker-endpointslices
Oct 26, 2026
Merged

thxCode merged 5 commits into
mainfrom
local-worker-endpointslices

Conversation

@thxCode

@thxCode thxCode commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

What type of PR is this?

/kind enhancement
/area worker
/area documentation

What this PR does / why we need it:

Reconciles directly managed discovery.k8s.io/v1 EndpointSlice resources alongside the legacy Endpoints object when the worker runs outside a nearby cluster, aligns workflow Helm pins to v3.21.4, and renames the local cluster setup guide:

  • Direct EndpointSlice routing and legacy compatibility (pkg/systemkuberess/{endpoint_slice.go,service.go}, deploy/gpustack-operator/chart/templates/worker/serviceaccount.yaml, docs/contribute/internals.md):
    • Reconciles a selectorless ClusterIP routing Service without recreating it on restart when Spec.ClusterIP has already been assigned by the API server in the matching IP family.
    • Labels the retained legacy Endpoints object with endpointslice.kubernetes.io/skip-mirror: "true" and directly reconciles <service>-direct EndpointSlice with endpointslice.kubernetes.io/managed-by: gpustack-operator-worker, kubernetes.io/service-name: <service>, matching address family (IPv4 / IPv6), a ready: true, serving: true endpoint at the reachable worker IP, port https, and a controller OwnerReference pointing to the routing Service.
    • Retires obsolete controller-mirrored slices only when their managed-by label is endpointslice-controller.k8s.io and their controller OwnerReference matches the legacy Endpoints UID, preserving unrelated slices.
    • Extends SelfSubjectAccessReview checks (services, services/finalizers, endpoints, endpointslices) and worker RBAC (discovery.k8s.io endpointslices get/list/create/update/delete), and documents the three startup routing environment variables (KUBERNETES_POD_NAMESPACE, KUBERNETES_SERVICE_NAME, KUBERNETES_POD_IP) in docs/contribute/internals.md.
  • CI Helm version alignment (.github/workflows/chart.yml, .github/workflows/site.yml):
    • Updates azure/setup-helm@v4 from v3.21.0 to v3.21.4 to match the repository's Helm toolchain pin.
  • Local cluster setup documentation (docs/contribute/local-cluster-setup.md, docs/README.md, docs/contribute/development.md, site/data/navigation.yaml):
    • Renames docs/contribute/kind.md to docs/contribute/local-cluster-setup.md (# Local Cluster Setup).

Which issue(s) this PR links to:

Relates #794
Relates #795
Relates #797

Special notes for your reviewer:

  • Verified with CGO_ENABLED=1 go test -race -count=1 ./pkg/systemkuberess/..., make lint, make lint chart, make lint docs, and make test chart.

Does this PR introduce a user-facing change?

NONE

@gpustack-code-review

gpustack-code-review Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

🔍 OpenCodeReview found 2 issue(s) in this PR.

  • ✅ Successfully posted inline: 1 comment(s)
  • 📋 Routed to summary by policy: 1 comment(s)

maintainability · low

📄 pkg/systemkuberess/endpoint_slice.go (L360-L361)

⚠️ GitHub could not post this as an inline comment: Routed to summary (severity low · category maintainability)

The new label selector adds kubernetes.io/service-name as a third ownership criterion, but isObsoleteRoutingSlice only proves ownership via the managed-by label / owner reference. The doc comment and internals.md say cleanup must also remove "the slice an earlier version of this operator created under another name". Current versions of newRoutingEndpointSlice do set discovery.LabelServiceName, so this is fine for them — but if any earlier operator version created its direct slice without that label, those slices will now silently stop being cleaned up (they are skipped at List time and never reach the ownership check). Worth confirming that every released version set the label, or noting the assumption in the comment.

Reviewed 82f6566..b7d1b74 only; earlier commits in this PR were reviewed in a previous run.

Comment thread docs/contribute/kind.md Resolved
Comment thread docs/contribute/kind.md Resolved
Signed-off-by: thxCode <thxcode0824@gmail.com>
…uards

Signed-off-by: thxCode <thxcode0824@gmail.com>
The chart and site workflows installed helm v3.21.0. The tooling moves to
v3.21.4 in the same series, so the workflows move with it: a workflow that
renders or packages a chart with another helm than the repository develops
against can produce an artifact the local gates never saw.

The Go version needs no change: every workflow already reads the version
from a go.mod (the root one, source/go.mod in the site checkout and
gpustack.ai/gpustack/go.mod in the api checkout), so the 1.27.3 of the
root go.mod is what they resolve.

Signed-off-by: thxCode <thxcode0824@gmail.com>
Signed-off-by: thxCode <thxcode0824@gmail.com>
@thxCode

thxCode commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

Review feedback summary

Source Location Verdict Outcome
@thxCode (#discussion_r4374334330) docs/contribute/kind.md:12 Valid Fixed (08f1078c, 82f65666): Removed the ## The host worker section and added a concise table of the three startup routing environment variables (KUBERNETES_POD_NAMESPACE, KUBERNETES_SERVICE_NAME, KUBERNETES_POD_IP) under ### System routing resources in docs/contribute/internals.md.
@thxCode (#discussion_r4374339699) docs/contribute/kind.md:1 Valid Fixed (82f65666): Renamed docs/contribute/kind.md to docs/contribute/local-cluster-setup.md, changed the title to # Local Cluster Setup, and updated references in docs/README.md, docs/contribute/development.md, and site/data/navigation.yaml.
@gpustack-code-review (#issuecomment-6409086430) docs/contribute/kind.md:71-75 Valid Fixed (82f65666): Resolved by withdrawing the ## The host worker walkthrough section.
@gpustack-code-review (#issuecomment-6409086430) pkg/systemkuberess/service.go:144-153 Valid Fixed (c59136d7): installRoutingService now compares the IP family of an existing actual.Spec.ClusterIP against the routing EndpointSlice address type (addressType), recreating the routing Service if the primary address family changes (covered in Test_installFakeSystemRoutingServiceKeepsTheRoutingServiceOfTheCluster).

@thxCode
thxCode force-pushed the local-worker-endpointslices branch from acb2c4d to 82f6566 Compare October 26, 2026 06:12
Comment thread pkg/systemkuberess/endpoint_slice.go Resolved
Comment thread pkg/systemkuberess/service.go Resolved
Comment thread pkg/systemkuberess/service.go Resolved
…leanup

Signed-off-by: thxCode <thxcode0824@gmail.com>
@thxCode

thxCode commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

Review feedback summary (ocr-review-run:40278487373-1)

Source Location Verdict Outcome
@gpustack-code-review (#discussion_r4374446221) pkg/systemkuberess/service.go:160 Valid Fixed (b7d1b748): newRoutingService now sets Spec.IPFamilies to [IPv4] or [IPv6] matching addressType (via routingIPFamily), and svcCompareFn checks Spec.IPFamilies as well as ClusterIP family so the recreated Service receives a ClusterIP of the matching family and converges (Test_installFakeSystemRoutingServiceKeepsTheRoutingServiceOfTheCluster).
@gpustack-code-review (#discussion_r4374446230) pkg/systemkuberess/service.go:163 Valid Fixed (b7d1b748): newRoutingService sets Protocol: core.ProtocolTCP on the https port and svcCompareFn checks ap.Name == expectedPort.Name, ap.Port == expectedPort.Port, and protocol compatibility (Test_installFakeSystemRoutingServiceKeepsTheRoutingServiceOfTheCluster/recreates_the_routing_service_when_the_port_name_differs).
@gpustack-code-review (#discussion_r4374446201) pkg/systemkuberess/endpoint_slice.go:363 Valid Fixed (b7d1b748): cleanupObsoleteRoutingSlices now scopes sliceCli.List with meta.ListOptions{LabelSelector: discovery.LabelServiceName + "=" + svc.GetName()}.
@gpustack-code-review (#issuecomment-6409086430) docs/contribute/internals.md:130-131 Valid Fixed (b7d1b748): Updated wording to state that the routing Service is recreated whenever its spec changes and the legacy Endpoints are recreated whenever they are deleted.
@gpustack-code-review (#issuecomment-6409086430) pkg/systemkuberess/service.go:47, pkg/systemkuberess/endpoint_slice.go:410-412 Valid (reminder) Covered (08f1078c, c59136d7, b7d1b748): pkg/systemkuberess/service_test.go ships unit tests covering all routing Service, Endpoints, and EndpointSlice reconcile, ownership, replacement, and cleanup paths.
@gpustack-code-review (#issuecomment-6409086430) pkg/systemkuberess/endpoint_slice.go:144-148 Not applicable Declined: An address-family change only happens when the worker restarts on a new primary host IP family, at which point the previous IP family address is no longer reachable and installRoutingService has already recreated the Service for the new family. Keeping the deterministic <svc>-direct slice name avoids leaving stale unreachable endpoints.
@gpustack-code-review (#issuecomment-6409086430) .github/workflows/site.yml:102-104 Out of scope Declined: All GitHub Actions across .github/workflows/*.yml in this repository follow major-version tag pinning (@v4), and line 102 (uses: azure/setup-helm@v4) was not modified in this PR.

Comment thread pkg/systemkuberess/service.go Resolved
@thxCode

thxCode commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

Review feedback summary (ocr-review-run:40280258429-1)

Source Location Verdict Outcome
@gpustack-code-review (#discussion_r4374538579) pkg/systemkuberess/service.go:197 Valid (reminder) Covered (b7d1b748): Regression tests in pkg/systemkuberess/service_test.go (Test_installFakeSystemRoutingServiceKeepsTheRoutingServiceOfTheCluster and Test_installFakeSystemRoutingService) cover Spec.IPFamilies, port-name comparison, and label-scoped EndpointSlice cleanup.
@gpustack-code-review (#issuecomment-6409086430) pkg/systemkuberess/endpoint_slice.go:360-361 Confirmed No change needed: Prior to this PR, pkg/systemkuberess only created Service and Endpoints (never a direct EndpointSlice), and both endpointslice-mirroring-controller and newRoutingEndpointSlice always set kubernetes.io/service-name: <svcName> (discovery.LabelServiceName), as Required by the Kubernetes EndpointSlice contract for service association.

@thxCode
thxCode merged commit ddd2578 into main Oct 26, 2026
9 checks passed
@thxCode
thxCode deleted the local-worker-endpointslices branch October 26, 2026 06:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant