Merge 35b9ab3f72 into a9292351c3
				
					
				
			This commit is contained in:
		
						commit
						64950d070c
					
				|  | @ -0,0 +1,162 @@ | |||
| # AEP-8459: MemoryPerCPU | ||||
| 
 | ||||
| <!-- toc --> | ||||
| - [Summary](#summary) | ||||
| - [Motivation](#motivation) | ||||
|   - [Goals](#goals) | ||||
|   - [Non-Goals](#non-goals) | ||||
| - [Proposal](#proposal) | ||||
| - [Design Details](#design-details) | ||||
|   - [API Changes](#api-changes) | ||||
|   - [Behavior](#behavior) | ||||
|   - [Feature Enablement and Rollback](#feature-enablement-and-rollback) | ||||
|     - [How can this feature be enabled / disabled in a live cluster?](#how-can-this-feature-be-enabled--disabled-in-a-live-cluster) | ||||
|   - [Kubernetes Version Compatibility](#kubernetes-version-compatibility) | ||||
|   - [Validation](#validation) | ||||
|   - [Test Plan](#test-plan) | ||||
| - [Implementation History](#implementation-history) | ||||
| - [Future Work](#future-work) | ||||
| - [Alternatives](#alternatives) | ||||
|   <!-- /toc --> | ||||
| 
 | ||||
| ## Summary | ||||
| 
 | ||||
| This AEP proposes a new feature to allow enforcing a fixed memory-per-CPU ratio (`memoryPerCPU`) in Vertical Pod Autoscaler (VPA) recommendations.   | ||||
| The feature is controlled by a new alpha feature gate `MemoryPerCPURatio` (default off). | ||||
| 
 | ||||
| ## Motivation | ||||
| 
 | ||||
| Many workloads scale their memory requirements proportionally to CPU, but today VPA generates independent CPU and memory recommendations. This can lead to skewed configurations — for example, too much memory for a small CPU allocation, or too little memory for a high CPU allocation. | ||||
| 
 | ||||
| The `memoryPerCPU` field addresses this by enforcing a predictable CPU-to-memory ratio in recommendations. This reduces the risk of misconfiguration, ensures consistency, and simplifies tuning for workloads where CPU and memory usage are tightly coupled. | ||||
| 
 | ||||
| This feature is particularly useful in environments where services are billed primarily on CPU with a fixed CPU-to-memory ratio. In such cases, it allows VPA to be used for automatic vertical scaling while preserving the existing billing model and guarantees to customers. | ||||
| 
 | ||||
| ### Goals | ||||
| 
 | ||||
| * Allow users to specify a `memoryPerCPU` ratio in `VerticalPodAutoscaler` objects.   | ||||
| * Ensure VPA recommendations respect the ratio across Target, LowerBound, UpperBound, and UncappedTarget.   | ||||
| * Provide a feature gate to enable/disable the feature cluster-wide. | ||||
| 
 | ||||
| ### Non-Goals | ||||
| 
 | ||||
| * Redesign of the VPA recommender algorithm beyond enforcing the ratio.   | ||||
| * Supporting multiple ratio policies per container (only one `memoryPerCPU` is supported).   | ||||
| * Retroactive migration of existing VPAs without explicit user opt-in. | ||||
| 
 | ||||
| ## Proposal | ||||
| 
 | ||||
| Extend `ContainerResourcePolicy` with a new optional field: | ||||
| 
 | ||||
| ```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" | ||||
| ``` | ||||
| 
 | ||||
| When enabled, VPA will adjust CPU or memory recommendations to maintain: | ||||
| 
 | ||||
| ``` | ||||
| memory_bytes = cpu_cores * memoryPerCPU | ||||
| ``` | ||||
| 
 | ||||
| ## Design Details | ||||
| 
 | ||||
| ### API Changes | ||||
| 
 | ||||
| * New field `memoryPerCPU` (`resource.Quantity`) in `ContainerResourcePolicy`.   | ||||
| * Feature gate: `MemoryPerCPURatio` (alpha, default off). | ||||
| 
 | ||||
| ### Behavior | ||||
| 
 | ||||
| * If both CPU and memory are controlled, VPA enforces the ratio.   | ||||
| * Applies to Target, LowerBound, UpperBound, and UncappedTarget. | ||||
| * Ratio enforcement is strict: | ||||
|   * If the memory recommendation would exceed `cpu * memoryPerCPU`, then **CPU is increased** to satisfy the ratio. | ||||
|   * If the CPU recommendation would exceed `memory / memoryPerCPU`, then **memory is increased** to satisfy the ratio. | ||||
| * If ratio cannot be applied (e.g., missing CPU), fallback to standard recommendations.   | ||||
| * With the `MemoryPerCPURatio` feature gate disabled, the `memoryPerCPU` field is ignored and recommendations fall back to standard VPA behavior. | ||||
| 
 | ||||
| > [!IMPORTANT] | ||||
| > The enforced ratio values will be capped by | ||||
| > [`--container-recommendation-max-allowed-cpu`](https://github.com/kubernetes/autoscaler/blob/4d294562e505431d518a81e8833accc0ec99c9b8/vertical-pod-autoscaler/pkg/recommender/main.go#L122) | ||||
| > and | ||||
| > [`--container-recommendation-max-allowed-memory`](https://github.com/kubernetes/autoscaler/blob/4d294562e505431d518a81e8833accc0ec99c9b8/vertical-pod-autoscaler/pkg/recommender/main.go#L123) | ||||
| > flag values, if set. | ||||
| 
 | ||||
| #### Examples | ||||
| 
 | ||||
| * Example 1: `memoryPerCPU = 4Gi` | ||||
|   * Baseline recommendation: 1 CPU, 8Gi memory | ||||
|   * UncappedTarget (ratio enforced): 2 CPUs, 8Gi | ||||
|   * Target (after policy/caps): 2 CPUs, 8Gi | ||||
| 
 | ||||
| * Example 2: `memoryPerCPU = 4Gi` | ||||
|   * Baseline recommendation: 2 CPUs, 4Gi memory | ||||
|   * UncappedTarget (ratio enforced): 2 CPUs, 8Gi | ||||
|   * Target (after policy/caps): 2 CPUs, 8Gi | ||||
| 
 | ||||
| * Example 3: `memoryPerCPU = 4Gi`, with `--container-recommendation-max-allowed-memory=7Gi` or with `maxAllowed.memory=6Gi` set in VPA object | ||||
|   * Baseline recommendation: 2 CPUs, 4Gi memory | ||||
|   * UncappedTarget (ratio enforced): 2 CPUs, 8Gi | ||||
|   * Target (capped): 2 CPUs, 7Gi  ← memory capped by max-allowed-memory; ratio not fully satisfied | ||||
| 
 | ||||
| ### Feature Enablement and Rollback | ||||
| 
 | ||||
| #### How can this feature be enabled / disabled in a live cluster? | ||||
| 
 | ||||
| * Feature gate name: `MemoryPerCPURatio`   | ||||
| * Default: Off (Alpha)   | ||||
| * Components depending on the feature gate: | ||||
|   * admission-controller | ||||
|   * recommender | ||||
| 
 | ||||
| **When enabled**:   | ||||
| * VPA honors `memoryPerCPU` in recommendations.   | ||||
| 
 | ||||
| **When disabled**:   | ||||
| * `memoryPerCPU` is ignored.   | ||||
| * Recommendations behave as before. | ||||
| 
 | ||||
| ### Kubernetes Version Compatibility | ||||
| 
 | ||||
| The `memoryPerCPU` feature requires VPA version 1.5.0 or higher. The feature is being introduced as alpha and will follow the standard Kubernetes feature gate graduation process: | ||||
| - Alpha: v1.5.0 (default off) | ||||
| - Beta: TBD (default on) | ||||
| - GA: TBD (default on) | ||||
| 
 | ||||
| ### Validation | ||||
| 
 | ||||
| * `memoryPerCPU` must be > 0.   | ||||
| * Value must be a valid `resource.Quantity` (e.g., `512Mi`, `4Gi`).   | ||||
| 
 | ||||
| ### Test Plan | ||||
| 
 | ||||
| * Unit tests covering: | ||||
|   - ensuring ratio enforcement logic, | ||||
|   - ensuring that when the feature gate is on or off the values and validation are applied accordingly. | ||||
| * E2E tests comparing behavior with different configurations. | ||||
| 
 | ||||
| ## Implementation History | ||||
| 
 | ||||
| * 2025-08-19: Initial proposal | ||||
| 
 | ||||
| ## Future Work | ||||
| 
 | ||||
| 
 | ||||
| ## Alternatives | ||||
| 
 | ||||
		Loading…
	
		Reference in New Issue