Skip to content

OptimizationPolicy CRD Specification

Complete field reference for the OptimizationPolicy Custom Resource Definition.

The OptimizationPolicy CRD defines how OptiPod optimizes Kubernetes workloads. Each policy specifies:

  • Which workloads to target (selector)
  • How to collect metrics (metricsConfig)
  • Resource constraints (resourceBounds)
  • How to apply changes (updateStrategy)
  • When to apply changes (mode)
apiVersion: optipod.io/v1alpha1
kind: OptimizationPolicy

Standard Kubernetes metadata fields:

metadata:
name: my-policy # Policy name (required)
namespace: default # Policy namespace (required)
labels: # Optional labels
environment: production
annotations: # Optional annotations
description: "Production workload optimization"

Defines the operational behavior of the policy.

Type: string Required: Yes Enum: Auto, Recommend, Disabled Default: None (must be specified)

Values:

  • Auto - Automatically applies resource recommendations to workloads
  • Recommend - Computes recommendations but does not apply them (safe mode)
  • Disabled - Stops processing workloads under this policy

Example:

spec:
mode: Recommend # Start in safe mode

Defines the priority of this policy when multiple policies match the same workload. Higher weight policies take precedence.

Type: integer Required: No Default: 100 Range: 1 to 1000

Example:

spec:
weight: 200 # Higher priority than default

Defines which workloads this policy applies to. At least one selector type must be specified.

Type: object Required: Yes

Selects namespaces by labels using Kubernetes label selector syntax.

Type: LabelSelector Required: No

Example:

selector:
namespaceSelector:
matchLabels:
environment: production
team: platform

With match expressions:

selector:
namespaceSelector:
matchExpressions:
- key: environment
operator: In
values:
- production
- staging
- key: team
operator: NotIn
values:
- experimental

Valid operators: In, NotIn, Exists, DoesNotExist

Selects workloads by labels using Kubernetes label selector syntax.

Type: LabelSelector Required: No

Example:

selector:
workloadSelector:
matchLabels:
optimize: "true"
tier: backend

Defines allow and deny lists for namespace filtering.

Type: object Required: No

Fields:

  • allow ([]string) - List of namespaces to include
  • deny ([]string) - List of namespaces to exclude (takes precedence over allow)

Example:

selector:
namespaces:
allow:
- production
- staging
deny:
- kube-system
- kube-public

Defines include/exclude filters for workload types.

Type: object Required: No

Fields:

  • include ([]WorkloadType) - Workload types to include (if empty, includes all)
  • exclude ([]WorkloadType) - Workload types to exclude (takes precedence over include)

Valid WorkloadType values: Deployment, StatefulSet, DaemonSet

Example:

selector:
workloadTypes:
include:
- Deployment
- StatefulSet

Or exclude specific types:

selector:
workloadTypes:
exclude:
- DaemonSet

Defines metrics collection and processing configuration.

Type: object Required: Yes

Specifies the metrics backend.

Type: string Required: Yes Enum: prometheus, metrics-server, custom

Example:

metricsConfig:
provider: prometheus

Configures metrics-server specific behavior. Only applicable when provider: metrics-server.

Type: object Required: No

Fields:

  • minSamplesRequired (integer) - Minimum number of cached samples required before computing recommendations
    • Range: 1 to 100000
    • Default: Operator-wide default

Example:

metricsConfig:
provider: metrics-server
metricsServer:
minSamplesRequired: 20

Defines the time period over which metrics are aggregated.

Type: duration Required: No Default: 24h Format: Kubernetes duration (e.g., 12h, 24h, 48h)

Example:

metricsConfig:
rollingWindow: 48h # 48 hours of data

Defines which percentile to use for recommendations.

Type: string Required: No Default: P90 Enum: P50, P90, P99

Example:

metricsConfig:
percentile: P90 # Use 90th percentile

Multiplier applied to the selected percentile value. Provides a buffer above observed usage.

Type: float64 Required: No Default: 1.2 Minimum: 1.0

Example:

metricsConfig:
safetyFactor: 1.5 # 50% buffer above P90

Calculation:

Recommendation = Percentile(Usage) × SafetyFactor

Defines min/max constraints for CPU and memory recommendations.

Type: object Required: Yes

Defines CPU resource bounds.

Type: object Required: Yes

Fields:

  • min (Quantity) - Minimum allowed CPU value (required)
  • max (Quantity) - Maximum allowed CPU value (required)

Example:

resourceBounds:
cpu:
min: "100m" # 100 millicores
max: "4000m" # 4 cores

Validation: min must be less than or equal to max

Defines memory resource bounds.

Type: object Required: Yes

Fields:

  • min (Quantity) - Minimum allowed memory value (required)
  • max (Quantity) - Maximum allowed memory value (required)

Example:

resourceBounds:
memory:
min: "128Mi" # 128 mebibytes
max: "8Gi" # 8 gibibytes

