Files
kubeconform/crdSchemas/master-standalone/attunedefaults-stable-v1alpha1.json
T
2026-08-18 19:18:31 +01:00

764 lines
42 KiB
JSON

{
"description": "AttuneDefaults is the Schema for the attunedefaults API.\nIt defines cluster-scoped default values for AttunePolicy resources.",
"properties": {
"apiVersion": {
"description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
"type": "string"
},
"kind": {
"description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
"type": "string"
},
"metadata": {
"type": "object"
},
"spec": {
"description": "AttuneDefaultsSpec defines cluster-scoped default values for AttunePolicy resources.",
"properties": {
"costPricing": {
"description": "CostPricing configures the per-unit pricing used to compute\nEstimatedMonthlySavings. If omitted, defaults to standard\non-demand Linux pricing ($0.031/vCPU-hour, $0.004/GiB-hour).",
"properties": {
"cpuPerCoreHour": {
"description": "CPUPerCoreHour is the cost per vCPU-hour (e.g. \"0.031\").\nDefaults to 0.031 if not specified.",
"type": "string"
},
"memoryPerGiBHour": {
"description": "MemoryPerGiBHour is the cost per GiB-hour (e.g. \"0.004\").\nDefaults to 0.004 if not specified.",
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"cpu": {
"description": "CPU configures default CPU resource recommendation parameters.",
"properties": {
"allowDecrease": {
"description": "AllowDecrease controls whether the resource value can be decreased.\nFor CPU: nil defaults to true (decreases allowed, throttle detected by safety monitor).\nFor memory: nil defaults to false (decreases blocked to prevent OOMKill).",
"type": "boolean"
},
"burstSensitivity": {
"description": "BurstSensitivity controls how much burst detection inflates the\nrecommendation. Expressed as a decimal string multiplied by\nlog2(burstMagnitude). Default \"0.1\" gives ~20% boost for magnitude 4,\n~30% for 8, ~40% for 16. Set \"0\" to disable burst boost entirely\n(e.g. for batch jobs). Must be >= 0, max 1.0.",
"type": "string"
},
"controlledValues": {
"description": "ControlledValues specifies which resource values to manage.\n\"RequestsOnly\" (default) adjusts only requests, leaving limits unchanged.\n\"RequestsAndLimits\" adjusts both requests and limits in lockstep.\nFor Guaranteed-QoS pods (where requests equal limits), use\n\"RequestsAndLimits\" or resizes will be skipped to preserve QoS class.",
"enum": [
"RequestsOnly",
"RequestsAndLimits"
],
"type": "string"
},
"decreaseUsageMarginPercent": {
"description": "DecreaseUsageMarginPercent is the minimum headroom above recent memory\nusage required when decreasing memory limits (client-side pre-check).\nThe target limit must be at least usage * (1 + margin/100). Defaults to\n10. Only applied on the memory ResourceConfig when a limit decrease is\nattempted; ignored for CPU. Set 0 to require limit strictly above usage.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"type": "integer"
},
"maxAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxAllowed is the maximum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxChangePercent": {
"description": "MaxChangePercent is the maximum allowed change percentage per\nreconcile cycle for this resource (both directions). Limits how\naggressively the recommendation can deviate from the current value\nin a single step, forcing gradual convergence. Overridden by\nMaxIncreasePercent/MaxDecreasePercent if those are set.\nDefaults to 50 for CPU, 30 for memory.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxDecreasePercent": {
"description": "MaxDecreasePercent is the maximum allowed decrease percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for downward\nchanges. Memory decreases are riskier (OOM), so a lower cap is\nrecommended. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxIncreasePercent": {
"description": "MaxIncreasePercent is the maximum allowed increase percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for upward\nchanges. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"memoryFromCpuRatio": {
"description": "MemoryFromCPURatio derives memory recommendations from CPU recommendations\nusing a fixed ratio, instead of using Prometheus memory metrics. Useful for\nJVM, Go, and .NET workloads where heap scales linearly with CPU allocation\nand Prometheus memory metrics are unreliable (JVM reserves heap upfront,\nGo GC targets a fixed percentage of available memory).\nExample: \"2.0\" means memory = 2x the CPU recommendation in bytes\n(e.g., 500m CPU -> 1Gi memory). The derived value still passes through\nminAllowed, maxAllowed, and maxChangePercent bounds.\nOnly valid on the memory ResourceConfig; ignored on CPU.",
"type": "string"
},
"minAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MinAllowed is the minimum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"overhead": {
"description": "Overhead is the percentage of additional resources added on top of the\npercentile recommendation. Expressed as a string (e.g. \"20\" means 20%\nextra headroom above the target percentile). Must be >= 0, max 900.\nDefaults to \"20\" for CPU and \"30\" for memory.",
"pattern": "^([0-9]+(\\.[0-9]+)?)?$",
"type": "string"
},
"percentile": {
"description": "Percentile is the usage percentile to target for recommendations.\nSupported values: 50, 90, 95, 99. Omit or set to 0 to use the default\n(95 for CPU, 99 for memory).",
"enum": [
0,
50,
90,
95,
99
],
"format": "int32",
"type": "integer"
},
"startupBoost": {
"description": "StartupBoost temporarily increases CPU requests for newly created or\nrestarted pods to accelerate JVM/.NET class loading, JIT compilation,\nand cache warming. After the duration expires (or the container reaches\nReady), the CPU is reduced to the steady-state recommendation.\nOnly applies to CPU resources.",
"properties": {
"duration": {
"description": "Duration is the maximum time the boost remains active after pod\ncreation or container restart. The boost is removed when the\ncontainer reaches Ready or this duration expires, whichever comes first.\nMust be >= 10s and <= 1h.",
"type": "string"
},
"multiplier": {
"description": "Multiplier scales the recommended CPU request during startup.\nFor example, \"3.0\" means 3x the steady-state recommendation.\nMust be > 1.0 and <= 10.0.",
"type": "string"
}
},
"required": [
"duration",
"multiplier"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"excludeKnownSidecars": {
"description": "ExcludeKnownSidecars, when true (the default when unset on both\ndefaults and policy), automatically skips well-known mesh and\nsidecar container names. Set to false cluster-wide to restore\nexclude-only-via-excludedContainers behavior for policies that\ndo not set the field themselves.",
"type": "boolean"
},
"memory": {
"description": "Memory configures default memory resource recommendation parameters.",
"properties": {
"allowDecrease": {
"description": "AllowDecrease controls whether the resource value can be decreased.\nFor CPU: nil defaults to true (decreases allowed, throttle detected by safety monitor).\nFor memory: nil defaults to false (decreases blocked to prevent OOMKill).",
"type": "boolean"
},
"burstSensitivity": {
"description": "BurstSensitivity controls how much burst detection inflates the\nrecommendation. Expressed as a decimal string multiplied by\nlog2(burstMagnitude). Default \"0.1\" gives ~20% boost for magnitude 4,\n~30% for 8, ~40% for 16. Set \"0\" to disable burst boost entirely\n(e.g. for batch jobs). Must be >= 0, max 1.0.",
"type": "string"
},
"controlledValues": {
"description": "ControlledValues specifies which resource values to manage.\n\"RequestsOnly\" (default) adjusts only requests, leaving limits unchanged.\n\"RequestsAndLimits\" adjusts both requests and limits in lockstep.\nFor Guaranteed-QoS pods (where requests equal limits), use\n\"RequestsAndLimits\" or resizes will be skipped to preserve QoS class.",
"enum": [
"RequestsOnly",
"RequestsAndLimits"
],
"type": "string"
},
"decreaseUsageMarginPercent": {
"description": "DecreaseUsageMarginPercent is the minimum headroom above recent memory\nusage required when decreasing memory limits (client-side pre-check).\nThe target limit must be at least usage * (1 + margin/100). Defaults to\n10. Only applied on the memory ResourceConfig when a limit decrease is\nattempted; ignored for CPU. Set 0 to require limit strictly above usage.",
"format": "int32",
"maximum": 100,
"minimum": 0,
"type": "integer"
},
"maxAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxAllowed is the maximum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxChangePercent": {
"description": "MaxChangePercent is the maximum allowed change percentage per\nreconcile cycle for this resource (both directions). Limits how\naggressively the recommendation can deviate from the current value\nin a single step, forcing gradual convergence. Overridden by\nMaxIncreasePercent/MaxDecreasePercent if those are set.\nDefaults to 50 for CPU, 30 for memory.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxDecreasePercent": {
"description": "MaxDecreasePercent is the maximum allowed decrease percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for downward\nchanges. Memory decreases are riskier (OOM), so a lower cap is\nrecommended. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"maxIncreasePercent": {
"description": "MaxIncreasePercent is the maximum allowed increase percentage per\nreconcile cycle. Takes precedence over MaxChangePercent for upward\nchanges. Defaults to MaxChangePercent if not set.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"memoryFromCpuRatio": {
"description": "MemoryFromCPURatio derives memory recommendations from CPU recommendations\nusing a fixed ratio, instead of using Prometheus memory metrics. Useful for\nJVM, Go, and .NET workloads where heap scales linearly with CPU allocation\nand Prometheus memory metrics are unreliable (JVM reserves heap upfront,\nGo GC targets a fixed percentage of available memory).\nExample: \"2.0\" means memory = 2x the CPU recommendation in bytes\n(e.g., 500m CPU -> 1Gi memory). The derived value still passes through\nminAllowed, maxAllowed, and maxChangePercent bounds.\nOnly valid on the memory ResourceConfig; ignored on CPU.",
"type": "string"
},
"minAllowed": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MinAllowed is the minimum allowed resource value.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"overhead": {
"description": "Overhead is the percentage of additional resources added on top of the\npercentile recommendation. Expressed as a string (e.g. \"20\" means 20%\nextra headroom above the target percentile). Must be >= 0, max 900.\nDefaults to \"20\" for CPU and \"30\" for memory.",
"pattern": "^([0-9]+(\\.[0-9]+)?)?$",
"type": "string"
},
"percentile": {
"description": "Percentile is the usage percentile to target for recommendations.\nSupported values: 50, 90, 95, 99. Omit or set to 0 to use the default\n(95 for CPU, 99 for memory).",
"enum": [
0,
50,
90,
95,
99
],
"format": "int32",
"type": "integer"
},
"startupBoost": {
"description": "StartupBoost temporarily increases CPU requests for newly created or\nrestarted pods to accelerate JVM/.NET class loading, JIT compilation,\nand cache warming. After the duration expires (or the container reaches\nReady), the CPU is reduced to the steady-state recommendation.\nOnly applies to CPU resources.",
"properties": {
"duration": {
"description": "Duration is the maximum time the boost remains active after pod\ncreation or container restart. The boost is removed when the\ncontainer reaches Ready or this duration expires, whichever comes first.\nMust be >= 10s and <= 1h.",
"type": "string"
},
"multiplier": {
"description": "Multiplier scales the recommended CPU request during startup.\nFor example, \"3.0\" means 3x the steady-state recommendation.\nMust be > 1.0 and <= 10.0.",
"type": "string"
}
},
"required": [
"duration",
"multiplier"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"metricsSource": {
"description": "MetricsSource configures default metrics source settings.",
"properties": {
"cloudwatch": {
"description": "CloudWatch configures an Amazon CloudWatch Container Insights metrics source.",
"properties": {
"clusterName": {
"description": "ClusterName is the EKS cluster name for Container Insights metrics.\nRequired for metric filtering.",
"type": "string"
},
"region": {
"description": "Region is the AWS region (e.g. \"us-east-1\"). Required.",
"type": "string"
},
"roleArn": {
"description": "RoleARN is an optional IAM role ARN to assume for cross-account access.\nIf not set, uses the pod's service account IAM role (IRSA/Pod Identity).",
"type": "string"
}
},
"required": [
"clusterName",
"region"
],
"type": "object",
"additionalProperties": false
},
"cpuRecordingMetric": {
"description": "CPURecordingMetric is an optional pre-aggregated Prometheus metric name\nused instead of rate(container_cpu_usage_seconds_total). Labels must include\nnamespace, pod, and container. When set, the operator does not wrap the\nmetric in rate(). Pair with MemoryRecordingMetric for a recording-rules-only path.",
"type": "string"
},
"datadog": {
"description": "Datadog configures a Datadog metrics source.",
"properties": {
"apiKeySecretRef": {
"description": "APIKeySecretRef references a Secret containing the Datadog API key.\nThe Secret must contain an \"api-key\" key and optionally an \"app-key\" key.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
},
"site": {
"default": "datadoghq.com",
"description": "Site is the Datadog site (e.g. \"datadoghq.com\", \"datadoghq.eu\", \"us5.datadoghq.com\").\nDefaults to \"datadoghq.com\".",
"type": "string"
}
},
"required": [
"apiKeySecretRef"
],
"type": "object",
"additionalProperties": false
},
"historyWindow": {
"description": "HistoryWindow is the time window for historical metrics data.\nDefaults to 7d (168h) if not specified.",
"type": "string"
},
"memoryRecordingMetric": {
"description": "MemoryRecordingMetric is an optional pre-aggregated Prometheus metric name\nused instead of container_memory_working_set_bytes. Same label requirements\nas CPURecordingMetric.",
"type": "string"
},
"minimumDataPoints": {
"description": "MinimumDataPoints is the minimum number of data points required\nbefore generating recommendations. Minimum 1, default 48 samples.\nWith the default queryStep of 5m, 48 samples is about 4 hours of data.\nDefaults to 48 if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"format": "int32",
"minimum": 1,
"type": "integer"
},
"podAggregation": {
"description": "PodAggregation controls how multi-pod series are reduced in Prometheus\nrange queries for this policy.\n Max (default): max by (container) \u2014 size for the busiest pod; O(containers) series.\n Avg: avg by (container) across pods.\n None: no aggregation (one series per pod; expensive for high replica counts).\nDatadog and CloudWatch already group by container; this field applies to Prometheus.",
"enum": [
"Max",
"Avg",
"None"
],
"type": "string"
},
"prometheus": {
"description": "Prometheus configures a Prometheus metrics source.",
"properties": {
"address": {
"description": "Address is the URL of the Prometheus-compatible query endpoint.",
"type": "string"
},
"bearerTokenSecret": {
"description": "BearerTokenSecret references a Kubernetes Secret containing a bearer\ntoken for authenticating with managed Prometheus services.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
},
"headers": {
"additionalProperties": {
"type": "string"
},
"description": "Headers are custom HTTP headers added to every query request.\nUse for non-secret tenant or routing headers (e.g. \"X-Scope-OrgID\"\nfor Mimir). Do not put credentials here; use BearerTokenSecret for\nauthentication tokens.",
"type": "object"
},
"queryParameters": {
"additionalProperties": {
"type": "string"
},
"description": "QueryParameters are appended to every query request URL.\nUse for backend-specific settings such as Thanos deduplication\n(e.g. {\"dedup\": \"true\", \"partial_response\": \"true\"}). Reserved\nquery keys controlled by the operator (`query`, `start`, `end`, `step`,\n`time`, `timeout`) are rejected.",
"type": "object"
},
"tls": {
"description": "TLS configures TLS settings for the connection.",
"properties": {
"insecureSkipVerify": {
"description": "InsecureSkipVerify disables TLS certificate verification.\nUse only for self-signed certificates in development.",
"type": "boolean"
}
},
"type": "object",
"additionalProperties": false
}
},
"required": [
"address"
],
"type": "object",
"additionalProperties": false
},
"queryStep": {
"description": "QueryStep is the step interval for Prometheus range queries and ETA\ncalculations. Should match your Prometheus scrape interval for\naccurate time estimates. Minimum 10s, maximum 1h. Default 5m.",
"type": "string"
},
"rateWindow": {
"description": "RateWindow is the window used in the PromQL rate() function for CPU\nqueries. Defaults to queryStep if not set. Must be >= 30s and <= historyWindow.\nAdvanced users may set this independently to control CPU rate smoothing\n(e.g. a short rateWindow for responsive tracking with a longer queryStep).",
"type": "string"
},
"vpa": {
"description": "VPA configures consumption of existing VerticalPodAutoscaler recommendations.",
"properties": {
"name": {
"description": "Name is the name of the VerticalPodAutoscaler object.",
"type": "string"
},
"namespace": {
"description": "Namespace is the namespace of the VPA. Defaults to the policy's namespace.",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"updateStrategy": {
"description": "UpdateStrategy configures default update strategy settings.",
"properties": {
"autoRevert": {
"description": "AutoRevert automatically reverts changes if degradation is detected.\nDefaults to true if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"type": "boolean"
},
"canary": {
"description": "Canary configures canary rollout behavior when Type is Canary.",
"properties": {
"autoPromote": {
"description": "AutoPromote controls whether the operator automatically promotes the\nresize to all pods after the observation period passes without safety\nviolations. When false (default), the user must manually switch the\nmode to Auto to resize the remaining pods.",
"type": "boolean"
},
"observationPeriod": {
"description": "ObservationPeriod is how long to observe canary pods before proceeding.",
"type": "string"
},
"percentage": {
"description": "Percentage is the percentage of pods to resize first.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
}
},
"required": [
"observationPeriod",
"percentage"
],
"type": "object",
"additionalProperties": false
},
"cooldown": {
"description": "Cooldown is the minimum time between successive resize operations.\nDefaults to 1h if not specified.",
"type": "string"
},
"export": {
"description": "Export configures how recommendations are exported for external\nconsumption (e.g. GitOps workflows with ArgoCD or Flux).",
"properties": {
"configMap": {
"description": "ConfigMap enables exporting recommendations to ConfigMaps.",
"type": "boolean"
},
"pullRequest": {
"description": "PullRequest enables opt-in GitOps PR automation (default off).\nRequires a token Secret and repository identity. Never logs the token.",
"properties": {
"apiUrl": {
"description": "APIURL overrides the API base URL (Enterprise GitHub or self-hosted GitLab).\nDefaults: https://api.github.com or https://gitlab.com/api/v4.",
"type": "string"
},
"baseBranch": {
"description": "BaseBranch is the PR target branch. Defaults to \"main\".",
"type": "string"
},
"cooldown": {
"description": "Cooldown is the minimum time between PR create/update attempts for this\npolicy. Defaults to 24h.",
"type": "string"
},
"dryRun": {
"description": "DryRun logs the intended PR and updates status without calling the\nremote API. Useful for CI and first enablement.",
"type": "boolean"
},
"enabled": {
"description": "Enabled turns on PR automation. Default false.",
"type": "boolean"
},
"labels": {
"description": "Labels are applied to the pull request when supported by the provider.",
"items": {
"type": "string"
},
"maxItems": 20,
"type": "array"
},
"minChangePercent": {
"description": "MinChangePercent is the minimum absolute percent change (per container\nresource vs template) required to open or update a PR. Defaults to 10.",
"format": "int32",
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"provider": {
"description": "Provider is \"github\" or \"gitlab\". Default \"github\".",
"enum": [
"github",
"gitlab"
],
"type": "string"
},
"repository": {
"description": "Repository is \"owner/name\" (GitHub) or \"group/project\" (GitLab path).\nRequired when Enabled is true.",
"type": "string"
},
"tokenSecretRef": {
"description": "TokenSecretRef references a Secret key holding a PAT / project token.\nGitHub: repo contents + pull requests. GitLab: api scope on the project.\nRequired when Enabled is true.",
"properties": {
"key": {
"description": "Key within the Secret.",
"type": "string"
},
"name": {
"description": "Name of the Secret.",
"type": "string"
}
},
"required": [
"key",
"name"
],
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
},
"includeExplanationsInStatus": {
"description": "IncludeExplanationsInStatus controls whether recommendation explanation\nchains are written to status. Set to false on large policies to shrink\nCR size. Default: true.",
"type": "boolean"
},
"initialSizing": {
"description": "InitialSizing enables a mutating admission webhook that sets resource\nrequests/limits on new pods at creation time, based on existing\nrecommendations. This eliminates the \"deploy with bad defaults, wait\nfor first reconcile\" gap. Requires the namespace label\nattune.io/initial-sizing=enabled. Defaults to false.",
"type": "boolean"
},
"maxConcurrentResizes": {
"default": 1,
"description": "MaxConcurrentResizes is the maximum number of pods to resize\nconcurrently within a single reconcile cycle. Default: 1 (serial).",
"format": "int32",
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"maxStatusRecommendations": {
"description": "MaxStatusRecommendations caps how many workload recommendations are\nwritten to status.recommendations. Resizes still use the full in-memory\nset. When the cap is hit, entries with the largest absolute CPU+memory\nrequest change are kept. Default: 100 (operator may override via flag).",
"format": "int32",
"maximum": 500,
"minimum": 1,
"type": "integer"
},
"maxTotalCpuIncrease": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxTotalCPUIncrease is the maximum aggregate CPU increase allowed\nacross all pods in a single reconcile cycle (e.g. \"2000m\", \"4\").\nOnce exhausted, remaining pods are deferred to the next cycle.\nDecreases do not consume budget. Default: unlimited.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"maxTotalMemoryIncrease": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"description": "MaxTotalMemoryIncrease is the maximum aggregate memory increase\nallowed across all pods in a single reconcile cycle (e.g. \"4Gi\").\nOnce exhausted, remaining pods are deferred to the next cycle.\nDecreases do not consume budget. Default: unlimited.",
"pattern": "^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$",
"x-kubernetes-int-or-string": true
},
"resizeMethod": {
"description": "ResizeMethod controls what happens when an in-place resize fails.\n InPlaceOnly (default): skip the pod and retry next cycle.\n InPlaceOrRecreate: fall back to pod eviction if in-place resize\n fails or is marked Infeasible by kubelet. The owning controller\n recreates the pod with updated resources. Evictions respect\n PodDisruptionBudgets and never evict the last replica.\nDefaults to InPlaceOnly if not set (applied by the controller so that\nAttuneDefaults cluster configuration can override it).",
"enum": [
"InPlaceOnly",
"InPlaceOrRecreate"
],
"type": "string"
},
"safetyObservationPeriod": {
"description": "SafetyObservationPeriod is how long to observe a pod after resize before\nconcluding the resize is safe. Applies to all modes (Auto, OneShot, Canary).\nTakes precedence over canary.observationPeriod when set. Must be >= 1m.\nDefaults to 5m if neither this nor canary.observationPeriod is set.",
"type": "string"
},
"schedule": {
"description": "Schedule restricts when resize operations can occur. Recommendations\nare always computed; only resize execution is gated. If omitted,\nresizes can occur at any time (current behavior).",
"properties": {
"daysOfWeek": {
"description": "DaysOfWeek restricts resizes to specific days. Values: Monday through Sunday.\nIf omitted, all days are allowed.",
"items": {
"enum": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
],
"type": "string"
},
"type": "array"
},
"timezone": {
"default": "UTC",
"description": "Timezone for interpreting window start/end times. Must be a valid\nIANA timezone name (e.g. \"America/New_York\"). Default: \"UTC\".",
"type": "string"
},
"windows": {
"description": "Windows defines time-of-day ranges when resizes are allowed.\nIf multiple windows are specified, resizes are allowed during any of them.",
"items": {
"description": "TimeWindow defines a daily time range.",
"properties": {
"end": {
"description": "End time in HH:MM format (24-hour). If end < start, the window\nwraps past midnight (e.g. start=22:00, end=06:00).",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"type": "string"
},
"start": {
"description": "Start time in HH:MM format (24-hour).",
"pattern": "^([01]\\d|2[0-3]):[0-5]\\d$",
"type": "string"
}
},
"required": [
"end",
"start"
],
"type": "object",
"additionalProperties": false
},
"type": "array"
}
},
"type": "object",
"additionalProperties": false
},
"sloGuardrails": {
"description": "SLOGuardrails defines application-level SLO metrics to check after\na resize. If any metric breaches its threshold during the safety\nobservation period, the resize is automatically reverted.\nRequires a Prometheus-compatible metrics source.",
"items": {
"description": "SLOGuardrail defines an application-level metric that is checked after\na resize to detect degradation. If the metric breaches the threshold,\nthe safety monitor triggers an automatic revert.",
"properties": {
"comparison": {
"default": "above",
"description": "Comparison is \"above\" or \"below\". \"above\" reverts when value > threshold.",
"enum": [
"above",
"below"
],
"type": "string"
},
"evaluationWindow": {
"description": "EvaluationWindow is how long after resize to check. Defaults to 5m.",
"type": "string"
},
"name": {
"description": "Name identifies this guardrail for logging and status reporting.",
"type": "string"
},
"query": {
"description": "Query is a PromQL query that returns a scalar value.\nTemplate variables: {{ .Namespace }}, {{ .WorkloadName }}, {{ .PodName }}",
"type": "string"
},
"threshold": {
"description": "Threshold is the value that triggers a revert.",
"type": "string"
}
},
"required": [
"name",
"query",
"threshold"
],
"type": "object",
"additionalProperties": false
},
"maxItems": 10,
"type": "array"
},
"templatePersistence": {
"description": "TemplatePersistence optionally writes recommended resources into the\nworkload pod template (Deployment/StatefulSet) so new pods start\ncorrectly sized. Default off. Do not enable under unmanaged GitOps\nsync without adopting recommendations in Git; prefer export or\ninitialSizing in that case.",
"properties": {
"enabled": {
"description": "Enabled turns on template persistence. When false or unset, templates\nare never mutated.",
"type": "boolean"
},
"when": {
"description": "When selects the trigger. Defaults to AfterSuccessfulResize when\nEnabled is true and When is empty.",
"enum": [
"AfterSuccessfulResize",
"OnRecommendation"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
},
"type": {
"description": "Mode determines the update behavior, graduated from safe to automated:\n Recommend: collects metrics and writes recommendations to status, no pod changes.\n OneShot: resizes one pod per reconcile cycle.\n Canary: resizes a percentage of pods first, then the rest after observation.\n Auto: resizes all eligible pods each cycle.\n Observe: collects metrics and tracks data points but does not surface recommendations or savings.\nStart with Recommend in production and promote after reviewing status.\nDefaults to Recommend if not set (applied by the controller, not the webhook,\nso that AttuneDefaults cluster configuration can override it).",
"enum": [
"Observe",
"Recommend",
"OneShot",
"Canary",
"Auto"
],
"type": "string"
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object",
"additionalProperties": false
}
},
"type": "object"
}