runtime

package
v0.14.28-dev Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package runtime supervises a podman container that hosts this outpost's k3s-agent kubelet. The container's identity is THIS outpost's identity (NodeToken, AgentName, overlay credentials); from the cluster's POV there's one Node per outpost — the container is invisible.

Why a container (not a host subprocess): security isolation (kubelet + containerd run under cgroups managed by an outer runtime, not directly on the host); cross-platform Linux runtime (macOS hosts don't have a host kubelet but can run a privileged Linux container via Docker Desktop / Rancher Desktop / ycode-podman / Lima). One model, every OS.

Lifecycle: outpost daemon calls Up(ctx, opts). Up locates `podman` on PATH, pulls/builds the image if missing, starts a named container with the credentials threaded in via env, then streams its logs back to outpost's slog. Down(ctx, opts) stops + removes the container. Up is idempotent — repeated calls with the same AgentName reuse the existing container.

Index

Constants

View Source
const DefaultControlPlaneAPIPort = 16443

DefaultControlPlaneAPIPort is where a HOSTED apiserver listens. Deliberately not 6443: that belongs to the visitor for a cluster this host JOINS.

View Source
const DefaultImage = "outpost-runtime:dev"

DefaultImage is the runtime image tag the outpost daemon expects to find. Built by `outpost cluster build-runtime`; can be overridden via Options.Image.

View Source
const DefaultPeerAPIBridgePort = 16444

DefaultPeerAPIBridgePort is the host-loopback endpoint through which host-side virtual nodes reach the peer apiserver visitor inside the agent runtime container. It is distinct from both the visitor's in-container 6443 and the hosted control plane's host-side 16443.

View Source
const FallbackPodCIDR = "10.42.255.0/24"

FallbackPodCIDR mirrors the CNI_LOCAL_POD_CIDR default in image/entrypoint.sh — the fixed range the single-node fallback allocates from on EVERY node. Reported for operator legibility only; nothing here configures the container (the entrypoint owns that value, and an operator override rides in via ExtraEnv).

MUST equal the entrypoint's default, and TestFallbackPodCIDRMatchesEntrypoint pins the two together. They drifted once already: this constant said 10.43.42.0/24 (inside the k3s SERVICE CIDR — the silent node-local misroute the entrypoint comment records as fixed) long after the entrypoint had moved to 10.42.255.0/24, so every status view and log line reported a range no container ever allocated from.

View Source
const PodNetworkModeEnv = "OUTPOST_POD_NETWORK_MODE"

PodNetworkModeEnv is the env var runtime.Up stamps on the container so the entrypoint can branch on the classified mode instead of re-deriving it from "is OUTPOST_POD_CIDR set" — a test that no longer distinguishes peer-flannel from the single-node fallback.

View Source
const ServerNodeTokenPath = "/var/lib/rancher/k3s/server/node-token"

ServerNodeTokenPath is where k3s writes the node token inside the control-plane container.

Variables

View Source
var ErrPodmanNotFound = errors.New("runtime: no `podman` or `docker` binary on PATH (install Docker Desktop / Rancher Desktop / podman to enable the DKS agent runtime)")

ErrPodmanNotFound is returned by Up when neither `podman` nor `docker` is on PATH. The outpost daemon surfaces it as a clear "install Docker Desktop / Rancher Desktop / podman to enable the agent runtime" message; on macOS this is the expected gating.

Functions

func BuildImage added in v0.1.3

func BuildImage(ctx context.Context, opts BuildOptions) (string, error)

BuildImage materializes the embedded build context (Dockerfile + entrypoint.sh + cni/) to a tempdir and runs `podman build` against it. Idempotent: every invocation is a fresh tempdir, but podman's own layer cache means a second run with no source changes returns in seconds (each RUN line hashes its inputs; identical inputs reuse the cached layer).

Returns the image tag that was produced and any build error. The tempdir is cleaned up on return regardless of outcome.

func Down

func Down(ctx context.Context, opts Options) error

Down stops + removes the container. Used during outpost shutdown + when the operator disables DKS.

func DownServer

func DownServer(ctx context.Context, opts ServerOptions) error

DownServer stops and removes the control-plane container. The data volume is deliberately KEPT: removing it destroys the cluster's identity, and a stop is not a request to do that.

func EnsureImage added in v0.14.8

func EnsureImage(ctx context.Context, opts BuildOptions, wantVersion, stateDir string) (bool, error)

EnsureImage builds the runtime image iff it is absent OR was built by a different outpost version — so an `outpost upgrade` (or any binary swap) makes the container image self-rebuild on the next DKS agent start, with no manual `outpost cluster build-runtime` step. It returns whether a rebuild happened.

Why a host marker file instead of an image label: the pinned podman engine's `build` accepts only --build-arg/-f/-t (no --label), so the image can't carry the version itself. `<stateDir>/runtime-image-version` records the version that produced the current image; a mismatch (or a missing image) triggers a rebuild. Cheap: one `image inspect` in the steady state, no rebuild.

func ExecInContainer added in v0.14.7

func ExecInContainer(ctx context.Context, opts Options, args ...string) ([]byte, error)

ExecInContainer runs a command inside the outpost's runtime container and returns its combined output.

Used by the overlay refresher to talk to the tailscaled that lives in there — checking `tailscale status` and re-running `tailscale up` with a fresh key. Going through podman exec (rather than reaching into the container's socket) keeps the daemon free of any assumption about the container's internals beyond "the tailscale CLI is on its PATH".

A non-nil error covers both "podman could not run it" and "the command exited non-zero"; the output is returned either way so callers can log what actually happened.

func KubeconfigPath

func KubeconfigPath(dir string) string

KubeconfigPath is where the admin kubeconfig lands on the HOST.

func PodmanAvailable

func PodmanAvailable() bool

PodmanAvailable reports whether the runtime is usable on this host. Outpost CLI / admincore status surface uses this to render a clear "DKS agent runtime unavailable — install podman" hint instead of failing silently at start time.

func PurgeVolumes added in v0.14.11

func PurgeVolumes(ctx context.Context, opts Options) error

PurgeVolumes removes a node's persistent-identity volumes so the next join mints a FRESH identity (new machine key → clean Headscale registration → the overlay can converge). Call ONLY after Down (the container must be gone — podman refuses to remove an in-use volume) AND after cloudbox's node teardown succeeded. A missing volume is normal (swallowed); `-f` also detaches a stopped container's reference.

func ServerContainerName

func ServerContainerName(agentName string) string

ServerContainerName is the container this host's control plane runs in.

func ServerNodeToken

func ServerNodeToken(ctx context.Context, opts ServerOptions) (string, error)

ServerNodeToken returns the k3s node token of the control plane this host hosts. The value is a CREDENTIAL — callers must print it to stdout on request and never log it.

Errors distinguish the three ways this fails, because they need different fixes: no container engine, no control-plane container running, and a container that is up but has not initialized the cluster yet.

func SuperviseServer

func SuperviseServer(ctx context.Context, opts ServerOptions, cfg SupervisorConfig) error

SuperviseServer keeps this host's control-plane container up and serving for the life of ctx. It returns nil when ctx is cancelled and never returns otherwise — run it under the daemon errgroup.

A bring-up failure is never terminal: unlike the previous one-shot UpServer, a cold engine at boot only delays the plane, it does not disable it until the next restart.

func TailLogs

func TailLogs(ctx context.Context, opts Options) error

TailLogs blocks and streams the container's logs to slog at info level. Returns when the container exits (or ctx is canceled). The caller typically runs this in a goroutine inside the errgroup.

func Up

func Up(ctx context.Context, opts Options) error

Up ensures the runtime container is running with the supplied credentials. Idempotent: if a matching container with the expected name already exists, Up reuses it (or starts it if stopped). Configuration/image changes replace it and mark the new inner runtime for stale-IPAM recovery. Returns immediately after the container is started; container exit is observed through ctx + a follow-up goroutine the caller spins to tail logs.

func UpServer

func UpServer(ctx context.Context, opts ServerOptions) error

UpServer brings up (or reattaches to) this host's control plane. Idempotent.

Types

type BuildOptions added in v0.1.3

type BuildOptions struct {
	// Tag is the image reference to produce (e.g.
	// "outpost-runtime:dev" or a registry-qualified name for push).
	// Empty defaults to DefaultImage.
	Tag string

	// TargetArch is the linux architecture of the runtime image
	// ("amd64" or "arm64"). Empty defaults to the host's arch — the
	// usual case, since the container runs on the same machine the
	// outpost daemon does. Override only when cross-building (e.g.
	// from an arm64 dev machine for an amd64 production host).
	TargetArch string

	// PodmanBin overrides the autodetected `podman`/`docker` binary
	// used to drive the build. Empty triggers the same PATH lookup
	// the supervisor uses (pickPodmanBin).
	PodmanBin string

	// Stdout / Stderr receive the podman build's output. Defaults
	// (when nil) route to os.Stdout / os.Stderr so the operator
	// sees the build progress interactively.
	Stdout, Stderr *os.File
}

BuildOptions controls `outpost cluster build-runtime`. All fields are optional — sensible defaults match the supervisor in Up().

type Options

type Options struct {
	// AgentName is the outpost's identity. The container's k3s-agent
	// joins as Node <AgentName>; the container itself is named
	// <AgentName>-runtime.
	AgentName string
	// HostName is the registered physical host that owns this Node.
	// It may differ from AgentName when the operator overrides the
	// cluster node-name prefix.
	HostName string

	// Image is the runtime container image (e.g. "outpost-runtime:dev").
	// Built once via `outpost cluster build-runtime` or pulled from a
	// registry. Empty defaults to DefaultImage.
	Image string

	// NodeToken is the k3s join token cloudbox handed out at pairing
	// (K10<ca-hash>::node:<secret>). Passed into the container via
	// the OUTPOST_NODE_TOKEN env var; never written to disk on the
	// host.
	NodeToken string

	// APIServer is the URL the container's k3s-agent dials. In the
	// cloudbox model this is the loopback STCP visitor inside the
	// container (see overlay package). Empty defaults to
	// "https://127.0.0.1:6443".
	APIServer string

	// CloudboxHost / CloudboxPort are where the container-side frpc
	// dials to establish the matrix-tunnel + STCP visitor. Required
	// for the kubelet-in-container model — entrypoint.sh runs frpc
	// to open 127.0.0.1:APIPort inside the container, tunneling to
	// cloudbox's embedded apiserver. e.g. "ai.dhnt.io" + 443.
	CloudboxHost string
	CloudboxPort int

	// STCPSecret authenticates the STCP visitor on the cloudbox side
	// (cluster.k3s-apiserver publisher). Cluster-wide secret minted
	// at pairing time; passed in via env.
	STCPSecret string

	// MatrixToken is the shared frp auth token (same value cloudbox
	// holds in MATRIX_TOKEN). Empty disables [auth] in frpc.toml.
	MatrixToken string

	// FRPProtocol / FRPServerUser select WHICH control plane this node
	// joins, without changing anything else about the runtime.
	//
	// Cloudbox is reached over "wss" (TLS terminated at its edge) and
	// publishes the apiserver as user "cloudbox". A peer-hosted plane is
	// reached over plain "tcp" (an frps on another of the user's own
	// machines, usually via loopback or LAN) and publishes as
	// "control-plane". The entrypoint defaults both to the cloudbox values,
	// so an empty pair renders a byte-identical frpc.toml to the one that
	// shipped before peer-hosted planes existed.
	//
	// The serverUser is not cosmetic: frp scopes STCP visibility BY USER, so
	// a visitor naming the wrong one is refused rather than misrouted.
	FRPProtocol   string
	FRPServerUser string

	// APIPort is the loopback port the STCP visitor binds inside the
	// container (must match cloudbox's ClusterAPIServerPort). Empty
	// defaults to 6443.
	APIPort int

	// APIBridgeHostPort publishes the in-container apiserver visitor on this
	// port of the HOST's loopback interface. Peer-plane virtual-kubelet
	// runners use it to reach the exact same authenticated visitor as the
	// physical agent. Zero preserves the historical cloudbox behavior: no
	// host port is published and the visitor remains container-local.
	//
	// The host bind address is deliberately not configurable. The peer
	// apiserver is never a LAN service.
	APIBridgeHostPort int

	// KubeletPort is the per-outpost port cloudbox allocated at
	// pairing time (fc.Cluster.KubeletProxyPort). Three things ride
	// on this same number so the apiserver→kubelet hop terminates:
	//   - kubelet binds + advertises this port (so the Node's
	//     daemonEndpoint.Port matches what's reachable);
	//   - the in-container frpc publishes 127.0.0.1:<port> to
	//     cloudbox's loopback at the same port number;
	//   - cloudbox's apiserver dials 127.0.0.1:<port> for this Node.
	// Empty (0) leaves the kubelet on its default 10250 with no
	// outbound publish — `kubectl exec`/`logs`/`port-forward` won't
	// work against this outpost, but the rest of cluster-agent mode
	// keeps functioning. Old pairings without KubeletProxyPort
	// allocated land here.
	KubeletPort int

	// PodCIDR is the per-outpost /24 carved by cloudbox at Exchange
	// time. Empty disables the outpost-cni conflist; k3s falls back
	// to its own defaults (--flannel-backend=none means no pod
	// networking, fine for control-plane-only smoke tests).
	PodCIDR string

	// OverlayLoginServer / OverlayAuthKey turn on tailscaled inside
	// the container. Both must be non-empty; both empty leaves the
	// overlay off (single-node mode).
	OverlayLoginServer string
	OverlayAuthKey     string

	// PeerFlannel selects the peer-hosted-DKS pod network: stock k3s
	// flannel VXLAN pinned to the tailnet underlay
	// (--flannel-iface=tailscale0), per
	// docs/adr-peer-dks-pod-network.md. Set when this node joins a
	// PEER-hosted control plane.
	//
	// It changes what the entrypoint does in three ways: no conflist is
	// written (flannel writes its own 10-flannel.conflist), any conflist
	// left behind by a previous mode is REMOVED (CNI picks the
	// lexically-first file, so a stale 10-bridge.conflist would
	// out-select flannel and silently misroute), and the agent refuses
	// to start until tailscale0 actually has an IPv4.
	//
	// Never set for the cloudbox-hosted plane — that path keeps using
	// outpost-cni + advertised routes, byte-for-byte as before.
	PeerFlannel bool

	// OverlayRelay* describe the SECOND frpc session a peer-joined worker's
	// container opens — directly to CLOUDBOX — for exactly one visitor: the
	// `overlay-control` STCP publisher that carries the ts2021 tailnet
	// registration (Cloudflare strips the Upgrade header on the public
	// HTTPS URL, so this tunnelled hop is the only path to Headscale).
	//
	// On the cloudbox-hosted plane these stay empty: there the MAIN frpc
	// session already dials cloudbox and carries the overlay-control
	// visitor, byte-for-byte as before. On a peer plane the main session
	// dials the PEER's frps, which publishes no overlay-control — hence
	// this dedicated relay session.
	//
	// Host/Port/Protocol/Token are the cloudbox PAIRING values
	// (fc.ServerAddr/ServerPort/Protocol/Token); Secret is cloudbox's
	// cluster STCP secret (conf.ClusterConfig.CloudSTCPSecret); User is
	// the publisher's frp user (conf.CloudboxPublisherUser). All-empty
	// disables the relay.
	OverlayRelayHost     string
	OverlayRelayPort     int
	OverlayRelayProtocol string
	OverlayRelayToken    string
	OverlayRelaySecret   string
	OverlayRelayUser     string

	// PodmanBin overrides the autodetected `podman`/`docker` binary.
	// Empty triggers PATH lookup; tests set it.
	PodmanBin string

	// ExtraEnv is appended to the container's env in KEY=VALUE form.
	// Escape hatch for development.
	ExtraEnv []string

	// ForceRecreate replaces an otherwise matching runtime. The caller sets
	// this when EnsureImage rebuilt the local image in this process.
	ForceRecreate bool
}

Options is the supervisor's input. All fields except ExtraEnv are required; LoginServer/AuthKey/PodCIDR may be empty for single-node (no-overlay) testing.

func (Options) OverlayRelayActive

func (o Options) OverlayRelayActive() bool

OverlayRelayActive reports whether these Options carry a usable relay: both the endpoint and the visitor secret must be present, matching the entrypoint's own activation test. A half-configured relay (host with no secret, or vice versa) is treated as absent so the failure surfaces in the daemon's fail-closed check rather than as an frp auth error inside the container.

func (Options) PodNetwork added in v0.14.7

func (o Options) PodNetwork() PodNetwork

PodNetwork classifies the node these Options describe, honoring an ExtraEnv override of the fallback range so the reported CIDR matches what the container will really allocate from.

type PodNetwork added in v0.14.7

type PodNetwork struct {
	// Mode is the classification. Never empty.
	Mode PodNetworkMode

	// PodCIDR is the range pods on this node get IPs from. In overlay
	// mode it is the cloudbox-allocated per-node CIDR; in fallback mode
	// it is the fixed range shared with every other node.
	PodCIDR string
}

PodNetwork is the classified pod-network state of one node: which mode the container will come up in, and the pod CIDR that mode will actually allocate from.

func ClassifyPodNetwork added in v0.14.7

func ClassifyPodNetwork(podCIDR string, peerFlannel bool) PodNetwork

ClassifyPodNetwork is the single source of truth for the mode.

peerFlannel wins over the CIDR test: a peer-joined worker's pod CIDR is allocated by the PEER's k3s controller-manager and is not knowable here, so "PodCIDR is empty" no longer implies the single-node fallback the way it did when cloudbox was the only allocator.

func (PodNetwork) Log added in v0.14.7

func (n PodNetwork) Log(node string)

Log announces the pod-network mode at boot. The fallback is logged at WARN, not Info: a node with no pod network is a silent multi-node-cluster corruption, and this line is the only place it becomes visible before pods start colliding. The overlay case logs at Info with the CIDR so the two are trivially greppable.

func (PodNetwork) Overlay added in v0.14.7

func (n PodNetwork) Overlay() bool

Overlay reports whether this node has a real (per-node, routable) pod network.

type PodNetworkMode added in v0.14.7

type PodNetworkMode string

PodNetworkMode classifies which CNI configuration the runtime container's entrypoint will write for this node. The modes are NOT interchangeable and the difference is invisible from the outside — a node in any of them joins and reports Ready — so this type exists to make the distinction nameable, loggable, and reportable rather than implicit in "is OUTPOST_POD_CIDR set".

const (
	// PodNetworkOverlay means cloudbox carved a per-outpost pod CIDR
	// for this node and the entrypoint writes the outpost-cni conflist
	// over the tailscale overlay: unique pod IPs per node, cross-node
	// pod routing. This is the only mode that is correct in a
	// multi-node cluster.
	PodNetworkOverlay PodNetworkMode = "overlay"

	// PodNetworkSingleNodeFallback means no pod CIDR was allocated, so
	// the entrypoint falls back to a plain bridge + host-local IPAM out
	// of a FIXED range that is identical on every node. Correct for a
	// single-node cluster; catastrophic in a multi-node one — every
	// node hands out the same pod IPs, Service endpoint lists contain
	// duplicate addresses, and kube-proxy can DNAT a request to the
	// wrong local workload. Nothing errors and the node reports Ready,
	// which is precisely why it has to be announced.
	PodNetworkSingleNodeFallback PodNetworkMode = "single-node-fallback"

	// PodNetworkPeerFlannel means this node joins a PEER-hosted control
	// plane and gets its pod network from stock k3s flannel VXLAN pinned
	// to the tailnet underlay (--flannel-iface=tailscale0). See
	// docs/adr-peer-dks-pod-network.md (Option A).
	//
	// This is a CORRECT multi-node mode, not a fallback: flannel reads
	// Node.spec.podCIDR — allocated by the peer's own k3s
	// controller-manager — so there is no per-node CIDR for outpost to
	// carry, no conflist for the entrypoint to template, and nothing for
	// cloudbox to allocate. The pod CIDR is genuinely unknown on this
	// side of the join, which is why PodCIDR stays empty here rather
	// than being filled with a placeholder that would read as a real
	// allocation.
	PodNetworkPeerFlannel PodNetworkMode = "peer-flannel"
)

type ServerHealth

type ServerHealth struct {
	// Endpoint is the URL that was probed.
	Endpoint string `json:"endpoint"`
	// Serving is the load-bearing field: the apiserver answered in HTTP.
	//
	// ANY well-formed HTTP response counts, including 401 and 403. An
	// apiserver that denies anonymous requests still had to accept the
	// connection, complete a TLS handshake and route the request to say so —
	// which is the whole question. Only a transport error (refused, timed
	// out, TLS never completed) means dead. Treating a 401 as unhealthy
	// would have the supervisor restart a perfectly good, correctly-locked
	// down control plane in a loop.
	Serving bool `json:"serving"`
	// Status is the HTTP status code when Serving.
	Status int `json:"status,omitempty"`
	// Err is the transport error when not Serving.
	Err string `json:"err,omitempty"`
	// ContainerRunning / ContainerExists describe the container the plane
	// runs in. Populated by CheckServer, not by ProbeAPIServer.
	ContainerRunning bool `json:"container_running"`
	ContainerExists  bool `json:"container_exists"`

	CheckedAt time.Time `json:"checked_at"`
}

ServerHealth is a point-in-time answer to "is this host's control plane actually serving?". Exported, and cached in LastServerHealth, so a status surface can report it without owning a probe of its own.

func CheckServer

func CheckServer(ctx context.Context, opts ServerOptions) ServerHealth

CheckServer answers the whole question for one host: is the control-plane container running, and is the apiserver inside it serving? The result is cached for LastServerHealth.

This is the function a status surface calls. It is safe on a host that hosts nothing — the container simply does not exist and Serving is false.

func LastServerHealth

func LastServerHealth() (ServerHealth, bool)

LastServerHealth returns the most recent readiness result the supervisor (or a CheckServer caller) observed, and whether there has been one at all.

Exported for the status surface: reading a cached answer costs nothing, so a status call never has to wait on a network timeout to say something useful.

func ProbeAPIServer

func ProbeAPIServer(ctx context.Context, endpoint string) ServerHealth

ProbeAPIServer asks one question: does an apiserver answer at endpoint?

It never fails — a dead server is a result, not an error — so callers get a classification rather than an error to interpret.

func (ServerHealth) String

func (h ServerHealth) String() string

String renders a health result for logs and for an operator-facing status line. Kept here so every surface says the same thing.

type ServerOptions

type ServerOptions struct {
	// AgentName identifies the host; the container is <AgentName>-control-plane.
	AgentName string
	// Image defaults to DefaultImage — the SAME image the agent runtime uses,
	// so an operator never has to keep two images in step.
	Image string

	// TunnelToken gates worker frpc logins.
	TunnelToken string
	// STCPSecret authorizes visitors of the published apiserver proxy.
	STCPSecret string

	// TunnelBindAddr / TunnelBindPort are where the container PUBLISHES its
	// frps to the host. Defaults 127.0.0.1:7000 — loopback, so enabling a
	// control plane never silently exposes it to the network.
	TunnelBindAddr string
	TunnelBindPort int

	// APIPort is the apiserver's port, used BOTH inside the container and as
	// the published host port so the kubeconfig k3s writes is valid on the
	// host unmodified.
	//
	// DEFAULT 16443, NOT 6443, and the difference is load-bearing. A host that
	// JOINS a cluster already binds 127.0.0.1:6443 — that is where its STCP
	// visitor puts the apiserver it joins. A host that also HOSTS a plane
	// would collide, and the collision is silent and vicious: kubectl reaches
	// whichever listener won the port while presenting the OTHER cluster's CA,
	// so it reports `certificate signed by unknown authority` and every
	// instinct says "bad certificate" rather than "wrong server".
	//
	// Hosting and joining are independent decisions, so they must not contend
	// for one port.
	APIPort int

	// KubeconfigDir is a HOST directory the container writes its admin
	// kubeconfig into. This is what makes the cluster operable without
	// `podman exec`, and what cluster.control_plane_kubeconfig points at.
	KubeconfigDir string

	// TLSSANs are extra apiserver certificate SANs, comma-separated. Needed
	// when workers reach this plane by an address other than loopback.
	TLSSANs string

	ClusterCIDR string
	ServiceCIDR string

	PodmanBin     string
	ForceRecreate bool
}

ServerOptions configures the control-plane container.

func (ServerOptions) APIReadyURL

func (o ServerOptions) APIReadyURL() string

APIReadyURL is the address the hosted apiserver's readiness endpoint is reachable at FROM THIS HOST — the same host:port the kubeconfig k3s writes names, because the container publishes the apiserver there precisely so the kubeconfig is valid unmodified.

A wildcard bind is probed on loopback: 0.0.0.0 is where the listener accepts, not an address anything dials.

type SupervisorConfig

type SupervisorConfig struct {
	// CheckInterval is how often the readiness probe runs once the container
	// is up.
	CheckInterval time.Duration
	// UnhealthyGrace is how long the apiserver must be continuously unhealthy
	// (container gone, or up but not serving) before the container is
	// recreated. A single missed probe is not a restart: k3s can be briefly
	// unresponsive under load, and a hair-trigger supervisor is its own
	// outage.
	UnhealthyGrace time.Duration
	// FirstBackoff / MaxBackoff bound the retry after a bring-up or recreate
	// failure — e.g. a container engine still cold at boot, the same reason
	// the join side retries rather than treating the first failure as fatal.
	FirstBackoff time.Duration
	MaxBackoff   time.Duration
}

SupervisorConfig tunes SuperviseServer. The zero value is usable — every field falls back to a production-sane default via withDefaults.

Directories

Path Synopsis
image
cni command
Command outpost-cni implements a minimal Container Network Interface (CNI) plugin for Phase 3 of the outpost overlay design.
Command outpost-cni implements a minimal Container Network Interface (CNI) plugin for Phase 3 of the outpost overlay design.
cni/internal/plugin
Package plugin contains the load-bearing logic for the outpost-cni binary, factored out so the tiny main package stays under 100 lines.
Package plugin contains the load-bearing logic for the outpost-cni binary, factored out so the tiny main package stays under 100 lines.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL