noderoll

package
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Jun 16, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package noderoll observes a managed-nodegroup rolling update in real time — which nodes are draining, terminating, and coming online — by reconciling against live Kubernetes Node state. It is the data source behind the live roll panel; rendering lives in internal/render.

EKS's UpdateNodegroupVersion API only reports one coarse status for the whole roll (via DescribeUpdate). The per-node truth comes from the cluster: managed nodegroup nodes carry the labels used below, so a label-scoped Node list/watch gives us exactly the nodegroup being rolled, classified by AMI and lifecycle.

Index

Constants

View Source
const (
	// LabelNodegroup scopes nodes to a single managed nodegroup.
	LabelNodegroup = "eks.amazonaws.com/nodegroup"
	// LabelImage is the AMI ID a node was launched with — the signal for
	// old-vs-new during an AMI roll.
	LabelImage = "eks.amazonaws.com/nodegroup-image"
)

EKS-managed nodegroup node labels.

Variables

This section is empty.

Functions

This section is empty.

Types

type Event

type Event struct {
	Node string    `json:"node"`
	Kind EventKind `json:"kind"`
}

Event is a single observed lifecycle transition.

type EventKind

type EventKind string

EventKind classifies a node lifecycle transition during a roll.

const (
	EvtJoining    EventKind = "joining"    // a new node appeared, not yet Ready
	EvtOnline     EventKind = "online"     // a node became Ready
	EvtDraining   EventKind = "draining"   // a node was cordoned / tainted for removal
	EvtTerminated EventKind = "terminated" // a node left the cluster
)

type KubeObserver

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

KubeObserver reads node state from the cluster's Kubernetes API, scoped to a single managed nodegroup. It is read-only and safe to poll.

func NewKubeObserver

func NewKubeObserver(client kubernetes.Interface, nodegroup, targetAMI string) *KubeObserver

NewKubeObserver returns an Observer for nodegroup, treating targetAMI as the "new" AMI the roll is moving toward.

func (*KubeObserver) CaptureBaseline

func (o *KubeObserver) CaptureBaseline(ctx context.Context) error

CaptureBaseline records the nodegroup's current node set as "old" so that nodes appearing afterward count as the new (on-target) nodes — for live rolls where the target AMI ID isn't known in advance.

func (*KubeObserver) Snapshot

func (o *KubeObserver) Snapshot(ctx context.Context) (Snapshot, error)

Snapshot lists the nodegroup's nodes and classifies each. Nodes from other nodegroups are excluded by the label selector.

type NodeView

type NodeView struct {
	Name     string `json:"name"`
	OnTarget bool   `json:"onTarget"` // launched with the target (new) AMI
	Ready    bool   `json:"ready"`
	Phase    Phase  `json:"phase"`
	// Pods/PodsTotal track eviction progress while a node is Draining (0 when
	// not draining or when pod accounting isn't available).
	Pods      int `json:"pods,omitempty"`
	PodsTotal int `json:"podsTotal,omitempty"`
	// Pressure lists active node-pressure conditions (MemoryPressure, etc.) — an
	// advisory layered over Phase. A node can be Ready yet under pressure when the
	// replacement instance is undersized; the roll looks healthy while it isn't.
	Pressure []string `json:"pressure,omitempty"`
}

NodeView is one node's observed state.

type Observer

type Observer interface {
	Snapshot(ctx context.Context) (Snapshot, error)
}

Observer yields successive snapshots of a roll. Implementations: a Kubernetes-backed one (below), an ASG-activities fallback, and a scripted one for tests/--simulate.

type Phase

type Phase string

Phase is a node's lifecycle position during a roll.

const (
	PhaseReady    Phase = "Ready"    // serving (Ready, not cordoned)
	PhaseJoining  Phase = "Joining"  // new node not yet Ready
	PhaseDraining Phase = "Draining" // cordoned / tainted for removal
)

type ScriptedObserver

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

ScriptedObserver replays a fixed sequence of snapshots. It backs the `nodegroup update --simulate` dev flag and tests, so the full live roll can be exercised with no AWS and no cluster. After the last frame it keeps returning the final state.

func NewScriptedObserver

func NewScriptedObserver(frames []Snapshot) *ScriptedObserver

NewScriptedObserver replays frames in order.

func (*ScriptedObserver) AtEnd

func (o *ScriptedObserver) AtEnd() bool

AtEnd reports whether the last frame has been reached.

func (*ScriptedObserver) Snapshot

func (o *ScriptedObserver) Snapshot(_ context.Context) (Snapshot, error)

Snapshot returns the next frame, advancing until the last (which then repeats).

type Snapshot

type Snapshot struct {
	Nodes       []NodeView `json:"nodes"`
	Total       int        `json:"total"`
	ReadyTarget int        `json:"readyTarget"` // Ready nodes already on the target AMI
	Draining    int        `json:"draining"`
	Joining     int        `json:"joining"`
	// Warnings are recent Kubernetes Warning events scoped to this nodegroup's
	// nodes — the "why is a node stuck" signal (failed drain/eviction, sandbox
	// failures) that the coarse lifecycle phases can't show.
	Warnings []WarnEvent `json:"warnings,omitempty"`
}

Snapshot is the nodegroup's state at one instant, plus roll aggregates.

func DemoTimeline

func DemoTimeline() []Snapshot

DemoTimeline builds a realistic surge roll of 3 old nodes → 3 new nodes (max-surge 1): each new node joins and goes Ready, then an old node drains its pods and terminates. Used by --simulate.

type Tracker

type Tracker struct {
	Events []Event
	// contains filtered or unexported fields
}

Tracker derives lifecycle events by diffing successive snapshots — turning the observer's point-in-time state into the "node came online / went offline" feed the live panel shows. It is pure: feed it snapshots, read Events.

func NewTracker

func NewTracker() *Tracker

NewTracker returns an empty Tracker.

func (*Tracker) Observe

func (t *Tracker) Observe(s Snapshot)

Observe diffs s against the previous snapshot and appends any transitions. The first snapshot is taken as the baseline (no events), so a roll that is already in flight on attach doesn't replay its whole history.

func (*Tracker) Recent

func (t *Tracker) Recent(n int) []Event

Recent returns the last n events (fewer if not enough have accrued).

type WarnEvent added in v0.8.0

type WarnEvent struct {
	Node    string `json:"node"`    // the nodegroup node it concerns
	Object  string `json:"object"`  // involved object, "Kind/name"
	Reason  string `json:"reason"`  // e.g. FailedDraining, FailedCreatePodSandbox
	Message string `json:"message"` // human detail (truncated for display)
}

WarnEvent is a Kubernetes Warning event scoped to a nodegroup node.

Jump to

Keyboard shortcuts

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