Documentation
¶
Index ¶
- Constants
- func CleanStaleBridge(log *slog.Logger)
- type Config
- type Manager
- func (m *Manager) Cleanup()
- func (m *Manager) CloseHostPort(port int, containerIP string)
- func (m *Manager) GatewayIP() string
- func (m *Manager) InstallFirewallRules() error
- func (m *Manager) OpenHostPort(port int, containerIP string) error
- func (m *Manager) Setup(ctx context.Context, id string, netns string) (*SetupResult, error)
- func (m *Manager) Teardown(ctx context.Context, id string, netns string) error
- type SetupResult
Constants ¶
const DefaultSubnet = "10.88.0.0/16"
DefaultSubnet is the preferred IP range for containers.
Variables ¶
This section is empty.
Functions ¶
func CleanStaleBridge ¶
CleanStaleBridge deletes the ephemerd0 bridge if it exists. Used on startup in the WSL containerd-only worker to remove bridges left over from a previous boot (all WSL2 distros share one kernel so bridges persist across instances).
Types ¶
type Config ¶
type Config struct {
DataDir string
Subnet string // container subnet (auto-selected if empty)
MTU int // bridge MTU (auto-detected from host if 0)
CNIBinDir string // path to CNI plugin binaries (Linux only, ignored elsewhere)
GatewayPorts []int // extra TCP ports to allow from containers to the gateway (e.g., module proxy)
// ControlPorts are TCP ports the ephemerd control plane binds on the
// gateway (bridge) address that MUST NOT be reachable from inside
// containers: the in-VM containerd (default 10000), the unauthenticated
// dispatch gRPC server (containerd+1), and the debug exec server
// (containerd+2). The firewall adds targeted INPUT DROP rules from the
// container subnet to the gateway on these ports. Empty = no INPUT
// control-plane rules (e.g. a bare-metal Linux host with no in-VM
// dispatch server listening on the bridge).
ControlPorts []int
// The fields below configure the Windows L2Bridge egress path (see
// network_windows.go and l2bridge.go). They are ignored on Linux/macOS.
// When L2BridgeEgress is false (the default), Windows uses the HNS NAT
// network and none of them are consulted.
//
// L2BridgeEgress is the opt-in. HostNIC (the host adapter to bridge onto)
// and IPPool (the reserved LAN range container addresses come from) are
// REQUIRED when it is set; Subnet and Gateway are derived from HostNIC when
// empty. PublicDNS defaults to public resolvers so container DNS never needs
// the blocked LAN router. ExtraAllowedCIDRs carves destinations out above
// the RFC1918 block.
L2BridgeEgress bool
HostNIC string
IPPool string
Gateway string
PublicDNS []string
ExtraAllowedCIDRs []string
// AllowHostAccess permits job containers to address the ephemerd host
// itself on the L2Bridge path. Required by anything ephemerd serves TO
// containers over the network — the per-job dind Docker API and the Go
// module proxy both listen on the host address — because the egress ACLs
// otherwise block the host along with the rest of RFC1918.
//
// It is an address-scoped /32 allow, so it opens every port the host has
// listening, not just ephemerd's. The control-plane ports are blocked back
// off at the host firewall (see l2BridgeControlPlaneRules), which CAN match
// on the container source here because L2Bridge does not NAT. Left false
// when nothing needs to be reachable, which is the strictest posture.
AllowHostAccess bool
Log *slog.Logger
}
Config for container networking.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager handles platform-specific container networking. On Linux, this uses CNI with a bridge and iptables firewall. On Windows, this uses HCN with a NAT network and ACL policies.
func (*Manager) Cleanup ¶
func (m *Manager) Cleanup()
Cleanup removes all networking state: firewall rules, bridge interface, CNI config, IP allocations, and DNS files. Called on shutdown.
func (*Manager) CloseHostPort ¶ added in v0.2.0
CloseHostPort removes an allow previously added by OpenHostPort. containerIP must match the one it was opened with.
func (*Manager) GatewayIP ¶
GatewayIP returns the host address that services ephemerd runs for jobs must bind to in order to be reachable from inside containers — the Go module proxy and, on Windows, the per-job dind Docker API listener.
Normally that is the bridge gateway (e.g. "10.88.0.1"), the first usable address of the container subnet. On the Windows L2Bridge path there is no such bridge gateway: containers are peers on the host's LAN, so the platform reports the host's own adapter address instead. Binding to the old hard-coded 10.88.0.1 there would fail outright — no interface holds that address once the NAT network is out of the picture — and take dind provisioning down with it.
func (*Manager) InstallFirewallRules ¶
InstallFirewallRules blocks container traffic to private network ranges.
func (*Manager) OpenHostPort ¶ added in v0.2.0
OpenHostPort opens a scoped host-firewall inbound allow for one TCP port from the single container at containerIP to the host, so a per-job service ephemerd binds on the host (dind's Docker API) is reachable from THAT job's container and no other. Only the Windows L2Bridge path does anything; elsewhere it is a no-op. Pair with CloseHostPort on teardown, passing the same containerIP.
Returns an error rather than opening anything when containerIP is empty or unparseable — see the platformNetworking doc for why widening is not a permissible fallback.
type SetupResult ¶
type SetupResult struct {
// NetNS is the network namespace identifier (Linux: path, Windows: namespace ID).
NetNS string
// EndpointID is the HCN endpoint ID (Windows only). Used to attach
// the network to the container via the OCI spec.
EndpointID string
// IP is the container's IP address on the bridge network.
// Populated on Linux from the CNI result; empty on other platforms.
IP string
}
SetupResult contains the network configuration applied to a container.