Vertical application scaling in a cluster
Managed Service for Kubernetes supports several types of autoscaling. In this article you will learn how to configure the automatic management of pod resources with Vertical Pod Autoscaler:
Getting started
-
If you do not have the Yandex Cloud command line interface yet, install and initialize it.
The folder specified in the CLI profile is used by default. You can specify a different folder using the
--folder-name
or--folder-id
parameter. -
sg-k8s
: For master and node group.k8s-public-services
: For public access to services from the internet.k8s-master-whitelist
: For accessing the Kubernetes API.
-
Create a Managed Service for Kubernetes cluster. Use these settings:
- Use the previously created security groups.
- If you intend to use your cluster within the Yandex Cloud network, there is no need to allocate a public IP address to it. To allow connections from outside the network, assign a public IP to the cluster.
-
Create a node group. Use these settings:
- Use the previously created security groups.
- Allocate it a public IP address to grant internet access to the node group and allow pulling Docker images and components.
-
Install kubectl
and configure it to work with the created cluster.If a cluster has no public IP address assigned and
kubectl
is configured via the cluster's private IP address, runkubectl
commands on a Yandex Cloud VM that is in the same network as the cluster. -
Install Vertical Pod Autoscaler from the following repository
:cd /tmp && \ git clone https://github.com/kubernetes/autoscaler.git && \ cd autoscaler/vertical-pod-autoscaler/hack && \ ./vpa-up.sh
Create Vertical Pod Autoscaler and a test application
-
Create a file called
app.yaml
with thenginx
test application and load balancer settings:app.yaml--- ### Deployment apiVersion: apps/v1 kind: Deployment metadata: name: nginx labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: registry.k8s.io/hpa-example resources: requests: memory: "256Mi" cpu: "500m" limits: memory: "500Mi" cpu: "1" --- ### Service apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: LoadBalancer
-
Create a file called
vpa.yaml
with the Vertical Pod Autoscaler configuration:vpa.yaml--- apiVersion: autoscaling.k8s.io/v1 kind: VerticalPodAutoscaler metadata: name: nginx spec: targetRef: apiVersion: "apps/v1" kind: Deployment name: nginx updatePolicy: updateMode: "Auto" minReplicas: 1
-
Create objects:
kubectl apply -f app.yaml && \ kubectl apply -f vpa.yaml
-
Make sure that the Vertical Pod Autoscaler and
nginx
pods have changed their status toRunning
:kubectl get pods -n kube-system | grep vpa && \ kubectl get pods | grep nginx
Result:
vpa-admission-controller-58********-qmxtv 1/1 Running 0 44h vpa-recommender-67********-jqvgt 1/1 Running 0 44h vpa-updater-64********-xqsts 1/1 Running 0 44h nginx-6c********-62j7w 1/1 Running 0 42h
Test Vertical Pod Autoscaler
To test Vertical Pod Autoscaler, nginx
application workload will be simulated.
-
Review the recommendations provided by Vertical Pod Autoscaler prior to creating the workload:
kubectl describe vpa nginx
Note the low
Cpu
values in theStatus.Recommendation.Container Recommendations
metrics:Name: nginx Namespace: default Labels: <none> Annotations: <none> API Version: autoscaling.k8s.io/v1 Kind: VerticalPodAutoscaler ... Status: Conditions: Last Transition Time: 2022-03-18T08:02:04Z Status: True Type: RecommendationProvided Recommendation: Container Recommendations: Container Name: nginx Lower Bound: Cpu: 25m Memory: 262144k Target: Cpu: 25m Memory: 262144k Uncapped Target: Cpu: 25m Memory: 262144k Upper Bound: Cpu: 25m Memory: 262144k
-
Make sure that Vertical Pod Autoscaler is managing the
nginx
application pod resources:kubectl get pod <nginx_pod_name> --output yaml
Result:
apiVersion: v1 kind: Pod metadata: annotations: vpaObservedContainers: nginx vpaUpdates: 'Pod resources updated by nginx: container 0: cpu request, memory request, cpu limit, memory limit' ... spec: containers: ... name: nginx resources: limits: cpu: 50m memory: 500000Ki requests: cpu: 25m memory: 262144k
-
Run the workload simulation process in a separate window:
URL=$(kubectl get service nginx -o json \ | jq -r '.status.loadBalancer.ingress[0].ip') && \ while true; do wget -q -O- http://$URL; done
Tip
To increase load and accelerate the execution of the scenario, run several processes in separate windows.
-
After several minutes, review the recommendation provided by Vertical Pod Autoscaler after the workload is created:
kubectl describe vpa nginx
Vertical Pod Autoscaler allocated additional resources to the pods as the workload increased. Note the increased
Cpu
values in theStatus.Recommendation.Container Recommendations
metrics:Name: nginx Namespace: default Labels: <none> Annotations: <none> API Version: autoscaling.k8s.io/v1 Kind: VerticalPodAutoscaler ... Status: Conditions: Last Transition Time: 2022-03-18T08:02:04Z Status: True Type: RecommendationProvided Recommendation: Container Recommendations: Container Name: nginx Lower Bound: Cpu: 25m Memory: 262144k Target: Cpu: 410m Memory: 262144k Uncapped Target: Cpu: 410m Memory: 262144k Upper Bound: Cpu: 28897m Memory: 1431232100
-
Stop simulating the workload. Within a few minutes, the
Status.Recommendation.Container Recommendations
metric values will return to their original values.
Delete the resources you created
Delete the resources you no longer need to avoid paying for them:
- Delete the Kubernetes cluster.
- If static public IP addresses were used for cluster and node access, release and delete them.