你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
Azure Kubernetes 服务 (AKS) 中的垂直 Pod 自动缩放
本文概述 Azure Kubernetes 服务 (AKS) 中基于开源 Kubernetes 版本的垂直 Pod 自动缩放程序 (VPA)。 配置该程序后,它将根据过去的使用量自动设置每个工作负载中容器的资源请求和限制。 VPA 释放其他 Pod 的 CPU 和内存,并帮助有效利用 AKS 群集。
垂直 Pod 自动缩放提供一段时间内的资源使用情况建议。 若要管理资源使用量的突然增加,请使用水平 Pod 自动缩放程序,它可以根据需要缩放 Pod 副本数。
好处
垂直 Pod 自动缩放程序提供以下优势:
分析应用程序所需的处理器和内存资源并将其调整为合适的大小。 VPA 不仅会根据一段时间内的资源使用量负责纵向扩展,而且还负责纵向缩减。
如果某个 Pod 的缩放模式设置为“自动”或“重新创建”,当它需要更改其资源请求时,将逐出该 Pod。
通过指定资源策略为单个容器设置 CPU 和内存限制
确保节点中有适当的资源用于 Pod 调度
对处理器或内存资源所做调整的日志记录可配置
提高群集资源利用率并为其他 Pod 释放 CPU 和内存。
限制
垂直 Pod 自动缩放支持每个群集上的最多 1,000 个关联的
VerticalPodAutoscaler
对象。VPA 建议的资源可能多于群集中可用的资源。 因此,这会阻止 Pod 分配给节点并运行,因为节点没有足够的资源。 可以通过将 LimitRange 设置为每个命名空间的最大可用资源来克服此限制,这可确保 Pod 请求的资源不会超过指定。 此外,还可以设置
VerticalPodAutoscaler
对象中每个 Pod 允许的最大资源建议数。 请注意,VPA 无法完全克服节点资源不足的问题。 限制范围是固定的,但节点资源使用情况会动态更改。不建议将垂直 Pod 自动缩放程序与水平 Pod 自动缩放程序配合使用,后者根据相同的 CPU 和内存使用情况指标进行缩放。
VPA 推荐器最多只存储 8 天的历史数据。
VPA 不支持基于 JVM 的工作负载,因为对工作负载的实际内存使用情况的可见性有限。
不建议或不支持将自己的 VPA 实现与 VPA 的此托管实现一起运行。 支持使用额外的或自定义的推荐器。
不支持 AKS Windows 容器。
开始之前
AKS 群集正在运行 Kubernetes 版本 1.24 和更高版本。
已安装并配置 Azure CLI 2.52.0 或更高版本。 运行
az --version
即可查找版本。 如果需要进行安装或升级,请参阅安装 Azure CLI。kubectl
应连接到要安装 VPA 的群集。
VPA 概述
API 对象
垂直 Pod 自动缩放程序是 Kubernetes 自动缩放 API 组中的一个 API 资源。 支持的版本是 0.11 或更高版本,可在 Kubernetes 自动缩放程序存储库中找到。
VPA 对象由三个组件组成:
推荐器 - 它监视当前和过去的资源消耗,并基于它为容器的 CPU 和内存请求/限制提供建议值。 推荐器监视指标历史记录、内存不足 (OOM) 事件和 VPA 部署规范,并建议公平请求。 通过提供适当的资源请求和限制配置,可以提高和降低限制。
更新程序 - 它会检查哪些托管 Pod 设置了正确的资源,如果未设置,则会将其终止,以便控制器可以使用更新的请求重新创建它们。
VPA 许可控制器 - 它为新 Pod 设置正确的资源请求(由其控制器创建或重新创建,因为更新程序的活动)。
VPA 许可控制器
VPA 许可控制器是一个二进制文件,用于将自身注册为可变许可 Webhook。 创建每个 Pod 后,它会从 apiserver 获取请求,并评估是否存在匹配的 VPA 配置,或者查找相应的配置,并使用当前建议在 Pod 中设置资源请求。
独立作业在 VPA 允许控制器外运行,称为 overlay-vpa-cert-webhook-check
。 overlay-vpa-cert-webhook-check
用于创建和续订证书,并将 VPA 许可控制器注册为 MutatingWebhookConfiguration
。
为了获得高可用性,AKS 支持两个准入控制器副本。
VPA 对象操作模式
将为希望自动计算资源要求的每个控制器插入垂直 Pod 自动缩放程序资源。 这通常是部署。 有四种运行 VVA 的模式:
Auto
- VPA 在 Pod 创建期间分配资源请求,并使用首选更新机制更新现有 Pod。 目前,Auto
等效于Recreate
,也是默认模式。 免费重启(“就地”)更新 Pod 请求可用后,Auto
模式可以将它用作首选更新机制。 使用Recreate
模式时,如果 Pod 需要更改其资源请求,VPA 会逐出 Pod。 这可能会导致 Pod 一次性重启,从而导致应用程序不一致。 在这种情况下,可以使用 PodDisruptionBudget 限制重启并保持一致性。Recreate
- VPA 在 Pod 创建期间分配资源请求,并通过在请求的资源与遵循 Pod 中断预算的新建议(如果定义)明显不同时逐出现有 Pod 来更新这些请求。 仅当需要确保每当资源请求更改时重启 Pod 时,才应少量使用此模式。 否则,Auto
为首选模式,该模式在可用后可能会利用免重启更新。Initial
- VPA 仅在 Pod 创建期间分配资源请求,之后永远不会更改。Off
- VPA 不会自动更改 Pod 的资源要求。 建议经过计算,可以在 VPA 对象中检查。
应用程序开发期间的部署模式
如果不熟悉 VPA,建议使用一种常见部署模式,即在应用程序开发期间执行以下步骤,以确定其独特的资源利用率特征,测试 VPA 以验证它是否正常运行,并与其他 Kubernetes 组件一起测试以优化群集的资源利用率。
在生产群集中设置 UpdateMode = "Off",并在建议模式下运行 VPA,以便测试并熟悉 VPA。 UpdateMode = "Off" 可以避免引入可能导致中断的错误配置。
首先通过收集给定时间段内的实际资源利用率遥测数据来建立可观测性。 这有助于了解受容器和 Pod 资源上运行的工作负载影响的症状或问题的行为和迹象。
熟悉监视数据以了解性能特征。 根据此见解,相应地设置所需的请求/限制,然后在下一次部署或升级中
根据你的要求将
updateMode
值设为Auto
、Recreate
或Initial
。
在群集上部署、升级或禁用 VPA
本部分介绍如何在群集上部署、升级或禁用垂直 Pod 自动缩放程序。
若要在新群集上启用 VPA,请将
--enable-vpa
参数与 az aks create 命令结合使用。az aks create -n myAKSCluster -g myResourceGroup --enable-vpa
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
(可选)若要在现有群集上启用 VPA,请使用
--enable-vpa
[https://learn.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-update] 命令。az aks update -n myAKSCluster -g myResourceGroup --enable-vpa
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
(可选)若要在现有群集上禁用 VPA,请使用
--disable-vpa
[https://learn.microsoft.com/en-us/cli/azure/aks?view=azure-cli-latest#az-aks-update] 命令。az aks update -n myAKSCluster -g myResourceGroup --disable-vpa
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
若要验证垂直 Pod 自动缩放程序 Pod 是否已成功创建,请使用 kubectl get 命令。
kubectl get pods -n kube-system
该命令的输出包括以下特定于 VPA Pod 的结果。 Pod 应显示 running 状态。
NAME READY STATUS RESTARTS AGE
vpa-admission-controller-7867874bc5-vjfxk 1/1 Running 0 41m
vpa-recommender-5fd94767fb-ggjr2 1/1 Running 0 41m
vpa-updater-56f9bfc96f-jgq2g 1/1 Running 0 41m
测试垂直 Pod 自动缩放程序安装
以下步骤将创建包含两个 Pod 的部署,其中每个 Pod 运行单个容器,该容器请求 100 个毫核,并尝试利用数量略高于 500 的毫核。 这些步骤还会创建一个指向部署的 VPA 配置。 VPA 将观察 Pod 的行为,大约五分钟后,将通过更高的 CPU 请求更新 Pod。
创建名为
hamster.yaml
的文件,并将 kubernetes/autoscaler GitHub 存储库中垂直 Pod 自动缩放程序示例的以下清单复制到该文件中。使用 kubectl apply 命令部署
hamster.yaml
垂直 Pod 自动缩放程序示例,并指定 YAML 清单的名称:kubectl apply -f hamster.yaml
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
运行以下 kubectl get 命令以从 hamster 示例应用程序中获取 Pod:
kubectl get pods -l app=hamster
示例输出如下所示:
hamster-78f9dcdd4c-hf7gk 1/1 Running 0 24s hamster-78f9dcdd4c-j9mc7 1/1 Running 0 24s
对其中一个 Pod 使用 kubectl describe 命令以查看其 CPU 和内存预留量。 将“exampleID”替换为上一步骤的输出中返回的 Pod ID 之一。
kubectl describe pod hamster-exampleID
示例输出是有关群集的信息片段:
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。
等待 vpa-updater 启动新的 hamster Pod,这需要几分钟时间。 可以使用 kubectl get 命令监视 Pod。
kubectl get --watch pods -l app=hamster
启动新的 hamster Pod 后,描述运行 kubectl describe 命令的 Pod 并查看已更新的 CPU 和内存预留量。
kubectl describe pod hamster-<exampleID>
示例输出是描述 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 自动缩放程序使用一个更合适的值更正了估算值。
若要查看 VPA 提供的已更新建议,请运行 kubectl describe 命令来描述 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 自动缩放程序请求
当 updateMode 设置为 Auto 时,垂直 Pod 自动缩放使用 VerticalPodAutoscaler
对象在 Pod 上自动设置资源请求。可以根据要求和测试设置不同的值。 在此示例中,updateMode 设置为 Recreate
。
运行以下命令为群集启用 VPA。 将群集名称
myAKSCluster
替换为你的 AKS 群集名称,并将myResourceGroup
替换为群集所在资源组的名称。az aks update -n myAKSCluster -g myResourceGroup --enable-vpa
创建名为
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"]
此清单描述了包含两个 Pod 的部署。 每个 Pod 包含一个请求 100 milliCPU 和 50 MiB 内存的容器。
使用 kubectl create 命令创建 Pod,如以下示例所示:
kubectl create -f azure-autodeploy.yaml
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
运行以下 kubectl get 命令以获取 Pod:
kubectl get pods
输出如以下示例所示,其中显示了 Pod 的名称和状态:
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
创建名为
azure-vpa-auto.yaml
的文件,并将描述VerticalPodAutoscaler
的以下清单复制到其中: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 都属于此VerticalPodAutoscaler
。Recreate
的updateMode
值表示垂直 Pod 自动缩放程序控制器可以删除 Pod,调整 CPU 和内存请求,然后启动新 Pod。使用 kubectl apply 命令将清单应用于群集:
kubectl create -f azure-vpa-auto.yaml
等待几分钟,然后运行以下 kubectl get 命令再次查看正在运行的 Pod:
kubectl get pods
输出如以下示例所示,其中显示了 Pod 名称已更改,并显示了 Pod 状态:
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
使用 Kubectl get 命令获取有关正在运行的 Pod 的详细信息。 将
podName
替换为在上一步骤中检索的某个 Pod 的名称。kubectl get pod podName --output yaml
输出如以下示例所示,其中显示了垂直 Pod 自动缩放程序控制器已将内存请求增加到 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
若要获取有关垂直 Pod 自动缩放程序及其 CPU 和内存建议的详细信息,请使用 kubectl get 命令:
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 或内存目标即可使容器以最佳方式运行。 如果目标 CPU 和内存建议更高,结果可能有所不同。垂直 Pod 自动缩放程序使用
lowerBound
和upperBound
属性来确定是否要删除 Pod 并将其替换为新 Pod。 如果 Pod 中的请求低于下限或高于上限,垂直 Pod 自动缩放程序会删除该 Pod,并将它替换为符合目标属性的 Pod。
垂直 Pod 自动缩放程序的额外推荐器
在 VPA 中,其中一个核心组件是推荐器。 它根据实时资源消耗提供资源使用情况建议。 群集启用 VPA 时,AKS 会部署推荐器。 可以使用与默认映像相同的映像部署自定义推荐器或额外推荐器。 使用自定义推荐器的好处是可以自定义建议逻辑。 使用额外的推荐器,如果有多个 VPA 对象,则可以将 VPA 分区为多个推荐器。
以下示例是应用于现有 AKS 群集的额外推荐器。 然后,将 VPA 对象配置为使用额外的推荐器。
创建名为
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 # nobody 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
使用 kubectl apply 命令部署
extra-recomender.yaml
垂直 Pod 自动缩放程序示例,并指定 YAML 清单的名称。kubectl apply -f extra-recommender.yaml
片刻之后,该命令将会完成,并返回有关群集的 JSON 格式信息。
创建名为
hamnster_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 和内存的自动模式和计算建议来简化 VPA 对象。
使用 kubectl apply 命令部署
hamster_extra-recomender.yaml
示例,并指定 YAML 清单的名称。kubectl apply -f hamster_customized_recommender.yaml
等待 vpa-updater 启动新的 hamster Pod,这需要几分钟时间。 可以使用 kubectl get 命令监视 Pod。
kubectl get --watch pods -l app=hamster
启动新的 hamster Pod 后,描述运行 kubectl describe 命令的 Pod 并查看已更新的 CPU 和内存预留量。
kubectl describe pod hamster-<exampleID>
示例输出是描述 Pod 的信息片段:
State: Running Started: Wed, 28 Sep 2022 15:09:51 -0400 Ready: True Restart Count: 0 Requests: cpu: 587m memory: 262144k Environment: <none>
若要查看 VPA 提供的已更新建议,请运行 kubectl describe 命令来描述 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> Spec: recommenders: Name: customized-recommender
疑难解答
若要诊断 VPA 安装问题,请执行以下步骤。
使用以下命令检查是否所有系统组件都在运行:
kubectl --namespace=kube-system get pods|grep vpa
输出应列出三个 Pod - 推荐器、更新器和允许控制器,状态显示为 Running
。
确认系统组件是否记录任何错误。 对于上一个命令返回的每个 Pod,请运行以下命令:
kubectl --namespace=kube-system logs [pod name] | grep -e '^E[0-9]\{4\}'
通过运行以下命令确认已创建自定义资源定义:
kubectl get customresourcedefinition | grep verticalpodautoscalers
后续步骤
本文介绍了如何自动缩放群集节点的资源利用率(例如 CPU 和内存),以符合应用程序的要求。
还可以使用水平 Pod 自动缩放程序自动调整运行应用程序的 Pod 数。 有关使用水平 Pod 自动缩放程序的步骤,请参阅在 AKS 中缩放应用程序。
请参阅垂直 Pod 自动缩放程序 [API 参考],详细了解相关 VPA 对象的定义。