PodResourceProfile API reference
Author a profile only for the intended pod/container selector or target. PRP changes resource fields at a lifecycle/activation transition; it does not replace KEDA activation. Do not overlap PRA or another writer on the same fields.
API details
Section titled “API details”Group: keda.kedify.io. Kind: PodResourceProfile. Scope: Namespaced.
Defaults below are schema defaults only. “Not specified” does not imply a controller default of zero or false. Required fields are required within their containing object. Runtime behavior can impose additional conditions described in the capability guide.
v1alpha1 fields
Section titled “v1alpha1 fields”Served: true; storage: true.
| Field | Type | Required | Schema default | Meaning and validation |
|---|---|---|---|---|
spec | object | No | Not specified | PodResourceProfileSpec defines the desired state of PodResourceProfile x-kubernetes-validations: [{“message”:“PodResourceProfile must have either a pod selector or target specified”,“rule”:“has(self.target) != has(self.selector)”},{“message”:”‘(de)activated’ triggers can be used only with ScaledObjects as targets. See .spec.target.kind”,“rule”:“!has(self.trigger.after) || !self.trigger.after.endsWith(‘activated’) || (has(self.target) && self.target.kind == ‘scaledobject’ && self.trigger.after.endsWith(‘activated’))”},{“message”:“Specify exactly one of newResources or newResourcesPercent”,“rule”:“has(self.newResources) != has(self.newResourcesPercent)”}] |
spec.containerName | string | Yes | Not specified | ContainerName what container in the pod should be updated minLength: 1 |
spec.newResources | object | No | Not specified | NewResources contains the new resource settings that should be applied x-kubernetes-validations: [{“message”:“Specify limits or requests or both”,“rule”:“has(self.limits) || has(self.requests)”}] |
spec.newResources.limits | object | No | Not specified | |
spec.newResources.limits.* | integer or string | No | Not specified | pattern: ”^(\+|-)?(([0-9]+(\.[0-9])?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9])?)|(\.[0-9]+))))?$” |
spec.newResources.requests | object | No | Not specified | |
spec.newResources.requests.* | integer or string | No | Not specified | pattern: ”^(\+|-)?(([0-9]+(\.[0-9])?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9])?)|(\.[0-9]+))))?$” |
spec.newResourcesPercent | object | No | Not specified | NewResourcesPercent contains signed percent deltas to apply to current resources x-kubernetes-validations: [{“message”:“Specify limits or requests or both”,“rule”:“has(self.limits) || has(self.requests)”}] |
spec.newResourcesPercent.limits | object | No | Not specified | ResourcePercentList maps resource name to signed percent delta. x-kubernetes-validations: [{“message”:“Only cpu and memory resources are supported”,“rule”:“self.all(k, k == ‘cpu’ || k == ‘memory’)”},{“message”:“Percent value must be between -99 and 1000”,“rule”:“self.all(k, self[k] >= -99 && self[k] <= 1000)”}] |
spec.newResourcesPercent.limits.* | integer | No | Not specified | |
spec.newResourcesPercent.requests | object | No | Not specified | ResourcePercentList maps resource name to signed percent delta. x-kubernetes-validations: [{“message”:“Only cpu and memory resources are supported”,“rule”:“self.all(k, k == ‘cpu’ || k == ‘memory’)”},{“message”:“Percent value must be between -99 and 1000”,“rule”:“self.all(k, self[k] >= -99 && self[k] <= 1000)”}] |
spec.newResourcesPercent.requests.* | integer | No | Not specified | |
spec.paused | boolean | No | false | Paused if set to true, can make the controller ignore this CR |
spec.priority | integer | No | 0 | Priority in case multiple (unpaused) PodResourceProfile CRs matches, only the one with the highest priority will be applied. If not specified, it is 0 and if multiple PodResourceProfile with the same priority matches the pod’s label selector, then the next one that’s closest to now() is chosen. Again if multiple match, then lexicographically smaller is picked (CR name). |
spec.selector | object | No | Not specified | Selector is the general label selector spec that identifies one or multiple Pods if selector is specified, don’t use the target |
spec.selector.matchExpressions | array | No | Not specified | matchExpressions is a list of label selector requirements. The requirements are ANDed. |
spec.selector.matchExpressions[] | object | No | Not specified | A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. |
spec.selector.matchExpressions[].key | string | Yes | Not specified | key is the label key that the selector applies to. |
spec.selector.matchExpressions[].operator | string | Yes | Not specified | operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. |
spec.selector.matchExpressions[].values | array | No | Not specified | values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. |
spec.selector.matchExpressions[].values[] | string | No | Not specified | |
spec.selector.matchLabels | object | No | Not specified | matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed. |
spec.selector.matchLabels.* | string | No | Not specified | |
spec.target | object | No | Not specified | Target is the reference to a workload whose pods should be modified if target is specified, don’t use the selector |
spec.target.kind | string | Yes | Not specified | Kind specifies the target workload whose containers will be obtaining the resource updates Caveat: if set to ‘scaledobject’ the ScaledObject has to have its ‘.spec.scaleTargetRef.kind’ equal to ‘deployment’, ‘daemonset’, ‘statefulset’, or ‘rollout’ so that we can reach its pods transitively. In other words, not every scalable CR will work here. The ‘rollout’ kind refers to an Argo Rollout in argoproj.io/v1alpha1. enum: [“deployment”,“daemonset”,“statefulset”,“rollout”,“scaledobject”] |
spec.target.name | string | Yes | Not specified | minLength: 1 |
spec.trigger | object | Yes | Not specified | Trigger is condition or event that triggers the resource change |
spec.trigger.after | string | No | "containerReady" | After specifies the event or the state pod/container needs to be in when we start counting (see Delay) Allowed values are: - ‘containerReady’: specifies whether the container is currently passing its readiness check. The value will change as readiness probes keep executing. If no readiness probes are specified, this field defaults to true once the container is fully started. field: pod.status.containerStatuses.ready time: pod.status.containerStatuses.state.running.startedAt - ‘containerStarted’: indicates whether the container has finished its postStart lifecycle hook and passed its startup probe. Initialized as false, becomes true after startupProbe is considered successful. Resets to false when the container is restarted, or if kubelet loses state temporarily. In both cases, startup probes will run again. Is always true when no startupProbe is defined and container is running and has passed the postStart lifecycle hook. The null value must be treated the same as false. field: pod.status.containerStatuses.started time: pod.status.containerStatuses.state.running.startedAt - ‘podReady’: means the pod is able to service requests and should be added to the load balancing pools of all matching services field: pod.status.conditions[?(.type==‘Ready’)].status time: pod.status.conditions[?(.type==‘Ready’)].lastTransitionTime - ‘podScheduled’: represents status of the scheduling process for this pod field: pod.status.conditions[?(.type==‘PodScheduled’)].status time: pod.status.conditions[?(.type==‘PodScheduled’)].lastTransitionTime - ‘podRunning’ means the pod has been bound to a node and all the containers have been started. At least one container is still running or is in the process of being restarted. field: pod.status.phase time: pod.status.startTime.time - ‘deactivated’ This is specific to KEDA and works only with .target.kind == scaledobject. It denotes a state of a ScaledObject whose triggers are not active. This is useful for throttling the CPU for a workloads that are not being actively used - stand-by mode. field: scaledobject.conditions[?(.type==‘Active’)].status time: scaledobject.conditions[?(.type==‘Active’)].lastTransitionTime when the aforementioned field goes from true (active) -> false (passive) - ‘activated’ Dual event to ‘deactivated’. field: scaledobject.conditions[?(.type==‘Active’)].status time: time: scaledobject.conditions[?(.type==‘Active’)].lastTransitionTime when the aforementioned field goes from true (passive) -> false (active) enum: [“containerReady”,“containerStarted”,“podReady”,“podScheduled”,“podRunning”,“deactivated”,“activated”] |
spec.trigger.delay | string | Yes | Not specified | Delay denotes how long the controller should wait before applying the new resources to the pod example values: 30s, 1m, 2m30s, 90s, 2h minLength: 1 |
status
Section titled “status”| Field | Type | Required | Schema default | Meaning and validation |
|---|---|---|---|---|
status | object | No | Not specified | PodResourceProfileStatus defines the observed state of PodResourceProfile |
status.conditions | array | No | Not specified | |
status.conditions[] | object | No | Not specified | Condition contains details for one aspect of the current state of this API Resource. |
status.conditions[].lastTransitionTime | string | Yes | Not specified | lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. |
status.conditions[].message | string | Yes | Not specified | message is a human readable message indicating details about the transition. This may be an empty string. maxLength: 32768 |
status.conditions[].observedGeneration | integer | No | Not specified | observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. minimum: 0 |
status.conditions[].reason | string | Yes | Not specified | reason contains a programmatic identifier indicating the reason for the condition’s last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty. minLength: 1; maxLength: 1024; pattern: ”^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$” |
status.conditions[].status | string | Yes | Not specified | status of the condition, one of True, False, Unknown. enum: [“True”,“False”,“Unknown”] |
status.conditions[].type | string | Yes | Not specified | type of condition in CamelCase or in foo.example.com/CamelCase. maxLength: 316; pattern: ”^([a-z0-9]([-a-z0-9][a-z0-9])?(\.[a-z0-9]([-a-z0-9][a-z0-9])?)/)?(([A-Za-z0-9][-A-Za-z0-9_.])?[A-Za-z0-9])$” |
status.effectiveSelector | object | No | Not specified | A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects. |
status.effectiveSelector.matchExpressions | array | No | Not specified | matchExpressions is a list of label selector requirements. The requirements are ANDed. |
status.effectiveSelector.matchExpressions[] | object | No | Not specified | A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. |
status.effectiveSelector.matchExpressions[].key | string | Yes | Not specified | key is the label key that the selector applies to. |
status.effectiveSelector.matchExpressions[].operator | string | Yes | Not specified | operator represents a key’s relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. |
status.effectiveSelector.matchExpressions[].values | array | No | Not specified | values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. |
status.effectiveSelector.matchExpressions[].values[] | string | No | Not specified | |
status.effectiveSelector.matchLabels | object | No | Not specified | matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is “key”, the operator is “In”, and the values array contains only “value”. The requirements are ANDed. |
status.effectiveSelector.matchLabels.* | string | No | Not specified | |
status.lastResourceUpdate | string | No | Not specified | |
status.observedGeneration | integer | No | Not specified | |
status.triggered | boolean | No | Not specified | |
status.triggeredAt | string | No | Not specified |
Inspect the installed contract
Section titled “Inspect the installed contract”kubectl get crd podresourceprofiles.keda.kedify.io -o yamlkubectl explain podresourceprofile.spec --recursiveCompare served/storage versions and schema before applying configuration. Inspect the resource’s status and events after changing its owning source; schema acceptance alone does not prove successful reconciliation.
Use, verify and diagnose
Section titled “Use, verify and diagnose”- Pod Resource Profiles (PRP)
- Keep a small warm pod instead of scaling to zero
- Pod resources do not resize as expected
Triggers
Section titled “Triggers”Allowed values include:
containerReady: (default value) specifies whether the container is currently passing its readiness check. The value will change as readiness probes continue executing. If no readiness probes are specified, this field defaults to true once the container is fully started.- field:
pod.status.containerStatuses.ready - time:
pod.status.containerStatuses.state.running.startedAt
- field:
containerStarted: indicates whether the container has completed its postStart lifecycle hook and passed its startup probe. Initialized as false, it becomes true after the startupProbe is considered successful. Resets to false if the container is restarted or if kubelet temporarily loses state. In both cases, startup probes will run again. Always true if no startupProbe is defined, and the container is running and has passed the postStart lifecycle hook. The null value must be treated the same as false.- field:
pod.status.containerStatuses.started - time:
pod.status.containerStatuses.state.running.startedAt
- field:
podReady: indicates that the pod can service requests and should be added to the load balancing pools of all matching services.- field:
pod.status.conditions[?(.type=='Ready')].status - time:
pod.status.conditions[?(.type=='Ready')].lastTransitionTime
- field:
podScheduled: represents the status of the scheduling process for this pod.- field:
pod.status.conditions[?(.type=='PodScheduled')].status - time:
pod.status.conditions[?(.type=='PodScheduled')].lastTransitionTime
- field:
podRunning: indicates that the pod has been bound to a node and all containers have started. At least one container is still running or is being restarted.- field:
pod.status.phase - time:
pod.status.startTime
- field:
(de)activated: this value is only allowed when.spec.target.kindis set toscaledobjectand it will triggers itself based on the activation status of the associated ScaledObject.
Addressing Pods
Section titled “Addressing Pods”In the example above, a common label selector was used. It has the same spec as a Deployment’s selector, so anything that
can appear under deployment.spec.selector can be used here as well. Using the selector we can make the PodResourceProfile feature
available also for Jobs and CronJobs.
Another way to target pods is by using the target field.
For example:
target: kind: deployment name: nginxUsing selector and target is mutually exclusive. The allowed kinds for .spec.target field are:
deploymentstatefulsetdaemonsetrollout(Argo Rollouts)scaledobject
It is assumed that the workload is present in the same namespace as the created PRP resource.