Skip to content

Two backends of one VIP on the same node cannot both serve #787

Closed

Description

@privateip

Summary

A load balancer VIP can have only one working backend per node for a given port, because the node has no way to tell which of two local backends a flow was meant for.

The second backend's binding reports a conflict and receives nothing, but the gateway keeps sending it a share of new flows. Those flows land on the first backend, which then carries both shares while the second sits idle, and the load balancer's own status shows no problem.

This matters once a rule has more backends than there are nodes, or when backends are packed onto a few nodes.

Acceptance criteria

  • Two backends of one VIP on the same node each receive the flows the gateway assigns them
  • Or, if that is not supported, the gateway stops assigning flows to a backend that cannot be reached and the rule's status says so
  • Deleting either backend leaves the other serving its flows

Activity

  1. self-assigned this
    on Oct 7, 2026
  2. added
    needs triageIssues that need to be triaged before implementing
    and removed
    needs triageIssues that need to be triaged before implementing
    on Oct 7, 2026
  3. privateip commented on Oct 9, 2026

    @privateip
    CollaboratorAuthor

    Fixed by #809, which is merged to main but not yet released. v0.5.4 does not include it.

    05d21240 gives each backend a slot, a 16-bit hash of its address and port, and the gateway writes that slot into the uSID it encapsulates to. The node keys its ingress translation row on the slot, so two backends of one VIP on one node each get their own row and each bind with Bound=True. Deleting one removes only its own rows.

    7fb5bb88 covers the case where two backends on one node hash to the same slot. The gateway and the node drop the later backend in the same order, report it under BackendsUnresolved, and send it no flows.

    The tests TestServiceVIPBinding_SameVIPDistinctBackendsBothBind, TestNetworkRuleBindingReconciler_SameNodeBackendsGetOwnBindings, TestBuildDesiredRule_SameNodeBackendsGetTheirOwnSlot and TestDropConflictingBackends cover these cases and pass on main. The lab check in #809 also had both backends on one compute node answering.

    If you still see this on a release that includes #809, please reopen with details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

Priority

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions