Skip to content

Commit a6533b9

Browse files
authored
Add Vertical Pod Autoscaler support (#183)
* feat: add Vertical Pod Autoscaler * docs: add VPA section * feat: Add tests for VPA * feat: add support for k8s < 1.25 for VPA * fix(vpa): fix typos * fix: typos
1 parent 5ee6616 commit a6533b9

File tree

5 files changed

+403
-0
lines changed

5 files changed

+403
-0
lines changed

charts/k8s-service/README.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ The following resources will be deployed with this Helm Chart, depending on whic
4242
- `Horizontal Pod Autoscaler`: The `Horizontal Pod Autoscaler` automatically scales the number of pods in a replication
4343
controller, deployment, replica set or stateful set based on observed CPU or memory utilization.
4444
Created only if the user sets `horizontalPodAutoscaler.enabled = true`.
45+
- `Vertical Pod Autoscaler`: The `Vertical Pod Autoscaler` can offer recommendations or change the CPU and memory for both
46+
requests and limits based on specified configuration.
47+
Created only if the user sets `verticalPodAutoscaler.enabled = true`.
4548
- `PodDisruptionBudget`: The `PodDisruptionBudget` resource that specifies a disruption budget for the `Pods` managed by
4649
the `Deployment`. This manages how many pods can be disrupted by a voluntary disruption (e.g
4750
node maintenance). Created if you specify a non-zero value for the `minPodsAvailable` input
@@ -1218,3 +1221,39 @@ You can learn more about using private registries with Kubernetes in [the offici
12181221
documentation](https://kubernetes.io/docs/concepts/containers/images/#using-a-private-registry).
12191222

12201223
back to [root README](/README.adoc#day-to-day-operations)
1224+
1225+
## How to enable Vertical Pod Autoscaler ?
1226+
1227+
[Vertical Pod Auto scaler](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler) is used to dynamically change
1228+
the requests and limits of running pods. It should **not be used** in combination with Horizontal Pod Autoscaler.
1229+
1230+
First you need to install it in the cluster by following the [installation guide](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler#installation)
1231+
1232+
1233+
VPA has the following modes:
1234+
1235+
* `Off` where right sizing recommendation will be generated but it won't change any existing pods
1236+
* `Initial` when a new pod is created, it will be configured with the limits/requests that are considered appropriate
1237+
* `Recreate` every time a new suitable sizing event happens (when better requests/limits are computed) pods may be evicted to apply the new configuration
1238+
* `Auto` it is the same as `Recreate`, but in the future, it may support restart-free updates
1239+
1240+
By default, the VPA is configured to generate recommendations only. The following configuration enables it:
1241+
```yaml
1242+
verticalPodAutoscaler:
1243+
enabled: true
1244+
```
1245+
1246+
To see the recommendation you can run
1247+
```bash
1248+
~ $ kubectl get vpa
1249+
NAME MODE CPU MEM PROVIDED AGE
1250+
release-nginx Auto 24m
1251+
1252+
1253+
~ $ kubectl describe vpa release-nginx
1254+
```
1255+
1256+
You can learn more about using Vertical Pod Autoscaler [the official
1257+
documentation](https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler).
1258+
1259+
back to [root README](/README.adoc#day-to-day-operations)

charts/k8s-service/templates/_capabilities_helpers.tpl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,12 @@
4949
{{- print "autoscaling/v2beta2" -}}
5050
{{- end -}}
5151
{{- end -}}
52+
53+
{{/* Get VertialPodAutoscaler API Version */}}
54+
{{- define "gruntwork.verticalPodAutoscaler.apiVersion" -}}
55+
{{- if and (.Capabilities.APIVersions.Has "autoscaling.k8s.io/v1") (semverCompare ">= 1.23-0" (include "gruntwork.kubeVersion" .)) -}}
56+
{{- print "autoscaling.k8s.io/v1" -}}
57+
{{- else -}}
58+
{{- print "autoscaling.k8s.io/v1beta2" -}}
59+
{{- end -}}
60+
{{- end -}}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- if .Values.verticalPodAutoscaler.enabled }}
2+
apiVersion: {{ include "gruntwork.verticalPodAutoscaler.apiVersion" . }}
3+
kind: VerticalPodAutoscaler
4+
metadata:
5+
name: {{ include "k8s-service.fullname" . }}
6+
namespace: {{ $.Release.Namespace }}
7+
spec:
8+
targetRef:
9+
apiVersion: apps/v1
10+
kind: Deployment
11+
name: {{ include "k8s-service.fullname" . }}
12+
updatePolicy:
13+
updateMode: {{ .Values.verticalPodAutoscaler.updateMode | quote }}
14+
minReplicas: {{ .Values.verticalPodAutoscaler.minReplicas }}
15+
resourcePolicy:
16+
containerPolicies:
17+
- containerName: {{ include "k8s-service.fullname" . }}
18+
{{- if .Values.verticalPodAutoscaler.mainContainerResourcePolicy.minAllowed }}
19+
minAllowed:
20+
{{- toYaml .Values.verticalPodAutoscaler.mainContainerResourcePolicy.minAllowed | nindent 8 }}
21+
{{- end }}
22+
23+
{{- if .Values.verticalPodAutoscaler.mainContainerResourcePolicy.maxAllowed }}
24+
maxAllowed:
25+
{{- toYaml .Values.verticalPodAutoscaler.mainContainerResourcePolicy.maxAllowed | nindent 8 }}
26+
{{- end }}
27+
28+
{{- if .Values.verticalPodAutoscaler.mainContainerResourcePolicy.controlledResources }}
29+
controlledResources:
30+
{{- toYaml .Values.verticalPodAutoscaler.mainContainerResourcePolicy.controlledResources | nindent 8 }}
31+
{{- end }}
32+
33+
{{- if .Values.verticalPodAutoscaler.mainContainerResourcePolicy.controlledValues }}
34+
controlledValues: {{ .Values.verticalPodAutoscaler.mainContainerResourcePolicy.controlledValues }}
35+
{{- end }}
36+
37+
{{- if .Values.verticalPodAutoscaler.extraResourcePolicy }}
38+
{{- toYaml .Values.verticalPodAutoscaler.extraResourcePolicy | nindent 4 }}
39+
{{- end }}
40+
{{- end }}

charts/k8s-service/values.yaml

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,159 @@ horizontalPodAutoscaler:
805805
minReplicas: 1
806806
maxReplicas: 10
807807

808+
# verticalPodAutoscaler is a map that configures the Vertical Pod Autoscaler information for this pod
809+
# The expected keys of vpa are:
810+
# - enabled (bool) : Whether or not Vertical Pod Autoscaler should be created, if false the
811+
# Vertical Pod Autoscaler will not be created
812+
# - updateMode (string) : Controls when autoscaler applies changes to the pod resources. Possible values:
813+
# * "Off" Changes are only recommended but the pods are not changed
814+
# * "Initial" Changes are applied at pod creation only
815+
# * "Recreate" Pods will be evicted to apply new scaling settings
816+
# * "Auto" Currently it is equivalent with "Recreate" but in the future
817+
# it will update pods without eviction
818+
# - minReplicas (int) : Minimal number of replicas which need to be alive for Updater to attempt
819+
# pod eviction (pending other checks like PDB).
820+
# - evictionRequirements (list) : Requirements that need to be true for an eviction event to be attempted
821+
# - mainContainerResourcePolicy (object) : Configuration for the main container
822+
# - extraResourcePolicy (list) : Configuration injected. Can be used if other sideCarContainers are used
823+
#
824+
#
825+
# The expected attributes for objects of type evictionRequirement:
826+
# - resource (list) : A list of one or more resources that the condition applies to. These resources can be "cpu", "memory", etc.
827+
# - changeRequirement (string) : The type of change required. Possible options:
828+
# * "TargetHigherThanRequests" - The eviction is attempted when the new target is higher than the current requests,
829+
# i.e., the Pod is scaled up.
830+
# * "TargetLowerThanRequests" - The eviction is attempted if the new target is lower than the current requests,
831+
# i.e., the Pod is scaled down.
832+
#
833+
# The expected attributes for `mainContainerResourcePolicy` object:
834+
# - mode (string) : The mode of operation. Can be "Off", "Auto"
835+
# - minAllowed (object) : The minimum resources allowed for the container.
836+
# - maxAllowed (object) : The maximum resources allowed for the container.
837+
# - controlledResources (list) : The list of resources that the policy can control. Can include "cpu" and "memory".
838+
# - controlledValues (string) : The values that the policy can control. Can be "RequestsOnly" or "RequestsAndLimits".
839+
#
840+
#
841+
# The expected attributes for `extraResourcePolicy` list of objects:
842+
# - containerName (string) : The name of the container that the policy applies to.
843+
# - mode (string) : The mode of operation. Can be "Off", "Auto"
844+
# - minAllowed (object) : The minimum resources allowed for the container.
845+
# - maxAllowed (object) : The maximum resources allowed for the container.
846+
# - controlledResources (list) : The list of resources that the policy can control. Can include "cpu" and "memory".
847+
# - controlledValues (string) : The values that the policy can control. Can be "RequestsOnly" or "RequestsAndLimits".
848+
849+
# The expected attributes for `minAllowed` and `maxAllowed` objects:
850+
# - cpu (string):
851+
# - memory (string):
852+
#
853+
#
854+
# Example configuration that uses all the features
855+
#
856+
# ```yaml
857+
# verticalPodAutoscaler:
858+
# enabled: true
859+
# updateMode: "Auto"
860+
# minPodsAvailable: 2
861+
# evictionRequirements:
862+
# # Allow scale up events if the CPU needs adjusting
863+
# - resource: ["cpu"]
864+
# changeRequirement: TargetHigherThanRequests
865+
#
866+
# # Allow scale up events if the Memory needs adjusting
867+
# - resource: ["memory"]
868+
# changeRequirement: TargetHigherThanRequests
869+
#
870+
# # Allow scale down events if both the CPU and memory need adjusting
871+
# - resource: ["cpu", "memory"]
872+
# changeRequirement: TargetLowerThanRequests
873+
# mainContainerResourcePolicy:
874+
# # Enable scaling for the main container
875+
# mode: "Auto"
876+
# minAllowed:
877+
# cpu: "0.2"
878+
# memory: "200Mi"
879+
# maxAllowed:
880+
# cpu: "1"
881+
# memory: "500Mi"
882+
# # Scale both the CPU and Memory of the container
883+
# controlledResources: ["cpu", "memory"]
884+
# # Adjust both requests and limits
885+
# controlledValues: "RequestsAndLimits"
886+
# # Configuration for other containers (e.g. when sideCarContainers are used)
887+
# extraResourcePolicy:
888+
# # Disable the scaling for all other containers by default
889+
# - containerName: "*"
890+
# mode: "Off"
891+
# # Assuming we have a sideCarContainers called "proxy"
892+
# - containerName: "proxy"
893+
# # Enable scaling actions
894+
# mode: "Auto"
895+
# minAllowed:
896+
# cpu: "0.2"
897+
# maxAllowed:
898+
# cpu: "1"
899+
# # Only scale the CPU
900+
# controlledResources: ["cpu"]
901+
# # Scale only the requests
902+
# controlledValues: "RequestsOnly"
903+
# ```
904+
#
905+
#
906+
# This will result in the following configuration
907+
#
908+
# ```yaml
909+
# apiVersion: autoscaling.k8s.io/v1
910+
# kind: VerticalPodAutoscaler
911+
# metadata:
912+
# name: XXXX
913+
# spec:
914+
# resourcePolicy:
915+
# containerPolicies:
916+
# - containerName: XXXX
917+
# controlledResources:
918+
# - cpu
919+
# - memory
920+
# controlledValues: RequestsAndLimits
921+
# maxAllowed:
922+
# cpu: "1"
923+
# memory: 500Mi
924+
# minAllowed:
925+
# cpu: "0.2"
926+
# memory: 200Mi
927+
# - containerName: ""
928+
# mode: "Off"
929+
# - containerName: proxy
930+
# controlledResources:
931+
# - cpu
932+
# controlledValues: RequestsOnly
933+
# maxAllowed:
934+
# cpu: "1"
935+
# minAllowed:
936+
# cpu: "0.2"
937+
# mode: Auto
938+
# targetRef:
939+
# apiVersion: apps/v1
940+
# kind: Deployment
941+
# name: m1-nginx
942+
# updatePolicy:
943+
# minReplicas: 2
944+
# updateMode: Auto
945+
#```
946+
#
947+
# The default config will not create the Vertical Pod Autoscaler by setting enabled = false,
948+
# the default values are set so if enabled is true the verticalPodAutoscaler has valid values
949+
# and is running in recommendation only mode
950+
verticalPodAutoscaler:
951+
enabled: false
952+
updateMode: "Off"
953+
minReplicas: 2
954+
mainContainerResourcePolicy:
955+
controlledResources: ["cpu", "memory"]
956+
controlledValues: "RequestsAndLimits"
957+
extraResourcePolicy:
958+
- containerName: ""
959+
mode: "Off"
960+
808961
# customResources is a map that lets you define Kubernetes resources you want installed and configured as part of this chart.
809962
# The expected keys of customResources are:
810963
# - enabled (bool) : Whether or not the provided custom resource definitions should be created.

0 commit comments

Comments
 (0)