WorkloadScalerRule CRD
WorkloadScalerRule tells the EcoScale agent which Kubernetes workloads should participate in optimization. The controller watches matching resources and creates WorkloadScaler resources for them.
Use WorkloadScalerRule for fleet-level discovery and safe defaults. Use WorkloadScaler for the per-workload policy and recommendation status that EcoScale evaluates over time.
Basic Shape
Section titled “Basic Shape”apiVersion: escale.dev/v1alpha1kind: WorkloadScalerRulemetadata: name: defaultspec: resourceSelectors: - apiVersion: apps/v1 kind: Deployment - apiVersion: apps/v1 kind: StatefulSet namespaceSelector: any: true runInterval: 5h optimize: - name: resourceThis rule discovers Deployments and StatefulSets in all namespaces, then creates WorkloadScaler resources that run resource recommendations every five hours.
Resource Selectors
Section titled “Resource Selectors”spec.resourceSelectors defines the workload kinds the rule should discover.
| Field | Purpose |
|---|---|
apiVersion | API version of the target workload, such as apps/v1 or argoproj.io/v1alpha1. |
kind | Target workload kind, such as Deployment, StatefulSet, or a custom CRD kind. |
name | Optional resource name filter. Use it when a rule should target one workload of a kind. |
labelSelector | Optional Kubernetes label selector. Use it when discovery should be limited by labels. |
podNamePattern | Optional pod-name regex format string for custom workload kinds. The value must contain %s, which is replaced with the workload name. |
Standard Kubernetes workload kinds have built-in pod name patterns. Custom CRDs often need an explicit podNamePattern so EcoScale can build accurate metrics queries for the pods owned by that workload.
resourceSelectors: - apiVersion: argoproj.io/v1alpha1 kind: Rollout podNamePattern: "^%s-[a-z0-9]+-[a-z0-9]+$"The pattern belongs on the selector because the workload kind and API group define how pods are named. This keeps discovery and metrics behavior in one place, which is easier to reason about than maintaining a separate pod-pattern configuration for the same custom kind.
Namespace Selector
Section titled “Namespace Selector”spec.namespaceSelector controls which namespaces are searched.
namespaceSelector: any: trueUse any: true for cluster-wide discovery. Use matchNames when a rule should only create WorkloadScaler resources for a known set of namespaces:
namespaceSelector: matchNames: - payments - catalogFor multi-team clusters, namespace-scoped rules are often easier to roll out and audit than one broad rule with many special cases.
Recommendation Cadence
Section titled “Recommendation Cadence”spec.runInterval is copied to the created WorkloadScaler.spec.interval.
runInterval: 5hUse a cadence that matches how quickly workloads change. Short intervals can be useful during active validation. Longer intervals reduce noise for stable services.
Optimization Scope
Section titled “Optimization Scope”spec.optimize lists the recommender types enabled for created WorkloadScaler resources.
optimize: - name: resourceResource optimization covers CPU and memory requests and limits. Replica optimization fields exist for rule defaults, but only enable replica automation when your installation and rollout process support it.
Rule Defaults
Section titled “Rule Defaults”WorkloadScalerRule can define defaults for WorkloadScaler resources created by the controller. Defaults are only applied when the corresponding WorkloadScaler field is absent. They do not overwrite explicit workload policy.
resources: applyEnabled: false minReplicas: 2 cpu: scalingPolicy: RequestsOnly scalingGoal: Balanced memory: scalingPolicy: RequestsAndLimits scalingGoal: Balancedreplicas: minReplicas: 2 maxReplicas: 10| Field | Applied to created WorkloadScaler |
|---|---|
resources.applyEnabled: true | spec.resources.updatePolicy.updateMode: Auto when unset. |
resources.minReplicas | spec.resources.updatePolicy.minReplicas when unset. |
resources.cpu.scalingPolicy | Wildcard container CPU scalingPolicy when unset. |
resources.cpu.scalingGoal | Wildcard container CPU scalingGoal when unset. |
resources.memory.scalingPolicy | Wildcard container memory scalingPolicy when unset. |
resources.memory.scalingGoal | Wildcard container memory scalingGoal when unset. |
replicas.applyEnabled: true | spec.replicas.updateMode: Auto when unset. |
replicas.minReplicas | spec.replicas.minReplicas when unset. |
replicas.maxReplicas | spec.replicas.maxReplicas when unset. |
applyEnabled: false or an omitted applyEnabled does not force Preview. It simply avoids setting Auto. This is intentional: teams can start with safe discovery defaults, then promote selected workloads to automation when confidence is earned.
Skipping Defaults
Section titled “Skipping Defaults”Some workloads need hand-authored policy. Add escale.dev/skip-defaults: "true" to the target workload or to the WorkloadScaler to prevent rule defaults from being applied.
metadata: annotations: escale.dev/skip-defaults: "true"Use this escape hatch for critical services, workloads managed by another platform workflow, or cases where the rule default is broadly useful but not appropriate for one target. The rule can still discover the workload; it just leaves the defaultable policy fields alone.
Custom Workload Example
Section titled “Custom Workload Example”apiVersion: escale.dev/v1alpha1kind: WorkloadScalerRulemetadata: name: rollout-defaultsspec: resourceSelectors: - apiVersion: argoproj.io/v1alpha1 kind: Rollout podNamePattern: "^%s-[a-z0-9]+-[a-z0-9]+$" namespaceSelector: matchNames: - checkout runInterval: 6h optimize: - name: resource resources: minReplicas: 2 cpu: scalingPolicy: RequestsOnly scalingGoal: Balanced memory: scalingPolicy: RequestsAndLimits scalingGoal: BalancedThis rule discovers Argo Rollouts in the checkout namespace, tells EcoScale how to match their pods for metrics, and applies conservative resource defaults to newly created WorkloadScaler resources.
Operational Guidance
Section titled “Operational Guidance”Start with narrow rules when introducing a new workload kind or namespace. Confirm that discovery, pod matching, and recommendations behave as expected before widening scope. If applyEnabled is set to true, make sure the connected agent is installed with apply-capable permissions and that the owning team is ready for automation.