Documentation
¶
Overview ¶
Package vip implements the cluster VIP allocator.
Every Service in Rune gets a stable virtual IP for its lifetime. The allocator owns the cluster's CIDR, allocates IPs out of a free list, and returns IPs to the free list after a 60-second cooldown to drain stale clients.
The allocator is the single writer of the ClusterNetwork resource. All state changes flow through orderedlog.Propose, so a Raft-backed control plane will see the same state changes in the same order without code changes here. The allocator never touches Badger directly; the orderedlog seam lint enforces this.
Index ¶
Constants ¶
const ( OpTypeBootstrapClusterNetwork = "vip.bootstrap" OpTypeAllocateVIP = "vip.allocate" OpTypeReleaseVIP = "vip.release" )
Op type constants. Wire-stable: changing the string breaks replay of old persisted events.
Variables ¶
var ( // ErrCIDRExhausted is returned by Allocate when no IPs are free. ErrCIDRExhausted = errors.New("vip: cluster CIDR exhausted; expand --cluster-cidr or release unused services") // ErrAlreadyBootstrapped is returned by Bootstrap if the cluster // network already exists with a different CIDR. ErrAlreadyBootstrapped = errors.New("vip: cluster network already bootstrapped with a different CIDR; reset cluster to change") // ErrInvalidCIDR is returned for unparseable, non-IPv4, or // public-range CIDRs. ErrInvalidCIDR = errors.New("vip: invalid CIDR (must be a private IPv4 range)") // ErrCIDRCollision is returned by Bootstrap when the configured // CIDR overlaps an existing host route. ErrCIDRCollision = errors.New("vip: cluster CIDR overlaps an existing host route") // ErrServiceNotAllocated is returned by Release for a serviceID // with no current allocation. ErrServiceNotAllocated = errors.New("vip: service has no VIP allocation") )
Sentinel errors.
var ReleaseCooldown = 60 * time.Second
ReleaseCooldown is how long an IP waits in the pending-release queue before returning to the free list. Exposed for tests.
Functions ¶
This section is empty.
Types ¶
type Allocator ¶
type Allocator struct {
// contains filtered or unexported fields
}
Allocator owns the ClusterNetwork resource and the in-memory pending-release queue. Safe for concurrent use.
func New ¶
func New(olog orderedlog.OrderedLog, opts Options) (*Allocator, error)
New constructs an Allocator backed by the given OrderedLog. It registers the allocator's Op types so subsequent Propose / Watch replay works. Call Bootstrap() exactly once at startup.
func (*Allocator) Allocate ¶
Allocate returns the (possibly already-allocated) VIP for serviceID. Calls are idempotent: a second Allocate for the same serviceID returns the existing IP without touching the free list.
func (*Allocator) Bootstrap ¶
Bootstrap ensures the cluster network exists. If it does not, the allocator validates the configured CIDR (private range + no host route collision unless SkipRouteCheck) and Proposes a BootstrapClusterNetwork op. Idempotent: re-running with the same CIDR is a no-op; running with a different CIDR returns ErrAlreadyBootstrapped.
Bootstrap also starts the background release-cooldown worker.
func (*Allocator) Close ¶
Close stops the background worker. The OrderedLog is owned by the caller and is NOT closed here.
func (*Allocator) Release ¶
Release schedules the VIP for serviceID to return to the free list after the ReleaseCooldown elapses. Returns immediately; ErrServiceNotAllocated if the service has no allocation.
The actual free-list update is performed by the background worker which Proposes a ReleaseVIP op once the cooldown window passes. This keeps Release synchronous-feeling for callers without blocking shutdown.
type Options ¶
type Options struct {
// CIDR is the desired service CIDR at bootstrap. Ignored once the
// cluster is bootstrapped (the persisted CIDR wins).
CIDR string
// SkipRouteCheck disables the netlink CIDR-collision check at
// Bootstrap. Used in tests and on platforms without netlink.
SkipRouteCheck bool
Logger log.Logger
}
Options configure an Allocator.