Architecture

Core concepts

How Kapr selects pods, validates revisions, handles recommendation changes, and persists proven resources.

Lifecycle

Pending
Preparing
Running
Awaiting
Persisted

A recommendation is captured as a deterministic revision, validated progressively, and either marked ValidatedWithoutPersistence or held at ValidatedAwaitingPersistence until admission-time injection occurs.

Stable, cumulative pod selection

StableHash sorts eligible pods using the workload UID and pod UID. Each percentage uses a prefix of that stable ordering, making steps cumulative: 10% followed by 25% adds the next 15%, rather than selecting a separate 25%.

Desired counts use ceiling division, so 10% of 11 pods selects 2 pods.

In-place resize semantics

StateMeaning
PendingNo resize has been requested.
InProgressPod spec has the target but runtime status has not caught up.
DeferredKubernetes reports a pending, retryable resize.
InfeasibleKubernetes cannot apply the resize; validation fails.
AppliedBoth pod spec and runtime status reflect the target.

A successful API patch is not enough. Kapr waits for pod status to report the target resources before counting the pod as applied.

Partial Manual resources

Manual recommendations are overlays on a frozen live baseline. Explicit request or limit keys replace baseline values, while omitted keys are inherited. Kapr freezes that baseline for the validation cycle so its own progressive rollout does not change the effective candidate between steps.

Omission means “preserve,” not “remove.” A partial recommendation requires consistent live Pod resources; otherwise Kapr cannot determine one safe inherited value.

QoS compatibility

Kubernetes fixes a Pod's QoS class at creation. An in-place resize cannot change it between BestEffort, Burstable, and Guaranteed. Kapr checks the complete Pod—including targeted containers, untargeted sidecars, and init containers—before requesting a resize.

If a recommendation would change QoS, Kapr sets phase Blocked and condition ResizeBlocked=True with reason InPlaceResizeWouldChangeQoSClass. For example, a fully resource-less BestEffort Pod cannot receive CPU or memory requests in place. Add initial resources to the workload template and recreate the Pods before validation.

Recommendation revisions and supersession

The revision fingerprints workload identity, container names, requests, and limits. Container order does not affect it.

If a recommendation changes during validation, Kapr supersedes the in-flight revision and begins again. If it changes after validation but before persistence, Kapr clears webhook eligibility and re-baselines from the already-resized live pods.

Rollout steps, persistence settings, lifecycle fields, labels, and annotations are deliberately excluded from the recommendation hash.

Manual revalidation

Changing spec.lifecycle.revalidationToken explicitly starts a fresh attempt even when the recommendation revision has not changed. Kapr records the handled token in status, making the request idempotent across reconciliation retries and controller restarts.

The new attempt starts at rollout step zero, uses a fresh live baseline, cancels pending persistence, and can retry a failed revision. VPA-backed canaries capture the latest available recommendation for the requested attempt.

The token is an opaque identifier, not a date. Clearing it does not trigger validation, and setting it back to the last observed value does nothing.

Deferred persistence

In AdmissionOnNextPodTemplateChange mode, validation does not patch the workload template. The webhook waits for the next update whose pod template is already changing, injects the validated resources, and adds revision annotations. The reconciler observes those annotations and records Persisted.

While awaiting persistence, an incoming resource edit is itself a template change. Kapr replaces matching container resources with the validated values. After the canary is Persisted, it does not continuously enforce against later drift.

Post-pause analysis

The optional CPU throttling evaluator queries Prometheus after the readiness check and pause. It supports AnyPod, PercentageOfPods, and Average aggregation. A failure triggers best-effort rollback and places the revision on a sticky deny-list.

The settle gate ensures every canary pod has been at target resources for at least the Prometheus lookback window before evaluation.