Validation: min must be less than or equal to max

Defines how resource updates are applied to workloads.

Type: object Required: Yes

Defines how resource updates are applied.

Type: string Required: No Default: webhook Enum: ssa, webhook

Values:

  • ssa - Uses Server-Side Apply for resource updates
  • webhook - Uses mutating webhooks for resource updates (GitOps-safe)

Example:

updateStrategy:
strategy: webhook

Defines when resource changes take effect. Only applicable for webhook strategy.

Type: string Required: No Default: onNextRestart Enum: immediate, onNextRestart

Values:

  • immediate - Triggers rolling restart after applying annotations
  • onNextRestart - Only applies annotations without triggering restarts

Example:

updateStrategy:
rolloutStrategy: onNextRestart

updateStrategy.allowInPlaceResize (optional)

Section titled “updateStrategy.allowInPlaceResize (optional)”

Enables in-place pod resize when supported by Kubernetes (1.27+).

Type: boolean Required: No Default: true

Example:

updateStrategy:
allowInPlaceResize: true

Enables pod recreation when in-place resize is not available.

Type: boolean Required: No Default: false

Example:

updateStrategy:
allowRecreate: false # Safer default

updateStrategy.updateRequestsOnly (optional)

Section titled “updateStrategy.updateRequestsOnly (optional)”

Controls whether to update only requests or both requests and limits.

Type: boolean Required: No Default: true

Example:

updateStrategy:
updateRequestsOnly: true # Only update requests

updateStrategy.useServerSideApply (optional)

Section titled “updateStrategy.useServerSideApply (optional)”

Enables Server-Side Apply for field-level ownership. Only applicable for SSA strategy.

Type: boolean Required: No Default: true

Example:

updateStrategy:
strategy: ssa
useServerSideApply: true

Defines how resource limits are calculated from recommendations. Only applicable when updateRequestsOnly: false.

Type: object Required: No

Fields:

  • cpuLimitMultiplier (float64) - Multiplier applied to CPU recommendation to calculate limit

    • Default: 1.0 (limit equals recommendation)
    • Range: 1.0 to 10.0
    • Example: 1.5 means limit = recommendation × 1.5
  • memoryLimitMultiplier (float64) - Multiplier applied to memory recommendation to calculate limit

    • Default: 1.1 (limit is 10% higher than recommendation)
    • Range: 1.0 to 10.0
    • Example: 1.2 means limit = recommendation × 1.2

Example:

updateStrategy:
updateRequestsOnly: false
limitConfig:
cpuLimitMultiplier: 1.5 # Limit = Request × 1.5
memoryLimitMultiplier: 1.1 # Limit = Request × 1.1

updateStrategy.allowUnsafeMemoryDecrease (optional)

Section titled “updateStrategy.allowUnsafeMemoryDecrease (optional)”

Disables memory safety checks when true. Use with caution.

Type: boolean Required: No Default: false

Behavior:

  • When false (default): OptiPod blocks memory decreases that could cause pod eviction or OOM
  • When true: OptiPod applies all memory recommendations regardless of safety concerns

Example:

updateStrategy:
allowUnsafeMemoryDecrease: false # Safe default

Warning: Setting this to true can cause pod instability. Only use in controlled environments.

updateStrategy.gradualDecreaseConfig (optional)

Section titled “updateStrategy.gradualDecreaseConfig (optional)”

⚠️ Implementation Status: This field is defined in the CRD schema and validated, but not currently implemented in the controller. Setting this configuration has no effect on actual behavior.

Configures gradual memory reduction for safer optimization. When implemented, large memory decreases would be applied incrementally over multiple reconciliations.

Type: object Required: No

Fields:

  • enabled (boolean) - Activates gradual decrease functionality

    • Default: false
    • Note: Currently has no effect
  • memoryDecreasePercentage (integer) - Maximum percentage to decrease memory per reconciliation

    • Default: 10 (10% per reconciliation)
    • Range: 1 to 50
    • Note: Currently has no effect
  • minimumDecreaseThreshold (Quantity) - Minimum decrease amount to trigger gradual reduction

    • Default: 100Mi
    • Decreases smaller than this threshold are applied immediately
    • Note: Currently has no effect
  • maximumTotalDecrease (integer) - Maximum total percentage decrease from original value

    • Default: 70 (70% maximum total decrease)
    • Range: 1 to 90
    • Prevents excessive optimization that could destabilize workloads
    • Note: Currently has no effect

Example:

updateStrategy:
gradualDecreaseConfig:
enabled: true
memoryDecreasePercentage: 10 # Max 10% per cycle
minimumDecreaseThreshold: 100Mi # Threshold to trigger
maximumTotalDecrease: 70 # Max 70% total decrease

Current Behavior: Memory decreases are applied immediately in full, subject to other safety checks.

