Documentation
¶
Overview ¶
Package isolation defines where the node stack (containerd, kubelet, CNI and CoreDNS) runs on a host. The agent and its daemon always run on the host; a Backend decides only where the node stack lives and how it is operated.
Phases receive a NodeRoot and call Path and Backend.Exec. They must not reference machine directories, machinectl or systemd-run --machine directly. Operations that need only a slot take a SlotRef; a caller with no filesystem view of the node passes a SlotName.
There is no global backend registry. The agent wires each mode's backend, daemon node operator and bootstrap plan together in one composition table (cmd/agent/internal/cmd/modes.go), so adding a mode is one table entry.
Index ¶
- Constants
- func JournalTailArgs(opts LogOptions) []string
- func StartLogStream(ctx context.Context, name string, args ...string) (io.ReadCloser, error)
- type Backend
- type DirRoot
- type ExecResult
- type ExecSpec
- type FakeBackend
- func (f *FakeBackend) Calls() []string
- func (f *FakeBackend) Destroy(_ context.Context, r SlotRef) error
- func (f *FakeBackend) Exec(_ context.Context, r SlotRef, cmd ExecSpec) (ExecResult, error)
- func (f *FakeBackend) Execs() []ExecSpec
- func (f *FakeBackend) Logs(_ context.Context, r SlotRef, _ LogOptions) (io.ReadCloser, error)
- func (f *FakeBackend) Mode() Mode
- func (f *FakeBackend) Prepare(_ context.Context, n NodeSpec) (NodeRoot, error)
- func (f *FakeBackend) Requirements() Requirements
- func (f *FakeBackend) Restart(_ context.Context, r SlotRef) error
- func (f *FakeBackend) Start(_ context.Context, r SlotRef) error
- func (f *FakeBackend) Status(_ context.Context, r SlotRef) (Status, error)
- func (f *FakeBackend) Stop(_ context.Context, r SlotRef) error
- type Grant
- type GrantKind
- type GrantPurpose
- type LibDirMount
- type LogOptions
- type Mode
- type NodeRoot
- type NodeSpec
- type Requirements
- type SlotName
- type SlotRef
- type Status
Constants ¶
const DefaultMode = ModeNSpawn
DefaultMode is the mode used when none is configured or recorded.
Variables ¶
This section is empty.
Functions ¶
func JournalTailArgs ¶
func JournalTailArgs(opts LogOptions) []string
JournalTailArgs returns the journalctl flags for the follow and line-count options. Each backend supplies the flags that select its units or machine, because they differ by mode.
func StartLogStream ¶
StartLogStream starts a command and returns its standard output. Closing the reader waits for the command, so a stream that was cut short does not leave a zombie. When the command ran to the end of its output and exited non-zero, for example journalctl against a machine that does not exist, Close returns an error carrying the end of its stderr. Stopping the stream early, by closing it or canceling ctx, is not an error.
Types ¶
type Backend ¶
type Backend interface {
Mode() Mode
// Requirements declares host requirements checked by preflight before
// anything is mutated, and ordering dependencies on host-global units.
Requirements() Requirements
// Prepare materializes a node root for a slot: it unpacks or installs
// artifacts and renders backend configuration.
Prepare(ctx context.Context, n NodeSpec) (NodeRoot, error)
Start(ctx context.Context, r SlotRef) error
Stop(ctx context.Context, r SlotRef) error
// Restart restarts the node stack only, never the host (soft reboot).
Restart(ctx context.Context, r SlotRef) error
// Destroy removes the node root and backend configuration for a slot.
Destroy(ctx context.Context, r SlotRef) error
Status(ctx context.Context, r SlotRef) (Status, error)
// Exec runs a command in the node stack.
Exec(ctx context.Context, r SlotRef, cmd ExecSpec) (ExecResult, error)
// Logs streams logs for a unit in the node stack.
Logs(ctx context.Context, r SlotRef, opts LogOptions) (io.ReadCloser, error)
}
Backend owns where the node stack runs.
type DirRoot ¶
DirRoot is a NodeRoot whose filesystem is a directory on the host. The nspawn backend uses it with the unpacked rootfs directory.
Dir must be set. A DirRoot never maps paths onto the host root: an empty Dir would turn every path into a host path, so Path panics on one rather than let a phase write the node's files over the host's. Use NewDirRoot to get an error instead, and SlotName to name a slot without a filesystem view.
func NewDirRoot ¶
NewDirRoot returns the DirRoot for slot rooted at dir. dir must be an absolute path other than the host root.
type ExecResult ¶
type ExecResult struct {
// Stdout is the captured standard output with trailing newlines trimmed.
Stdout string
}
ExecResult is the outcome of a successful Exec.
type ExecSpec ¶
type ExecSpec struct {
// Args is the command and its arguments.
Args []string
}
ExecSpec is a command run in the node stack.
type FakeBackend ¶
type FakeBackend struct {
FakeMode Mode
// Dir is the directory the roots Prepare returns resolve under. It must be
// an absolute directory other than the host root; see DirRoot.
Dir string
PrepareErr, StartErr, StopErr, RestartErr, DestroyErr, StatusErr, ExecErr error
// FakeStatus is what Status reports when StatusErr is nil.
FakeStatus Status
// ExecFunc, when set, produces the result of Exec.
ExecFunc func(ExecSpec) (ExecResult, error)
// contains filtered or unexported fields
}
FakeBackend records every call and returns configured results. It is safe for concurrent use. Set the Err fields to inject failures.
func (*FakeBackend) Calls ¶
func (f *FakeBackend) Calls() []string
Calls returns the recorded operations in order, as "op slot" strings.
func (*FakeBackend) Destroy ¶
func (f *FakeBackend) Destroy(_ context.Context, r SlotRef) error
Destroy implements Backend.
func (*FakeBackend) Exec ¶
func (f *FakeBackend) Exec(_ context.Context, r SlotRef, cmd ExecSpec) (ExecResult, error)
Exec implements Backend.
func (*FakeBackend) Execs ¶
func (f *FakeBackend) Execs() []ExecSpec
Execs returns the recorded Exec commands in order.
func (*FakeBackend) Logs ¶
func (f *FakeBackend) Logs(_ context.Context, r SlotRef, _ LogOptions) (io.ReadCloser, error)
Logs implements Backend.
func (*FakeBackend) Requirements ¶
func (f *FakeBackend) Requirements() Requirements
Requirements implements Backend.
func (*FakeBackend) Restart ¶
func (f *FakeBackend) Restart(_ context.Context, r SlotRef) error
Restart implements Backend.
func (*FakeBackend) Start ¶
func (f *FakeBackend) Start(_ context.Context, r SlotRef) error
Start implements Backend.
type Grant ¶
type Grant struct {
Kind GrantKind
Purpose GrantPurpose
// Source is the host path (or device node). It is empty for a GrantDevice
// that only names a device class and has no node to expose.
Source string
// Target is the in-node path. Empty means the same as Source.
Target string
ReadOnly bool
// DeviceClass is a cgroup device class selector such as char-input, for a
// GrantDevice that has no Source.
DeviceClass string
// DeviceAllow lists the device node paths or device group specifiers (for
// example char-infiniband_verbs) a GrantMount of a device directory needs,
// so nodes created in the directory after the node stack starts are usable.
DeviceAllow []string `json:",omitempty"`
}
Grant is a backend-neutral request for host resources. Each backend applies it in its own way, and a backend with nothing to apply ignores it.
type GrantKind ¶
type GrantKind string
GrantKind is the type of a Grant.
const ( // GrantMount exposes a host path inside the node stack. GrantMount GrantKind = "mount" // GrantDevice exposes a host device inside the node stack. GrantDevice GrantKind = "device" // GrantLibraryPath adds a directory to the node stack's library search path. GrantLibraryPath GrantKind = "library-path" )
type GrantPurpose ¶
type GrantPurpose string
GrantPurpose says what a Grant is for. Backends use it to place a grant in the right section of their own configuration and to keep a stable rendering order. It carries no host paths.
const ( // PurposeHostDevice is a discovered or configured host device node, or a // systemd device group specifier, such as /dev/kvm or char-input. PurposeHostDevice GrantPurpose = "host-device" // PurposeHostMount is a configured host path, or a whole device directory // such as /dev/infiniband whose Grant.DeviceAllow covers the nodes in it. PurposeHostMount GrantPurpose = "host-mount" // PurposeNvidiaDevice is an NVIDIA GPU device node or directory. PurposeNvidiaDevice GrantPurpose = "nvidia-device" // PurposeNvidiaLibDir is a host directory of NVIDIA driver libraries. PurposeNvidiaLibDir GrantPurpose = "nvidia-lib-dir" // PurposeNvidiaI386LibDir is a host directory of 32-bit NVIDIA libraries. PurposeNvidiaI386LibDir GrantPurpose = "nvidia-i386-lib-dir" // PurposeNvidiaHelperBin is the host directory of NVIDIA helper binaries // that node-start copies into the node. PurposeNvidiaHelperBin GrantPurpose = "nvidia-helper-bin" // PurposeAMDDevice is an AMD GPU device node. PurposeAMDDevice GrantPurpose = "amd-device" // PurposeAMDSysFS is a host sysfs path the AMD device plugin reads. PurposeAMDSysFS GrantPurpose = "amd-sysfs" )
type LibDirMount ¶
LibDirMount is a host library directory made visible at ContainerDir. Index orders the mounts and maps libraries to their directory.
type LogOptions ¶
type LogOptions struct {
// Unit is the systemd unit inside the node stack. Empty means all units.
Unit string
// Follow keeps the stream open for new entries.
Follow bool
// Lines limits output to the last N entries when positive.
Lines int
}
LogOptions selects which logs Logs returns.
type Mode ¶
type Mode string
Mode names an isolation mode.
const ( // ModeNSpawn runs the node stack in a systemd-nspawn machine. It is the // default, and the mode of every host that has no recorded mode. ModeNSpawn Mode = "nspawn" // ModeNone runs the node stack as agent-owned units directly on the host. ModeNone Mode = "none" // ModeContainer runs the node stack in a privileged OCI container // supervised by an agent-owned systemd unit. It is experimental: the agent // operates it only when its configuration opts in. ModeContainer Mode = "container" )
func ParseMode ¶
ParseMode validates s and returns the Mode it names. The empty string is the default mode. Unrecognized values are rejected rather than ignored so an older agent never silently runs a newer mode as nspawn.
ParseMode only says whether a name is a mode. Whether this agent can operate a mode is answered by the agent's mode composition table.
type NodeRoot ¶
type NodeRoot interface {
SlotRef
// Path maps an in-node absolute path to its path as seen by the agent.
Path(inNode string) string
}
NodeRoot resolves paths into the node stack's filesystem view.
type NodeSpec ¶
type NodeSpec struct {
// Slot is the blue/green slot, for example kube1 or kube2.
Slot string
// Version is the Kubernetes version the node runs. It is informational:
// no backend selects behavior from it.
Version string
// Grants are device, mount and library requests the node stack needs.
Grants []Grant
}
NodeSpec describes the node a backend prepares.
type Requirements ¶
type Requirements struct {
// HostPackages are packages that must be present on the host.
HostPackages []string
// HostCommands are executables that must be resolvable on the host.
HostCommands []string
// WritablePaths are host paths that must be writable.
WritablePaths []string
// After lists host-global units the node stack must start after.
After []string
}
Requirements declares what a backend needs from the host. Preflight checks it before anything is mutated.
type SlotName ¶
type SlotName string
SlotName is a SlotRef that carries only a slot name. It has no filesystem view: a backend that needs one builds its own root from the slot.
type SlotRef ¶
type SlotRef interface {
Slot() string
}
SlotRef names the blue/green slot an operation acts on. Every NodeRoot is a SlotRef. Operations that need only the slot, such as starting or stopping a node, take a SlotRef, so a caller that has no filesystem view of the node passes a SlotName and never has to make one up.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package container is the isolation backend that runs the node stack in a privileged OCI container with systemd as PID 1.
|
Package container is the isolation backend that runs the node stack in a privileged OCI container with systemd as PID 1. |
|
Package isolationtest is the conformance suite every isolation backend must pass.
|
Package isolationtest is the conformance suite every isolation backend must pass. |
|
Package migrate moves a live node from one isolation mode to another.
|
Package migrate moves a live node from one isolation mode to another. |
|
Package none is the isolation backend that runs the node stack directly on the host as agent-owned systemd units.
|
Package none is the isolation backend that runs the node stack directly on the host as agent-owned systemd units. |
|
Package nspawn is the isolation backend that runs the node stack in a systemd-nspawn machine.
|
Package nspawn is the isolation backend that runs the node stack in a systemd-nspawn machine. |