你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在 Azure Kubernetes 服务中使用垂直 Pod 自动缩放程序 (AKS)

本文介绍如何在 Azure Kubernetes 服务 (AKS) 群集上使用垂直 Pod 自动缩放程序 (VPA)。 VPA 会自动调整 Pod 的 CPU 和内存请求,以匹配工作负载的使用模式。 此功能有助于优化应用程序的性能,并降低在 AKS 中运行工作负载的成本。

有关详细信息,请参阅垂直 Pod 自动缩放程序概述

开始之前

  • 如果有现有的 AKS 群集,请确保它正在运行 Kubernetes 版本 1.24 或更高版本。

  • 需要安装和配置 Azure CLI 2.52.0 或更高版本。 运行 az --version 即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI

  • 如果在现有群集上启用 VPA,请确保已安装 kubectl 并配置为使用 az aks get-credentials 命令连接到 AKS 群集。

    az aks get-credentials --name <cluster-name> --resource-group <resource-group-name>
    

在新群集上部署垂直 Pod 自动缩放程序

  • 使用带有 --enable-vpa 标志的 az aks create 命令创建启用 VPA 的新 AKS 群集。

    az aks create --name <cluster-name> --resource-group <resource-group-name> --enable-vpa --generate-ssh-keys
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

更新现有群集以使用垂直 Pod 自动缩放程序

  • 使用带有 --enable-vpa 标志的 az aks update 命令更新现有群集,以使用 VPA。

    az aks update --name <cluster-name> --resource-group <resource-group-name> --enable-vpa 
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

在现有群集上禁用垂直 Pod 自动缩放程序

  • 使用带有 --disable-vpa 标志的 az aks update 命令在现有群集上禁用 VPA。

    az aks update --name <cluster-name> --resource-group <resource-group-name> --disable-vpa
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

测试垂直 Pod 自动缩放程序安装

以下示例将创建包含两个 Pod 的部署,其中每个 Pod 运行单个容器,该容器请求 100 个毫核,并尝试利用数量略高于 500 的毫核。 我们还会创建一个指向部署的 VPA 配置。 VPA 将观察 Pod 的行为,大约五分钟后,更新 Pod 以请求 500 的毫核。

  1. 创建名为 hamster.yaml 的文件,并将 kubernetes/autoscaler GitHub 存储库中垂直 Pod 自动缩放程序示例的以下清单复制到该文件中:

    apiVersion: "autoscaling.k8s.io/v1"
    kind: VerticalPodAutoscaler
    metadata:
      name: hamster-vpa
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind: Deployment
        name: hamster
      resourcePolicy:
        containerPolicies:
          - containerName: '*'
            minAllowed:
              cpu: 100m
              memory: 50Mi
            maxAllowed:
              cpu: 1
              memory: 500Mi
            controlledResources: ["cpu", "memory"]
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: hamster
    spec:
      selector:
        matchLabels:
          app: hamster
      replicas: 2
      template:
        metadata:
          labels:
            app: hamster
        spec:
          securityContext:
            runAsNonRoot: true
            runAsUser: 65534
          containers:
            - name: hamster
              image: registry.k8s.io/ubuntu-slim:0.1
              resources:
                requests:
                  cpu: 100m
                  memory: 50Mi
              command: ["/bin/sh"]
              args:
                - "-c"
                - "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"
    
  2. 使用 kubectl apply 命令部署 hamster.yaml 垂直 Pod 自动缩放程序示例。

    kubectl apply -f hamster.yaml
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

  3. 使用 kubectl get 命令查看正在运行的 Pod。

    kubectl get pods -l app=hamster
    

    输出应类似于以下示例输出:

    hamster-78f9dcdd4c-hf7gk   1/1     Running   0          24s
    hamster-78f9dcdd4c-j9mc7   1/1     Running   0          24s
    
  4. 使用 kubectl describe 命令查看其中一个 Pod 上的 CPU 和内存预留。 请确保将 <example-pod> 替换为上一步骤的输出中返回的 Pod ID 之一。

    kubectl describe pod hamster-<example-pod>
    

    输出应类似于以下示例输出:

     hamster:
        Container ID:  containerd://
        Image:         k8s.gcr.io/ubuntu-slim:0.1
        Image ID:      sha256:
        Port:          <none>
        Host Port:     <none>
        Command:
          /bin/sh
        Args:
          -c
          while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done
        State:          Running
          Started:      Wed, 28 Sep 2022 15:06:14 -0400
        Ready:          True
        Restart Count:  0
        Requests:
          cpu:        100m
          memory:     50Mi
        Environment:  <none>
    

    在此示例中,Pod 预留了 100 millicpu(毫核 CPU)和 50 MiB 内存。 对于此示例应用程序,Pod 需要低于 100 millicpu 才能运行,因此没有可用的 CPU 容量。 Pod 预留的内存也比需求量少得多。 垂直 Pod 自动缩放程序 vpa-recommender 部署将分析托管 hamster 应用程序的 Pod,以确定 CPU 和内存要求是否适当。 如果需要调整,vpa-updater 将使用更新的值重新启动 Pod。

  5. 使用 kubectl get 命令监视 Pod。

    kubectl get --watch pods -l app=hamster
    
  6. 当新的仓鼠 Pod 启动时,可以使用 kubectl describe 命令查看更新的 CPU 和内存预留。 请确保将 <example-pod> 替换为上一步骤的输出中返回的 Pod ID 之一。

    kubectl describe pod hamster-<example-pod>
    

    输出应类似于以下示例输出:

    State:          Running
      Started:      Wed, 28 Sep 2022 15:09:51 -0400
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        587m
      memory:     262144k
    Environment:  <none>
    

    在上面的输出中,可以看到 CPU 预留量已增加到 587 millicpu,这是原始值的五倍多。 内存已增加到 262,144 KB(大约 250 MiB),即原始值的五倍。 此 Pod 资源不足,而垂直 Pod 自动缩放程序使用一个更合适的值更正了估算值。

  7. 使用 kubectl describe 命令查看 VPA 提供的已更新建议,来描述 hamster-vpa 资源信息。

    kubectl describe vpa/hamster-vpa
    

    输出应类似于以下示例输出:

     State:          Running
      Started:      Wed, 28 Sep 2022 15:09:51 -0400
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        587m
      memory:     262144k
    Environment:  <none>
    

设置垂直 Pod 自动缩放程序请求

VerticalPodAutoscaler 对象会自动在具有 Auto updateMode 的 Pod 上设置资源请求。 可以根据要求和测试设置不同的值。 在此示例中,我们将创建并测试包含两个 Pod 的部署清单,每个 Pod 运行请求 100 milliCPU 和 50 MiB 内存的容器,并将 updateMode 设置为 Recreate

  1. 创建名为 azure-autodeploy.yaml 的文件,并将以下清单复制到其中:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: vpa-auto-deployment
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: vpa-auto-deployment
      template:
        metadata:
          labels:
            app: vpa-auto-deployment
        spec:
          containers:
          - name: mycontainer
            image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
            resources:
              requests:
                cpu: 100m
                memory: 50Mi
            command: ["/bin/sh"]
            args: ["-c", "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"]
    
  2. 使用 kubectl create 命令创建 Pod。

    kubectl create -f azure-autodeploy.yaml
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

  3. 使用 kubectl get 命令查看正在运行的 Pod。

    kubectl get pods
    

    输出应类似于以下示例输出:

    NAME                                   READY   STATUS    RESTARTS   AGE
    vpa-auto-deployment-54465fb978-kchc5   1/1     Running   0          52s
    vpa-auto-deployment-54465fb978-nhtmj   1/1     Running   0          52s
    
  4. 创建名为 azure-vpa-auto.yaml 的文件,并将以下清单复制到其中:

    apiVersion: autoscaling.k8s.io/v1
    kind: VerticalPodAutoscaler
    metadata:
      name: vpa-auto
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind:       Deployment
        name:       vpa-auto-deployment
      updatePolicy:
        updateMode: "Recreate"
    

    targetRef.name 值指定由名为 vpa-auto-deployment 的部署所控制的任何 Pod 都属于此 VerticalPodAutoscalerRecreateupdateMode 值表示垂直 Pod 自动缩放程序控制器可以删除 Pod,调整 CPU 和内存请求,然后启动新 Pod。

  5. 使用 kubectl apply 命令将清单应用于群集。

    kubectl create -f azure-vpa-auto.yaml
    
  6. 等待几分钟,然后使用 kubectl get 命令查看正在运行的 Pod。

    kubectl get pods
    

    输出应类似于以下示例输出:

    NAME                                   READY   STATUS    RESTARTS   AGE
    vpa-auto-deployment-54465fb978-qbhc4   1/1     Running   0          2m49s
    vpa-auto-deployment-54465fb978-vbj68   1/1     Running   0          109s
    
  7. 使用 kubectl get 命令获取有关正在运行的 Pod 的详细信息。 请确保将 <pod-name> 替换为上一输出中其中一个 Pod 的名称。

    kubectl get pod <pod-name> --output yaml
    

    输出应类似于以下示例输出,其中显示 VPA 控制器将内存请求增加到 262144k,CPU 请求增加到 25 milliCPU:

    apiVersion: v1
    kind: Pod
    metadata:
      annotations:
        vpaObservedContainers: mycontainer
        vpaUpdates: 'Pod resources updated by vpa-auto: container 0: cpu request, memory
          request'
      creationTimestamp: "2022-09-29T16:44:37Z"
      generateName: vpa-auto-deployment-54465fb978-
      labels:
        app: vpa-auto-deployment
    
    spec:
      containers:
      - args:
        - -c
        - while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done
        command:
        - /bin/sh
        image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
        imagePullPolicy: IfNotPresent
        name: mycontainer
        resources:
          requests:
            cpu: 25m
            memory: 262144k
    
  8. 使用 kubectl get 命令获取有关垂直 Pod 自动缩放程序及其 CPU 和内存建议的详细信息。

    kubectl get vpa vpa-auto --output yaml
    

    输出应类似于以下示例输出:

     recommendation:
      containerRecommendations:
      - containerName: mycontainer
        lowerBound:
          cpu: 25m
          memory: 262144k
        target:
          cpu: 25m
          memory: 262144k
        uncappedTarget:
          cpu: 25m
          memory: 262144k
        upperBound:
          cpu: 230m
          memory: 262144k
    

    在此示例中,target 属性的结果指定它不需要更改容器的 CPU 或内存目标才能以最佳方式运行。 但是,结果可能会因应用程序及其资源利用率而异。

    垂直 Pod 自动缩放程序使用 lowerBoundupperBound 属性来确定是否要删除 Pod 并将其替换为新 Pod。 如果 Pod 中的请求低于下限或高于上限,垂直 Pod 自动缩放程序会删除该 Pod,并将它替换为符合目标属性的 Pod。

垂直 Pod 自动缩放程序的额外推荐器

推荐器根据实时资源消耗提供资源使用情况建议。 群集启用 VPA 时,AKS 会部署推荐器。 可以使用与默认映像相同的映像部署自定义推荐器或额外推荐器。 使用自定义推荐器的好处是可以自定义建议逻辑。 使用额外的推荐器,可以将 VPA 分区为使用不同的推荐器。

在以下示例中,我们将创建一个额外的推荐器,应用于现有的 AKS 群集,并将 VPA 对象配置为使用额外的推荐器。

  1. 创建名为 extra_recommender.yaml 的文件,并将以下清单复制到其中:

    apiVersion: apps/v1 
    kind: Deployment 
    metadata: 
      name: extra-recommender 
      namespace: kube-system 
    spec: 
      replicas: 1 
      selector: 
        matchLabels: 
          app: extra-recommender 
      template: 
        metadata: 
          labels: 
            app: extra-recommender 
        spec: 
          serviceAccountName: vpa-recommender 
          securityContext: 
            runAsNonRoot: true 
            runAsUser: 65534
          containers: 
          - name: recommender 
            image: registry.k8s.io/autoscaling/vpa-recommender:0.13.0 
            imagePullPolicy: Always 
            args: 
              - --recommender-name=extra-recommender 
            resources: 
              limits: 
                cpu: 200m 
                memory: 1000Mi 
              requests: 
                cpu: 50m 
                memory: 500Mi 
            ports: 
            - name: prometheus 
              containerPort: 8942 
    
  2. 使用 kubectl apply 命令部署 extra-recomender.yaml 垂直 Pod 自动缩放程序示例。

    kubectl apply -f extra-recommender.yaml 
    

    片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。

  3. 创建名为 hamster-extra-recommender.yaml 的文件,并将以下清单复制到其中:

    apiVersion: "autoscaling.k8s.io/v1" 
    kind: VerticalPodAutoscaler 
    metadata: 
      name: hamster-vpa 
    spec: 
      recommenders:  
        - name: 'extra-recommender' 
      targetRef: 
        apiVersion: "apps/v1" 
        kind: Deployment 
        name: hamster 
      updatePolicy: 
        updateMode: "Auto" 
      resourcePolicy: 
        containerPolicies: 
          - containerName: '*' 
            minAllowed: 
              cpu: 100m 
              memory: 50Mi 
            maxAllowed: 
              cpu: 1 
              memory: 500Mi 
            controlledResources: ["cpu", "memory"] 
    --- 
    apiVersion: apps/v1 
    kind: Deployment 
    metadata: 
      name: hamster 
    spec: 
      selector: 
        matchLabels: 
          app: hamster 
      replicas: 2 
      template: 
        metadata: 
          labels: 
            app: hamster 
        spec: 
          securityContext: 
            runAsNonRoot: true 
            runAsUser: 65534 # nobody 
          containers: 
            - name: hamster 
              image: k8s.gcr.io/ubuntu-slim:0.1 
              resources: 
                requests: 
                  cpu: 100m 
                  memory: 50Mi 
              command: ["/bin/sh"] 
              args: 
                - "-c" 
                - "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done" 
    

    如果 memory 未在 controlledResources 中指定,则推荐器不会响应 OOM 事件。 在此示例中,我们只在 controlledValues 中设置 CPU。 controlledValues 允许选择是使用 RequestsOnly 选项更新容器的资源请求,还是使用 RequestsAndLimits 选项同时更新资源请求和限制。 默认值为 RequestsAndLimits。 如果使用 RequestsAndLimits 选项,则会根据实际使用情况计算请求,并根据当前 Pod 的请求和限制比率计算限制。

    例如,如果从请求 2 个 CPU 且限制为 4 个 CPU 的 Pod 开始,则 VPA 始终将限制设置为请求数的两倍。 同一原则也适用于内存。 使用 RequestsAndLimits 模式时,它可以用作初始应用程序资源请求和限制的蓝图。

    可以使用 CPU 和内存的 Auto 模式和计算建议来简化 VPA 对象。

  4. 使用 kubectl apply 命令部署 hamster-extra-recomender.yaml 示例。

    kubectl apply -f hamster-extra-recommender.yaml
    
  5. 使用 [kubectl get]kubectl get 命令监视 Pod。

    kubectl get --watch pods -l app=hamster
    
  6. 当新的仓鼠 Pod 启动时,可以使用 kubectl describe 命令查看更新的 CPU 和内存预留。 确保将 <example-pod> 替换为其中一个 Pod ID。

    kubectl describe pod hamster-<example-pod>
    

    输出应类似于以下示例输出:

    State:          Running
      Started:      Wed, 28 Sep 2022 15:09:51 -0400
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        587m
      memory:     262144k
    Environment:  <none>
    
  7. 使用 kubectl describe 命令查看 VPA 中的更新建议。

    kubectl describe vpa/hamster-vpa
    

    输出应类似于以下示例输出:

    State:          Running
     Started:      Wed, 28 Sep 2022 15:09:51 -0400
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        587m
      memory:     262144k
    Environment:  <none>
    Spec:
      recommenders:
        Name: customized-recommender
    

对垂直 Pod 自动缩放程序进行故障排除

如果遇到垂直 Pod 自动缩放程序的问题,则可以对系统组件和自定义资源定义进行故障排除,以确定问题。

  1. 使用以下命令验证是否所有系统组件都在运行:

    kubectl --namespace=kube-system get pods|grep vpa
    

    输出应列出三个 Pod:推荐器、更新器和允许控制器,状态都显示为 Running

  2. 对于在上一个输出中返回的每个 Pod,请使用以下命令验证系统组件是否记录任何错误:

    kubectl --namespace=kube-system logs [pod name] | grep -e '^E[0-9]\{4\}'
    
  3. 使用以下命令验证已创建自定义资源定义:

    kubectl get customresourcedefinition | grep verticalpodautoscalers
    

后续步骤

若要详细了解 VPA 对象,请参阅垂直 Pod 自动缩放程序 API 参考