Skip to content

feat(sandbox-manager): add network interface binding and reliable peer discovery - #920

Open
AiRanthem wants to merge 5 commits into
openkruise:masterfrom
AiRanthem:feature/network-interface-peer-discovery-260821
Open

feat(sandbox-manager): add network interface binding and reliable peer discovery#920
AiRanthem wants to merge 5 commits into
openkruise:masterfrom
AiRanthem:feature/network-interface-peer-discovery-260821

Conversation

@AiRanthem

Copy link
Copy Markdown
Member

Ⅰ. Describe what this PR does

This PR adds an optional --network-interface flag for Sandbox Manager and uses its validated IPv4 address consistently for the control API, peer route listener, memberlist bind/advertise address, and non-Sandbox proxy return path.

It also makes peer discovery resilient to startup ordering and temporary Kubernetes API failures:

  • validates the namespace, label selector, REST configuration, and selected network interface at startup;
  • lists selector-matching peer Pods with bounded retries until one memberlist join succeeds;
  • validates, deduplicates, and stably orders trusted seed addresses;
  • starts required listeners synchronously so bind failures reach the caller;
  • serializes Start/Stop and gives one lifecycle owner responsibility for Leave and Shutdown;
  • preserves upstream traffic-token and dedicated observability-listener behavior.

The design and lifecycle contract are documented in the accompanying English and Chinese proposals.

Ⅱ. Does this pull request fix one issue?

NONE

Ⅲ. Describe how to verify it

  • go test -mod=mod ./pkg/peers ./pkg/proxy ./pkg/sandbox-gateway/server ./pkg/sandbox-manager ./pkg/servers/e2b ./pkg/utils/network -count=1
  • go build -mod=mod ./cmd/sandbox-manager
  • git diff --check upstream/master...HEAD

Ⅳ. Special notes for reviews

  • An empty --network-interface preserves the existing non-hosted behavior.
  • A configured interface must be up and have exactly one global-unicast IPv4 address; startup fails instead of falling back.
  • The ext-proc listener, metrics, pprof, and other observability listeners remain outside the selected user-network address contract.
  • Peer discovery stops Kubernetes listing after the first successful join; memberlist handles ongoing membership afterward.
  • An in-flight memberlist Join is bounded by existing memberlist network deadlines because the upstream Join API has no context parameter.

…r discovery

- Introduce optional --network-interface flag to bind Sandbox Manager to one user network IPv4 address
- Validate interface existence, status, and single global unicast IPv4 address on startup; fail if invalid
- Use resolved address uniformly for control API, peer route service, memberlist binding/advertisement, and non-Sandbox proxy return
- Preserve existing non-hosted behavior when flag is empty, using POD_IP or first non-loopback address
- Reuse existing controller-runtime cache scoped by namespace and peer label selector for peer discovery; avoid separate client/cache
- Establish trusted seed addresses from cached Pods with filtering on memberlist-url annotation and duplicates
- Implement background, non-blocking lifecycle for peer discovery and joining with retries and network deadline aware shutdown
- Enforce one lifecycle owner for graceful Leave and Shutdown on stop requests; prevent concurrent cleanup races
- Ensure startup fails on invalid network scope/configuration before serving requests; seed discovery not a startup blocker
- Maintain compatibility by adding only CLI flag without CRD, HTTP model, or protocol changes and preserving existing user cluster config
- Document risks including resource use for Pod informer, delayed join cancellation, stale member presence on forced termination, and address change requiring restart

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
… discovery

- Add --network-interface flag to specify network interface for user-cluster traffic
- Resolve and validate the network interface IP address at startup
- Introduce --disable-envoy-ext-proc flag to disable Envoy ext-proc gRPC listener
- Pass resolved bind address and ext-proc disable flag to SandboxManagerOptions
- Update sandbox controller Run method to accept stop channel for graceful shutdown
- Refactor peer discovery to use a live, uncached Kubernetes client with namespace and label selector
- Implement bounded Pod listing with retries until joining memberlist succeeds
- Ensure peer discovery stops retrying after successful join to avoid cache overhead
- Add lifecycle management for peer discovery and memberlist join with once-only stop semantics
- Enhance memberlist peers start/stop logic with context handling and IP binding
- Add comprehensive unit tests covering start/stop, join lifecycle, peer leave, seed address trust,
  retry behavior, and namespace/label filtering in peer discovery
- Update proposal documents to reflect design and implementation details for peer discovery and
  network interface usage

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
- Add detailed join seed recording in fakeMemberlistHandle for better verification
- Refactor peerlist tests to assert joined seeds with namespace and label selector filtering
- Simplify and enhance synchronization in join retry and join order tests using atomic counters
- Add startBlockedJoin helper to test Join call blocking and graceful Stop handling
- Replace deprecated test patterns with improved concurrency control and clearer assertions

