feat(vpa): add MemoryPerCPURatio alpha feature gate

This commit is contained in:
Jérémy Spriet 2025-08-19 15:43:59 +02:00 committed by jeremy.spriet
parent 0a85516c69
commit 691cb27872
5 changed files with 66 additions and 4 deletions

View File

@ -7,6 +7,7 @@
- [CPU Recommendation Rounding](#cpu-recommendation-rounding)
- [Memory Recommendation Rounding](#memory-recommendation-rounding)
- [In-Place Updates](#in-place-updates-inplaceorrecreate)
- [MemoryPerCPU](#memorypercpu-memorypercpuratio)
## Limits control
@ -153,3 +154,52 @@ VPA provides metrics to track in-place update operations:
* `vpa_vpas_with_in_place_updatable_pods_total`: Number of VPAs with pods eligible for in-place updates
* `vpa_vpas_with_in_place_updated_pods_total`: Number of VPAs with successfully in-place updated pods
* `vpa_updater_failed_in_place_update_attempts_total`: Number of failed attempts to update pods in-place.
## MemoryPerCPU (`MemoryPerCPURatio`)
> [!WARNING]
> FEATURE STATE: VPA v1.5.0 [alpha]
VPA can enforce a fixed memory-per-CPU ratio in its recommendations.
When enabled, the recommender adjusts CPU or memory so that:
```
memory_bytes = cpu_cores * memoryPerCPU
```
This applies to Target, LowerBound, UpperBound, and UncappedTarget recommendations.
### Usage
Enable the feature on the recommender with:
```bash
--feature-gates=MemoryPerCPURatio=true
```
Then configure the ratio in your VPA object using the memoryPerCPU field, for example:
```yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-app
spec:
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: 1
memory: 4Gi
maxAllowed:
cpu: 4
memory: 16Gi
controlledResources: ["cpu", "memory"]
controlledValues: RequestsAndLimits
memoryPerCPU: "4Gi"
```
### Behavior
* If both CPU and Memory are controlled, VPA enforces the ratio.
### Limitations
* If `minAllowed` or `maxAllowed` constraints conflict with the ratio, the constraints take precedence and the ratio may not be respected.

View File

@ -14,7 +14,7 @@ This document is auto-generated from the flag definitions in the VPA admission-c
| `address` | string | ":8944" | The address to expose Prometheus metrics. |
| `alsologtostderr` | | | log to standard error as well as files (no effect when -logtostderr=true) |
| `client-ca-file` | string | "/etc/tls-certs/caCert.pem" | Path to CA PEM file. |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>InPlaceOrRecreate=true\|false (BETA - default=true) |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>InPlaceOrRecreate=true\|false (BETA - default=true)<br>MemoryPerCPURatio=true\|false (ALPHA - default=false) |
| `ignored-vpa-object-namespaces` | string | | A comma-separated list of namespaces to ignore when searching for VPA objects. Leave empty to avoid ignoring any namespaces. These namespaces will not be cleaned by the garbage collector. |
| `kube-api-burst` | float | 100 | QPS burst limit when making requests to Kubernetes apiserver |
| `kube-api-qps` | float | 50 | QPS limit when making requests to Kubernetes apiserver |
@ -68,7 +68,7 @@ This document is auto-generated from the flag definitions in the VPA recommender
| `cpu-integer-post-processor-enabled` | | | Enable the cpu-integer recommendation post processor. The post processor will round up CPU recommendations to a whole CPU for pods which were opted in by setting an appropriate label on VPA object (experimental) |
| `external-metrics-cpu-metric` | string | | ALPHA. Metric to use with external metrics provider for CPU usage. |
| `external-metrics-memory-metric` | string | | ALPHA. Metric to use with external metrics provider for memory usage. |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>InPlaceOrRecreate=true\|false (BETA - default=true) |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>InPlaceOrRecreate=true\|false (BETA - default=true)<br>MemoryPerCPURatio=true\|false (ALPHA - default=false) |
| `history-length` | string | "8d" | How much time back prometheus have to be queried to get historical metrics |
| `history-resolution` | string | "1h" | Resolution at which Prometheus is queried for historical metrics |
| `humanize-memory` | | | DEPRECATED: Convert memory values in recommendations to the highest appropriate SI unit with up to 2 decimal places for better readability. This flag is deprecated and will be removed in a future version. Use --round-memory-bytes instead. |
@ -144,7 +144,7 @@ This document is auto-generated from the flag definitions in the VPA updater cod
| `eviction-rate-burst` | int | 1 | Burst of pods that can be evicted. |
| `eviction-rate-limit` | float | | Number of pods that can be evicted per seconds. A rate limit set to 0 or -1 will disable<br>the rate limiter. (default -1) |
| `eviction-tolerance` | float | 0.5 | Fraction of replica count that can be evicted for update, if more than one pod can be evicted. |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>InPlaceOrRecreate=true\|false (BETA - default=true) |
| `feature-gates` | mapStringBool | | A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:<br>AllAlpha=true\|false (ALPHA - default=false)<br>AllBeta=true\|false (BETA - default=false)<br>InPlaceOrRecreate=true\|false (BETA - default=true)<br>MemoryPerCPURatio=true\|false (ALPHA - default=false) |
| `ignored-vpa-object-namespaces` | string | | A comma-separated list of namespaces to ignore when searching for VPA objects. Leave empty to avoid ignoring any namespaces. These namespaces will not be cleaned by the garbage collector. |
| `in-recommendation-bounds-eviction-lifetime-threshold` | | 12h0m0s | duration Pods that live for at least that long can be evicted even if their request is within the [MinRecommended...MaxRecommended] range |
| `kube-api-burst` | float | 100 | QPS burst limit when making requests to Kubernetes apiserver |

View File

@ -40,6 +40,12 @@ const (
// In each feature gate description, you must specify "components".
// The feature must be enabled by the --feature-gates argument on each listed component.
// alpha: v1.5.0
// components: recommender
// MemoryPerCPURatio enables enforcing a fixed memory-per-CPU ratio in recommendations.
MemoryPerCPURatio featuregate.Feature = "MemoryPerCPURatio"
// alpha: v1.4.0
// beta: v1.5.0

View File

@ -27,6 +27,9 @@ import (
// Entries are alphabetized.
var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.VersionedSpecs{
MemoryPerCPURatio: {
{Version: version.MustParse("1.5"), Default: false, PreRelease: featuregate.Alpha},
},
InPlaceOrRecreate: {
{Version: version.MustParse("1.4"), Default: false, PreRelease: featuregate.Alpha},
{Version: version.MustParse("1.5"), Default: true, PreRelease: featuregate.Beta},

View File

@ -268,7 +268,10 @@ func run(ctx context.Context, healthCheck *metrics.HealthCheck, commonFlag *comm
postProcessors = append(postProcessors, &routines.IntegerCPUPostProcessor{})
}
postProcessors = append(postProcessors, &routines.MemoryPerCPUPostProcessor{})
if features.Enabled(features.MemoryPerCPURatio) {
postProcessors = append(postProcessors, &routines.MemoryPerCPUPostProcessor{})
}
globalMaxAllowed := initGlobalMaxAllowed()
// CappingPostProcessor, should always come in the last position for post-processing
postProcessors = append(postProcessors, routines.NewCappingRecommendationProcessor(globalMaxAllowed))