Skip to content

Network Load Balancer #698

Open
26 of 38 issues completed
Open

Description

@privateip

Summary

Engineering plan for the per-region Layer 4 network load balancer proposed in datum-cloud/enhancements#884. A tenant exposes a set of VPC backends in one region behind a public address: IPv6 by default, with optional reserved static IPv4. TCP and UDP connections are spread across healthy backends without a proxy, keep the client's source address, stay on one backend for the life of the connection, and survive the loss of any single gateway node.

Most of the datapath already exists. galactic-gateway runs a stateless Maglev consistent-hash, Direct Server Return (DSR) XDP datapath, driven by NetworkGateway and NetworkRule. Infra already deploys it onto production edge nodes. This plan covers what stands between that datapath and a load balancer tenants can use: hardening, tenant safety, the missing features, and the public surface.

Architecture reference: docs/agents/ARCHITECTURE-GATEWAY.md.

Scope against enhancements#884

#884 has two phases of its own. Every phase in this plan (0 to 3 below) delivers #884 Phase 1: regional unicast. #884 Phase 2 (one global anycast VIP) is out of scope here, but nothing in this plan may preclude it (see Non-goals).

A load balancer belongs to one region. Its VIPs are announced to the internet only from that region, and every backend must be in that region. Inside the region, every gateway node advertises every VIP at equal preference and ECMP spreads clients across them. That is safe because Maglev is deterministic. It is still regional unicast in #884's terms: one region announces the address, not the global anycast of #884 Phase 2.

Requirements from enhancements#884 and how they map to the design

#884 requirement Status today Work
Per-region scope: traffic goes only to gVPC targets in the load balancer's region Partial. A NetworkRule lives in one cluster, but nothing rejects a backend in another region, and nothing stops the VIP being announced outside its region. #736, #702, #706
Every load balancer gets a public IPv6 address or subnet by default Missing. The tenant supplies the VIP. Nothing allocates one. #735, #702
One or more reserved static public IPv4 addresses, on request Missing. NetworkRule accepts IPv4 VIPs, but the datapath parses IPv6 only, so an IPv4 VIP is advertised and then never claimed. Nothing reserves IPv4. #735, #705
TCP and UDP Built.
Protocol support can grow (ESP, GRE, ICMP, SCTP) without breaking the configuration API Missing. NetworkRule's protocol enum is tcp/udp and its port is required, so a protocol without ports can't be expressed. #734
No L7 proxy. Client source address is preserved on the backend Built for IPv6. DSR over SRv6: the client's packet reaches the backend unmodified, and ServiceVIPBinding makes the backend answer on the VIP. Replies that cross an edge node are forwarded there. IPv4 clients aren't served at all yet. #705
Stateless consistent hash, Maglev-style Built. Every gateway node computes the same Maglev table from the same (VIP, backends) input, so a flow resolves to the same backend on any node. No flow table.
Default hash on the 5-tuple Built. The table is chosen by protocol, VIP and port, and the slot by the client's address and port.
Session affinity: None, ClientIP, ClientIPAndProtocol Missing. Only the 5-tuple hash exists. #733
Traffic goes only to active, healthy endpoints Missing. The backend list is static. A dead backend keeps its share of the Maglev table until someone edits the rule. #704

Non-goals

Carried over from #884:

Added for this plan:

Phases

Phase 0: Harden the existing datapath

Make what's deployed trustworthy before more load goes on it.

Sharing edge nodes with galactic-nat and galactic-vrf

Exit: the lab runs the gateway and the egress shards on the same edge nodes, task verify proves VIP traffic end to end within one site, and a gateway restart leaves egress running.

Phase 1: Tenant safety and regional scope

Nothing tenant-facing ships until one tenant can't steer another tenant's traffic, and a load balancer can't reach outside its region.

Exit: admission refuses a NetworkRule that names another tenant's VPC, a VIP not allocated to the tenant, or a backend outside the region. A VIP can't be reached from the internet through another region.

Phase 2: Feature completeness

Exit: a backend that dies stops receiving new flows without operator action, IPv4 VIPs serve IPv4 clients with their source address preserved, session affinity is configurable, and the API can take new protocols without a breaking change.

Phase 3: Product surface

Exit: a tenant can create a load balancer in a region through the API, CLI or portal, get an IPv6 address automatically, bind a reserved IPv4 address, see that it's healthy, and reach it from the internet over both.

Sequencing

Phase 0 and Phase 1 can run in parallel. Phase 2's health design can start alongside them. #696 can be designed now, but its protocol and affinity fields depend on #733 and #734, and it must not reach tenants before Phase 1 is done. #735 needs #696 for its tenant-facing resources. #694 and #695 follow #696.

Risks

Related

Activity

  1. self-assigned this
    on Oct 4, 2026
  2. 18 remaining items

  3. drewr commented on Oct 17, 2026

    @drewr

    A use case for UDP through the load balancer, with evidence from testing Datum Connect's peer-to-peer shares (iroh over QUIC) on a Compute instance on 2026-10-17.

    The instance is a unikernel in us-central-1 on the IPv6-only default network. Its interface address is fd20:0:1::5:0:0, and it sends from 2607:ed40:10c::1:0:1. Unsolicited inbound UDP doesn't reach it, but iroh's hole punching still opened a direct path to a phone on T-Mobile:

    14:23:06Z path 23ce68a090d0: Relayed, 348 ms via https://use1-1.relay.n0.iroh.link./
    14:30:53Z path 23ce68a090d0: Direct, 67 ms via [2607:fb91:14e3:c9eb:ad2:e58:51d7:afde]:52417
    19:04:13Z path 23ce68a090d0: Relayed, 58 ms via https://use1-1.relay.n0.iroh.link./
    

    For the punch to land, the phone had to reach the instance at the source port the relay saw. That means the egress translation kept one public port for the instance's socket across destinations, at least during that session.

    Direct paths are intermittent without an inbound rule. The first session took about 8 minutes to punch through, a later session from the same phone stayed relayed for at least 10 minutes, and a client on a hosting provider's network stayed relayed throughout. Relayed traffic added 50 to 470 ms here and depends on a third-party relay.

    A regional VIP with a UDP rule to the instance would make the direct path dependable. The Connect side is ready: a share can bind a fixed UDP port and advertise extra public addresses in its ticket, so a VIP from #735 and one UDP rule would cover it.

    Two things this use case relies on, both already in the plan. The backend must see the client's real source address, which DSR preserves. Replies must leave from the VIP, which ServiceVIPBinding handles, because iroh validates a path by the address that answers.

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

Metadata

Metadata

Assignees

Labels

Fields

Priority

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions