You can deploy the vertical-pod-autoscaler component in a Container Service for Kubernetes (ACK) cluster. vertical-pod-autoscaler is a Vertical Pod Autoscaler (VPA). The VPA enables vertical autoscaling of pods. The VPA automatically sets limits on the resource usage of a cluster based on the pod resource usage. This way, ACK can schedule the pods to nodes that have sufficient resources. The VPA also maintains the ratio of requests to limits that you specify in the initial container configurations. This topic describes how to use a YAML file to enable vertical pod autoscaling.

Prerequisites

Make sure that the following operations are completed:

Background information

Notice Vertical pod autoscaling is in testing. Use this feature with caution.
  • You can use the VPA to update the resource configurations of the running pods. This feature is in testing. The configuration updates will lead to pod restart and recreation, and the pods may be scheduled to other nodes.
  • The VPA does not evict the pods that are not managed by a replication controller. For these pods, the Auto mode is equivalent to the Initial mode.
  • The VPA and the Horizontal Pod Autoscaler (HPA) cannot run at the same time. The HPA monitors the CPU and memory metrics. If the HPA monitors only other custom or external resource metrics, you can use the VPA in conjunction with the HPA.
  • The VPA uses an admission webhook as its admission controller. If other admission webhooks exist in the cluster, make sure that the admission webhooks do not conflict with the admission webhook of the VPA. The execution sequence of admission controllers is defined in the configuration parameters of the API server.
  • The VPA can react to most out of memory (OOM) events, but may fail to handle some events in some scenarios.
  • The VPA performance is not tested in large-scale clusters.
  • The pod resource requests set by the VPA may exceed the upper limit of the actual resources, including node resources, idle resources, and resource quotas. In this case, a pod may enter the Pending state and cannot be scheduled. You can use the cluster autoscaler to mitigate this issue.
  • If multiple VPAs monitor the resource usage of a pod at the same time, some undefined behavior may occur.

