Help us shape the future of Go! Take the 2026 Go Developer Survey

staticpod

package
v1.37.1-stratum.0-rc.2 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package staticpod renders and manages the control-plane static pod manifests (the control plane runs as kubelet-managed static pods).

stratum is the SOLE writer of the manifest directory: every manifest is re-rendered idempotently from the persisted node state on controller start, so hand-edits are overwritten by design and the rendered files stand as the on-disk truth.

The systemctl-shaped verbs the host-process model needed are replaced by three file operations kubelet reacts to:

Restart — re-render with a bumped restarted-at annotation (content change
          makes kubelet recreate the pod)
Stop    — remove the manifest and wait for the component to go down
Start   — re-render the manifest from the current node state

Index

Constants

View Source
const AdmissionConfigAnnotation = "stratum.ciq.com/admission-config-sha256"

AdmissionConfigAnnotation carries the sha256 of the node profile's AdmissionConfiguration file on the kube-apiserver pod. The apiserver reads the admission-webhook.yaml merged from it only when it starts, and its manifest names that file without its contents, so a changed admission body would otherwise leave the running apiserver on the old policy. It is an annotation of its own so AuditPolicyAnnotation keeps the value it had.

View Source
const AuditPolicyAnnotation = "stratum.ciq.com/audit-policy-sha256"

AuditPolicyAnnotation carries the sha256 of the node profile's plain config files, in order, on the kube-apiserver pod: for the cis profile, its audit policy. The apiserver reads such a file only when it starts, and its manifest names the file without its contents, so a changed file would otherwise leave the running apiserver on the old one.

View Source
const RestartedAtAnnotation = "stratum.ciq.com/restarted-at"

RestartedAtAnnotation is bumped by Restart; kubelet recreates a static pod whenever its manifest content changes, and the annotation is the one field whose only job is to change.

Variables

View Source
var Names = []string{"etcd", "kube-apiserver", "kube-controller-manager", "kube-scheduler", "kube-vip"}

Names is every component rendered as a static pod, in start order.

Functions

func Active

func Active(name string) bool

Active reports whether the component's localhost listener is up.

func Dir

func Dir() string

Dir is the kubelet staticPodPath (prepare.go points kubelet.conf here).

func Exists

func Exists(name string) bool

Exists reports whether this node renders the component at all — the static-pod replacement for comps.UnitExists ("is this a control plane?").

func HasListener

func HasListener(name string) bool

HasListener reports whether the component owns a localhost listener a caller can wait on (the checks Active polls): every roster component but kube-vip, whose metrics server is disabled, and no name outside the roster. It is the listenerless rule localPort already encodes, so a second static pod without a listener needs only its localPort entry left out.

func ManifestName

func ManifestName(name string) (string, bool)

ManifestName reports whether a file name in the manifest directory — or in a snapshot of it — is one of the rendered component manifests ("<name>.yaml"), and which component. It is false for a render-derived file, a staging leftover, and anything else: kubelet parses every visible file in the directory as a pod, but only these are ones this package renders, and only these does a manifest-set restore replace. Exported for the upgrade's readers of a manifest snapshot, which must count exactly the components a restore replaces — a webhook config file is not a pod kubelet runs.

func NamesFor

func NamesFor(st *nodestate.NodeState) []string

NamesFor is the roster this node state renders: Names in start order, with kube-vip in it exactly when the state carries a VIP. It is the one place the kube-vip-only-with-VIP rule lives, so every roster derived from it — the upgrade's re-render order, the restore's restart set — cannot restate the rule beside it. A fresh slice per call: callers append to and reorder the roster they are handed, and one that aliased Names would corrupt it for every other reader.

func PIDs

func PIDs(name string) ([]int, error)

PIDs lists the processes on this node running the component: procid's walk with the static-pod scanners' deliberately loose argv[0]-basename rule, so an image's entrypoint with no staged host path is still found. An unreadable process table is unknown, not proof that the process is gone.

func Path

func Path(name string) string

Path is the manifest file for one component.

func Put

func Put(name string, b []byte) error

Put writes b as name's manifest, exactly as given. It is for putting back a manifest read earlier, where re-rendering would take its images from this binary rather than from whatever was running (an upgrade rollback runs the newer binary against the older manifests).

func Read

func Read(name string) ([]byte, error)

Read returns name's manifest exactly as it is on disk, or nil when there is none.

func Restart

func Restart(name string) error

Restart re-renders with a bumped restarted-at annotation; kubelet recreates the pod on the content change.

func RestartAsIs

func RestartAsIs(name string) error

RestartAsIs restarts a component whose manifest must not change: it bumps the restarted-at annotation on the manifest as it is on disk, where Restart re-renders it and so takes its images from this binary. An upgrade rollback runs the newer binary against the older manifests it has just restored, and re-rendering those would put the newer images back. It reports an error for a component with no manifest.

