Documentation
¶
Overview ¶
Package link implements the in-cluster gateway-link daemon: it brings up wg0 to the gateway VM and DNATs public ports to Service ClusterIPs, reloading from a watched ConfigMap. Leader election over a Lease lets only the holder program the data plane.
Index ¶
- func Apply(ctx context.Context, run runner, rc RuntimeConfig, privKey, peerPubKey string, ...) error
- func Reconcile(ctx context.Context, run runner, rc RuntimeConfig, privKey, peerPubKey string, ...) error
- func RenderNftables(forwards []ResolvedForward) (string, error)
- func RenderWGConf(rc RuntimeConfig, privKey, peerPubKey string) (string, error)
- func Run(ctx context.Context, cfg Config, log *zap.SugaredLogger) error
- func Teardown(ctx context.Context, run runner) error
- type Config
- type Forward
- type Peer
- type ResolvedForward
- type RuntimeConfig
- type WireGuard
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
func Apply(ctx context.Context, run runner, rc RuntimeConfig, privKey, peerPubKey string, resolve func(ctx context.Context, host string) (string, error)) error
Apply builds wg0 from scratch and programs nftables from rc, deleting any stale wg0 first for idempotency. It mutates host network state, must not run concurrently, and assumes kube-proxy DNAT; Cilium kube-proxy-replacement is unsupported.
func Reconcile ¶
func Reconcile(ctx context.Context, run runner, rc RuntimeConfig, privKey, peerPubKey string, resolve func(ctx context.Context, host string) (string, error)) error
Reconcile applies rc onto an already-up wg0 without tearing it down, so an established handshake and in-flight connections survive a config change.
func RenderNftables ¶
func RenderNftables(forwards []ResolvedForward) (string, error)
RenderNftables renders the inet "gateway" table that DNATs public wg0 ports to ClusterIPs and masquerades the traffic. The forward chain defaults to drop; output is deterministic, sorted by public port then protocol.
func RenderWGConf ¶
func RenderWGConf(rc RuntimeConfig, privKey, peerPubKey string) (string, error)
RenderWGConf renders a wg(8) setconf config for wg0; Address and MTU are omitted because ip(8) applies those. PersistentKeepalive is always emitted, including 0, so wg syncconf clears it when the config drops it.
Types ¶
type Config ¶
type Config struct {
// ConfigPath is the on-disk path to the JSON RuntimeConfig. Its parent dir is
// watched so in-place updates are picked up without a restart.
ConfigPath string `envconfig:"GATEWAY_CONFIG_PATH" default:"/etc/gateway/config/config.json"`
// WGKeyPath is the WireGuard private key path, kept out of the RuntimeConfig so
// the key Secret and the config ConfigMap rotate independently.
WGKeyPath string `envconfig:"GATEWAY_WG_KEY_PATH" default:"/etc/gateway/wg/private"`
// PeerPubKeyPath is the path to the gateway's WireGuard public key.
PeerPubKeyPath string `envconfig:"GATEWAY_WG_PEER_PUBKEY_PATH" default:"/etc/gateway/wg/peerPublicKey"`
// HealthAddr is the listen address for the readiness HTTP server.
HealthAddr string `envconfig:"GATEWAY_HEALTH_ADDR" default:":8080"`
// ReconcileInterval backstops the fsnotify-driven reload loop in case a
// filesystem event is missed.
ReconcileInterval time.Duration `envconfig:"GATEWAY_RECONCILE_INTERVAL" default:"10s"`
// PodNamespace is the namespace the leader-election Lease lives in. Required
// because the Lease lock is namespaced and the in-cluster client has no
// implicit namespace.
PodNamespace string `envconfig:"POD_NAMESPACE" required:"true"`
// PodName is this replica's leader-election identity, recorded as the Lease
// holder. Required and unique per pod.
PodName string `envconfig:"POD_NAME" required:"true"`
// LeaseName is the coordination.k8s.io Lease the replicas contend for. Shared
// across a gateway's replicas so exactly one holds it at a time.
LeaseName string `envconfig:"GATEWAY_LEASE_NAME" required:"true"`
}
Config is the process-level configuration for gateway-link, populated from the environment via config.Load.
type Forward ¶
type Forward struct {
Name string `json:"name"`
PublicPort int `json:"publicPort"`
// Protocol is tcp or udp; it is lowercased during validation.
Protocol string `json:"protocol"`
Service string `json:"service"`
TargetPort int `json:"targetPort"`
}
Forward maps a public port arriving on wg0 to an in-cluster Service, resolved to a ClusterIP at apply time.
type Peer ¶
type Peer struct {
// Endpoint is the gateway's public host:port. Optional on disk because the
// operator's observation of the gateway address may trail the link's start, in
// which case the reload loop waits for it.
Endpoint string `json:"endpoint"`
// AllowedIPs is the set of source ranges accepted from and routed to the peer,
// typically the wg0 subnet.
AllowedIPs []string `json:"allowedIPs"`
// PersistentKeepalive in seconds keeps the NAT pinhole open; 0 disables it.
PersistentKeepalive int `json:"persistentKeepalive"`
}
Peer is the gateway endpoint the link connects to. The peer's public key is read from Config.PeerPubKeyPath at apply time, not carried here.
type ResolvedForward ¶
type ResolvedForward struct {
Name string
PublicPort int
Protocol string
ClusterIP string
TargetPort int
}
ResolvedForward is a Forward with its Service resolved to a concrete ClusterIP, ready to be rendered into nftables DNAT rules.
type RuntimeConfig ¶
type RuntimeConfig struct {
WireGuard WireGuard `json:"wireguard"`
Forwards []Forward `json:"forwards"`
}
RuntimeConfig is the on-disk JSON config describing the WireGuard tunnel and the port forwards the link programs into nftables. The WireGuard private key is deliberately absent; it is read separately from Config.WGKeyPath.
func LoadRuntimeConfig ¶
func LoadRuntimeConfig(path string) (RuntimeConfig, error)
LoadRuntimeConfig reads and validates the JSON RuntimeConfig at path. Unknown fields are tolerated so older daemons can run against newer config schemas.
type WireGuard ¶
type WireGuard struct {
// Address is the wg0 address in CIDR form (e.g. 10.99.0.2/32).
Address string `json:"address"`
// ListenPort is the optional local UDP listen port; 0 picks an ephemeral port.
ListenPort int `json:"listenPort"`
// MTU is the optional wg0 MTU; 0 leaves the kernel default.
MTU int `json:"mtu"`
Peer Peer `json:"peer"`
}
WireGuard describes the local wg0 interface and the single gateway peer the link dials out to.