Install vertical-pod-autoscaler

  1. Run the following command to create a CustomResourceDefinition (CRD) for vertical-pod-autoscaler.

    The CRD improves the scalability of ACK clusters. For more information, see Extend the Kubernetes API with CustomResourceDefinitions.

    kubectl apply -f crd.yaml
    Use the following content to create a crd.yaml file:
    ---
    apiVersion: apiextensions.k8s.io/v1beta1
    kind: CustomResourceDefinition
    metadata:
      name: verticalpodautoscalers.autoscaling.k8s.io
      annotations:
        "api-approved.kubernetes.io": "https://github.com/kubernetes/kubernetes/pull/63797"
    spec:
      group: autoscaling.k8s.io
      scope: Namespaced
      names:
        plural: verticalpodautoscalers
        singular: verticalpodautoscaler
        kind: VerticalPodAutoscaler
        shortNames:
          - vpa
      version: v1beta1
      versions:
        - name: v1beta1
          served: false
          storage: false
        - name: v1beta2
          served: true
          storage: true
        - name: v1
          served: true
          storage: false
      validation:
        # openAPIV3Schema is the schema for validating custom objects.
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required: []
              properties:
                targetRef:
                  type: object
                updatePolicy:
                  type: object
                  properties:
                    updateMode:
                      type: string
                resourcePolicy:
                  type: object
                  properties:
                    containerPolicies:
                      type: array
                      items:
                        type: object
                        properties:
                          containerName:
                            type: string
                          controlledValues:
                            type: string
                            enum: ["RequestsAndLimits", "RequestsOnly"]
                          mode:
                            type: string
                            enum: ["Auto", "Off"]
                          minAllowed:
                            type: object
                          maxAllowed:
                            type: object
                          controlledResources:
                            type: array
                            items:
                              type: string
                              enum: ["cpu", "memory"]
    ---
    apiVersion: apiextensions.k8s.io/v1beta1
    kind: CustomResourceDefinition
    metadata:
      name: verticalpodautoscalercheckpoints.autoscaling.k8s.io
      annotations:
        "api-approved.kubernetes.io": "https://github.com/kubernetes/kubernetes/pull/63797"
    spec:
      group: autoscaling.k8s.io
      scope: Namespaced
      names:
        plural: verticalpodautoscalercheckpoints
        singular: verticalpodautoscalercheckpoint
        kind: VerticalPodAutoscalerCheckpoint
        shortNames:
          - vpacheckpoint
      version: v1beta1
      versions:
        - name: v1beta1
          served: false
          storage: false
        - name: v1beta2
          served: true
          storage: true
        - name: v1
          served: true
          storage: false
  2. Install the components of vertical-pod-autoscaler.

    vertical-pod-autoscaler contains the following components: admission-controller, recommender, and updater.

    Use the following YAML file to define and install admission-controller.

    Generate a certificate before you install admission-controller. Use this script to generate a certificate for the webhook.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vpa-admission-controller
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: vpa-admission-controller
      template:
        metadata:
          labels:
            app: vpa-admission-controller
        spec:
          serviceAccountName: admin
          containers:
            - name: admission-controller
              image: registry.cn-hangzhou.aliyuncs.com/acs/vpa-admission-controller:0.7.0
              imagePullPolicy: Always
              env:
                - name: NAMESPACE
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.namespace
              volumeMounts:
                - name: tls-certs
                  mountPath: "/etc/tls-certs"
                  readOnly: true
              resources:
                limits:
                  cpu: 200m
                  memory: 500Mi
                requests:
                  cpu: 50m
                  memory: 200Mi
              ports:
                - containerPort: 8000
          volumes:
            - name: tls-certs
              secret:
                secretName: vpa-tls-certs
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: vpa-webhook
      namespace: kube-system
    spec:
      ports:
        - port: 443
          targetPort: 8000
      selector:
        app: vpa-admission-controller
    

    Use the following YAML file to define and install recommender.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vpa-recommender
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: vpa-recommender
      template:
        metadata:
          labels:
            app: vpa-recommender
        spec:
          serviceAccountName: admin
          containers:
          - name: recommender
            image: registry.cn-hangzhou.aliyuncs.com/acs/vpa-recommender:0.7.0
            imagePullPolicy: Always
            resources:
              limits:
                cpu: 200m
                memory: 1000Mi
              requests:
                cpu: 50m
                memory: 500Mi
            ports:
            - containerPort: 8080
    

    Use the following YAML file to define and install updater.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vpa-updater
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: vpa-updater
      template:
        metadata:
          labels:
            app: vpa-updater
        spec:
          serviceAccountName: admin
          containers:
            - name: updater
              image: registry.cn-hangzhou.aliyuncs.com/acs/vpa-updater:0.7.0
              imagePullPolicy: Always
              resources:
                limits:
                  cpu: 200m
                  memory: 1000Mi
                requests:
                  cpu: 50m
                  memory: 500Mi
              ports:
                - containerPort: 8080
    

Verify that the VPA is installed

  1. Use the following YAML file to define and create a Deployment named nginx-deployment-basic and a VPA resource named nginx-deployment-basic-vpa.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-basic
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
    ---
    apiVersion: autoscaling.k8s.io/v1
    kind: VerticalPodAutoscaler
    metadata:
      name: nginx-deployment-basic-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind:       Deployment
        name:       nginx-deployment-basic
      updatePolicy:
        updateMode: "Off"
    Note Set updateMode to Off, and leave the requests and limits fields in the Deployment unspecified.
  2. Run the following command to query the CPU and memory resource requests recommended by the VPA for the Deployment:
    kubectl describe vpa nginx-deployment-basic-vpa

    The following command output shows the recommended resource requests:

    recommendation:
        containerRecommendations:
        - containerName: nginx
          lowerBound:
            cpu: 50m
            memory: 300144k
          target:
            cpu: 50m
            memory: 300144k
          upperBound:
            cpu: 8031m
            memory: 800000k

    You can set the resource requests for the Deployment based on the recommendation. The VPA performs continuous monitoring of the resource usage of the Deployment and provides optimization suggestions.