test(ext_proc): consolidate server run lifecycle tests

- Replace separate tests with table-driven TestServerRunLifecycle covering
  - synchronous bind failures for grpc listener
  - normal run and stop releasing both listeners
  - skipping grpc listener when ext-proc disabled
  - stopping before run prevents late start
- Verify listener release after stop in all scenarios

test(sandbox-manager): ensure cache start before peers and pass bind address

- Merge tests to check cache starts before peers and peers receive bind address and port
- Remove redundant assertions and simplify setup

test(servers/e2b): add newStartupController helper and improve startup signal handling tests

- Extract newStartupController to enable testing controller start behavior with custom run functions
- Adjust TestControllerSignalDuringStartupExitsCleanly to use new helper and verify expected zero exit semantics
- Update TestControllerRunPropagatesStartupFailure to use newStartupController and check synchronous startup error surfacing

test(utils/network): combine ResolveNetworkInterfaceAddress tests

- Unify empty and missing interface tests into a table-driven test for ResolveNetworkInterfaceAddress
- Confirm error messages and returned addresses for different interface names correctly

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
@kruise-bot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign furykerry for approval by writing /assign @furykerry in a comment. For more information see:The Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.10596% with 48 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.30%. Comparing base (a894e17) to head (6921fc6).
⚠️ Report is 7 commits behind head on master.

Files with missing lines Patch % Lines
pkg/peers/memberlist.go 88.54% 8 Missing and 7 partials ⚠️
pkg/sandbox-manager/core.go 60.00% 7 Missing and 3 partials ⚠️
pkg/proxy/server.go 72.72% 5 Missing and 4 partials ⚠️
pkg/utils/network/network.go 76.47% 8 Missing ⚠️
pkg/servers/e2b/core.go 92.00% 2 Missing and 2 partials ⚠️
pkg/sandbox-gateway/server/server.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #920      +/-   ##
==========================================
+ Coverage   83.08%   83.30%   +0.21%     
==========================================
  Files         257      259       +2     
  Lines       22536    22691     +155     
==========================================
+ Hits        18724    18902     +178     
+ Misses       3097     3056      -41     
- Partials      715      733      +18     
Flag Coverage Δ
unittests 83.30% <84.10%> (+0.21%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Use atomic bool flag to mark memberlist start completion
- Gate GetPeers, GetAllMembers, LocalAddr, LocalPort on started flag instead of list nil-check
- Add test to simulate concurrent getters racing with Start
- Publish list before the started flag is set, so getters never observe a nil list
- Prevent nil dereference and stale reads on memberlist data before start completion
- Keep a single English proposal (drop the CN copy, rename the EN file) and align the --network-interface flag description

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
…proposal

Address review findings on the network-interface peer discovery branch.

Proposal:
- Document the startup crash model: a termination signal during startup
  exits without graceful cleanup, while a signal observed together with a
  completed startup runs the graceful Stop path.
- Document Start exactly once and Stop at most once for the peer
  lifecycle instead of idempotent repeated Stop.
- Bring --disable-envoy-ext-proc into scope with its contract.
- Exclude terminal-phase Pods from the seed set; describe single-replica
  listing behavior, the Gateway PEER_NAMESPACE/PEER_LABEL_SELECTOR
  requirement, and where the peer client and interface resolution live.

Code:
- peers: drop the speculative Stop-before-Start guard and reject a second
  Start instead; share the lifecycle tail between Start and tests; wait a
  full retry interval after each attempt; log an empty seed set; always
  advertise the bound address; skip Succeeded/Failed Pods.
- proxy: drop the stopped flag and the redundant listener fields; the
  servers own their listeners.
- sandbox-manager: start the proxy before memberlist so the peer route
  listener serves before this replica is advertised; replace the elector
  runOnce with an atomic claim so Stop keeps honoring its context.
- e2b: prefer an already-available startup result when a signal arrives
  so a fully started controller shuts down gracefully.
- Makefile: run test packages serially while several test binaries bind
  the fixed route-refresh and ext-proc ports.

Tests: table-driven seed selection, shared lifecycle wiring, startup
ordering against an occupied port, awaitStartup both-ready rows, and the
controller startup tests moved to run_test.go.

Signed-off-by: AiRanthem <zhongtianyun.zty@alibaba-inc.com>
@AiRanthem
AiRanthem force-pushed the feature/network-interface-peer-discovery-260821 branch from 534bed2 to 6921fc6 Compare September 4, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants