Target reference
targetRef:
apiVersion: apps/v1
kind: Deployment
name: checkout| API version | Kinds |
|---|---|
apps/v1 | Deployment, StatefulSet |
argoproj.io/v1alpha1 | Rollout |
Recommendation
recommendation:
source: Manual | VPA
manual:
containers:
- name: app
resources:
requests: { cpu: 500m, memory: 768Mi }
limits: { cpu: "1", memory: 1Gi }
vpa:
name: checkout-vpa
selection: Target | LowerBound | UpperBoundManual resources are partial overlays. You can specify only requests, only limits, or individual CPU or memory keys. Explicit keys replace the captured live baseline; omitted keys inherit it and never mean removal. Kapr stores and validates the complete merged candidate in status.
If live Pods have inconsistent resources, Kapr blocks a partial Manual recommendation with reason PartialManualRecommendationRequiresConsistentBaseline. Make the fleet consistent or provide complete CPU and memory requests and limits. Requests must not exceed their effective limits after merging.
VPA recommendations provide requests; their refresh policy controls limit handling independently.
VPA refresh and limit policy
refreshPolicy:
mode: ManualCapture | ThresholdBased
minimumCpuDeltaPercent: 10
minimumMemoryDeltaPercent: 10
minimumTimeSinceLastValidation: 168h
vpaCpuLimitPolicy: Omit | Derive
defaultCpuLimitPercentageBump: 0
defaultMemoryLimitPercentageBump: 20
forceLimitResizing: falseThresholdBased requires the minimum time to have elapsed and at least one container's CPU or memory delta to meet its threshold. Deltas may increase or decrease.
vpaCpuLimitPolicy defaults to Omit. When the original workload container has no CPU limit, Kapr keeps the VPA CPU request but omits its CPU limit, even if defaultCpuLimitPercentageBump is configured. Set the policy to Derive to apply that bump to CPU.
Kapr never removes an original CPU limit because Kubernetes does not support removing it through in-place resize. An existing sufficient CPU limit is retained; one below the new CPU request is raised to the request. Memory-limit derivation remains independent.
For derived limits, a bump of 0 makes limit equal request; 20 makes it 120% of request. With forceLimitResizing: false, an existing limit is preserved whenever it already accommodates the new request. These rules only apply to VPA recommendations; Manual recommendations use their explicit resources.
Rollout
rollout:
initialDelay: 5m
maxConcurrentResizes: 2
podSelection: { strategy: StableHash }
steps:
- { percent: 10, pause: 10m }
- { percent: 50, pause: 30m }
- { percent: 100, pause: 1h }Steps must be strictly increasing and end at exactly 100%. initialDelay measures pod age since its latest Ready transition.
Safety
safety:
minReadyPods: 3
requireAllTargetPodsReadyBeforeStarting: true
stopIfTargetWorkloadUpdating: true
allowSingleReplicaWorkload: false
CPU throttling analysis
analysis:
cpuThrottling:
enabled: true
thresholdFraction: 0.05
window: 5m
mode: AnyPod | PercentageOfPods | Average
percentageOfPodsThreshold: 30
onMetricsUnavailable: Pass | Fail
prometheus:
url: http://prometheus.monitoring.svc:9090The configured pause is a minimum. Analysis waits until every selected pod has spent at least one full analysis window at its resized target.
Persistence
persistence:
mode: AdmissionOnNextPodTemplateChange | Disabled
gitOps:
enabled: falseDisabled validates live pods but never propagates the result to the workload template. The terminal phase is ValidatedWithoutPersistence.
Lifecycle and manual revalidation
lifecycle:
onRecommendationChange: Revalidate
revalidationToken: "retry-1"revalidationToken is an optional opaque string. Each new non-empty value starts one fresh validation attempt using the currently resolved recommendation. It can be a timestamp, deployment ID, Git commit, or operator-generated nonce; Kapr does not parse it as a date.
Reusing the last observed value or clearing the field is a no-op. An explicit token can retry a failed revision once and, for VPA recommendations, captures the latest recommendation without waiting for configured refresh thresholds.
Selected status fields
| Field | Purpose |
|---|---|
status.phase | High-level lifecycle state. |
recommendation.currentRevision | Hash of the current candidate. |
recommendation.validatedRevision | Revision proven across the fleet. |
validation.baselineResources | Resources being changed from. |
validation.candidateResources | Resources being validated. |
validation.observedRevalidationToken | Last manual retrigger token processed. |
validation.pods | Per-pod resize lifecycle. |
recommendation.failedRevisions | Sticky deny-list of failed hashes. |
conditions | Kubernetes-style decision details. |
For every field and metric, see the repository's full source reference.