Defines how often the policy is evaluated.

Type: duration Required: No Default: 5m Format: Kubernetes duration (e.g., 5m, 10m, 1h)

Example:

spec:
reconciliationInterval: 5m # Evaluate every 5 minutes

The status subresource provides information about the policy’s current state.

Represents the current state of the OptimizationPolicy resource using standard Kubernetes conditions.

Type: []Condition List Type: map (keyed by type)

Example:

status:
conditions:
- type: Ready
status: "True"
lastTransitionTime: "2025-01-28T10:00:00Z"
reason: PolicyActive
message: "Policy is active and processing workloads"

Count of workloads matching this policy’s selector.

Type: integer

Example:

status:
workloadsDiscovered: 10

Count of workloads successfully processed by this policy.

Type: integer

Example:

status:
workloadsProcessed: 8

Timestamp of the last reconciliation.

Type: Time

Example:

status:
lastReconciliation: "2025-01-28T10:30:00Z"

Provides breakdown of workloads by type.

Type: object

Fields:

  • deployments (integer) - Count of Deployment workloads
  • statefulSets (integer) - Count of StatefulSet workloads
  • daemonSets (integer) - Count of DaemonSet workloads

Example:

status:
workloadsByType:
deployments: 6
statefulSets: 2
daemonSets: 0
apiVersion: optipod.io/v1alpha1
kind: OptimizationPolicy
metadata:
name: production-policy
namespace: default
labels:
environment: production
spec:
# Operational mode
mode: Auto
weight: 200
# Workload selection
selector:
namespaceSelector:
matchLabels:
environment: production
workloadSelector:
matchLabels:
optimize: "true"
namespaces:
deny:
- kube-system
workloadTypes:
include:
- Deployment
- StatefulSet
# Metrics configuration
metricsConfig:
provider: prometheus
rollingWindow: 24h
percentile: P90
safetyFactor: 1.2
# Resource constraints
resourceBounds:
cpu:
min: "100m"
max: "4000m"
memory:
min: "256Mi"
max: "8Gi"
# Update strategy
updateStrategy:
strategy: webhook
rolloutStrategy: onNextRestart
allowInPlaceResize: true
allowRecreate: false
updateRequestsOnly: true
# Note: gradualDecreaseConfig not yet implemented
# Reconciliation
reconciliationInterval: 5m
status:
conditions:
- type: Ready
status: "True"
lastTransitionTime: "2025-01-28T10:00:00Z"
reason: PolicyActive
message: "Policy is active and processing workloads"
workloadsDiscovered: 10
workloadsProcessed: 8
lastReconciliation: "2025-01-28T10:30:00Z"
workloadsByType:
deployments: 6
statefulSets: 2
daemonSets: 0

The OptimizationPolicy CRD enforces the following validation rules:

  • spec.mode - Must be one of: Auto, Recommend, Disabled
  • spec.selector - At least one selector type must be specified
  • spec.metricsConfig.provider - Must be specified
  • spec.resourceBounds.cpu.min - Must be greater than zero
  • spec.resourceBounds.cpu.max - Must be greater than zero
  • spec.resourceBounds.memory.min - Must be greater than zero
  • spec.resourceBounds.memory.max - Must be greater than zero
  • spec.weight - Must be between 1 and 1000
  • spec.metricsConfig.safetyFactor - Must be >= 1.0
  • spec.metricsConfig.metricsServer.minSamplesRequired - Must be >= 1
  • spec.resourceBounds.cpu.min - Must be <= spec.resourceBounds.cpu.max
  • spec.resourceBounds.memory.min - Must be <= spec.resourceBounds.memory.max
  • spec.updateStrategy.limitConfig.cpuLimitMultiplier - Must be between 1.0 and 10.0
  • spec.updateStrategy.limitConfig.memoryLimitMultiplier - Must be between 1.0 and 10.0
  • spec.updateStrategy.gradualDecreaseConfig.memoryDecreasePercentage - Must be between 1 and 50
  • spec.updateStrategy.gradualDecreaseConfig.maximumTotalDecrease - Must be between 1 and 90
  • matchExpressions[].key - Required for each expression
  • matchExpressions[].operator - Must be one of: In, NotIn, Exists, DoesNotExist
  • matchExpressions[].values - Required for In and NotIn operators
  • matchExpressions[].values - Must not be specified for Exists and DoesNotExist operators
  • All workload types must be one of: Deployment, StatefulSet, DaemonSet
Terminal window
kubectl apply -f policy.yaml
Terminal window
kubectl get optimizationpolicies
# or use short name
kubectl get optpol
Terminal window
kubectl describe optimizationpolicy production-policy
Terminal window
kubectl get optimizationpolicy production-policy -o yaml
Terminal window
kubectl delete optimizationpolicy production-policy
Terminal window
kubectl get optimizationpolicies --watch