func RestoreSnapshot

func RestoreSnapshot(dir string) error

RestoreSnapshot puts a snapshot's manifest set back where the render keeps it: every manifest through the package's one staging path into the manifest directory, every render-derived file at the live path the render writes it, with the mode the snapshot holds. Anything else in the snapshot — a stray file, a leftover — lands nowhere: kubelet parses every non-hidden file in the manifest directory as a pod, and the derived files belong in the directory the apiserver's argv names. Before anything moves, the visible staging files the pre-atomic writer left in the live manifest directory are swept: kubelet parses them as pods, and they sort AFTER the real manifest in the file source's glob, so they hold that pod's store key permanently.

func Running

func Running(name string) (bool, error)

Running reports whether a static-pod component process is still present on this node. Unlike Active, it covers a process that has already closed its listener while it finishes shutting down, and kube-vip which has no listener. An error means the process state is unknown.

func Snapshot

func Snapshot(dir string) error

Snapshot copies the manifest set into dir, which it creates: every component manifest in the manifest directory, plus the render-derived files. Staging leftovers and anything else in the directory stay out — a file that joined a snapshot would be restored as a pod on every later restore. The set lands complete or not at all: it is staged under a hidden name beside dir and renamed into place only once every copy succeeded, so a snapshot that exists is one a restore can put back whole. A caller that keeps an existing snapshot for its own resume semantics (the upgrade's) must check before calling: a snapshot already at dir is not retaken.

func Start

func Start(name string) error

Start (re)renders one component's manifest from the persisted node state — the static-pod equivalent of the supervisor's ArgsFn semantics: `stratum snapshot rejoin/restore` patches the state, and Start renders the patched membership flags.

func StartTicks

func StartTicks(pid int) (uint64, bool, error)

StartTicks is when process pid started, in clock ticks since boot.

func Stop

func Stop(name string, timeout time.Duration) error

Stop removes the manifest and waits until the component's process is gone, so callers that are about to do something destructive (move etcd's data dir aside) know the old process is no longer serving or retaining host state. kube-vip has no listener, but its process must still exit before teardown.

func WaitActive

func WaitActive(name string, timeout time.Duration) error

WaitActive polls until Active or timeout.

func WaitReplaced

func WaitReplaced(name string, mark Mark, timeout time.Duration) error

WaitReplaced waits until every process running the component started after mark: once a changed manifest is written, until kubelet has taken down whatever ran before it. A process that started in mark's own tick counts as started before it: kubelet takes far longer than a tick to start a pod from a manifest written after the mark. A check that the component answers, made before then, can be answered by a process from the manifest it replaced, however many times that one was restarted in between.

func WriteAll

func WriteAll(st *nodestate.NodeState) error

WriteAll renders every control-plane manifest this node needs. Idempotent: an unchanged render is not rewritten (kubelet would restart the pod), and a restarted-at annotation left by a previous Restart is preserved so a controller restart does not bounce every pod.

Types

type ContainerSpec

type ContainerSpec struct {
	// Command is the explicit command in the manifest. If empty, the image's
	// entrypoint is unknown to this reader.
	Command []string
	// Argv is Command followed by Args. Without Command it starts with Args,
	// not the image entrypoint.
	Argv []string
	// Env is the container's declared environment. It does NOT include the
	// image's own ENV layer, which is not visible from the manifest; that is
	// pinned by digest in build/images.txt and audited at build time.
	Env map[string]string
}

ContainerSpec is the rendered exec definition of a component, read back from the manifest kubelet actually reads.

It exists so an auditor can see a component's ARGV and its ENVIRONMENT together, from one artifact. For a kubelet-managed static pod those really are the whole story: a container's environment is the image's ENV plus the pod spec's env, and the kubelet does not leak its own environ into it. So for any component rendered here, this file is the environment — which is what makes an audit of etcd's boolean TLS flags decidable rather than an inference about etcd's defaults.

func ReadContainerSpec

func ReadContainerSpec(name string) (ContainerSpec, error)

ReadContainerSpec parses the rendered manifest for a component and returns its explicit command, combined argv and declared environment.

Deliberately reads the FILE rather than re-rendering from node state: a re-render would report what stratum intends, and the point of an audit is to report what kubelet was handed. An out-of-band edit is therefore visible here, which is exactly what a CIS check over these flags is for.

type Mark

type Mark struct {
	// contains filtered or unexported fields
}

Mark is a point in time on this node's boot clock, the clock process start times are kept in.

func Now

func Now() (Mark, error)

Now marks the current time on the boot clock.

Jump to

Keyboard shortcuts

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