AKS 中的自动 Pod 中断预算管理(预览版)

重要

AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:

AKS 群集升级期间,会通过驱逐 Pod 来清空节点,以便对这些节点重新制作映像或进行替换。 Pod 中断预算(PDB) 通过限制同时不可用的 Pod 数量,在此过程中保护应用程序的可用性。 然而,在 PDB 配置错误或部署没有足够的副本来满足预算时,PDB 也可能完全阻止逐出。 完全没有配置 PDB 的部署则存在相反的问题:没有任何机制能防止其 Pod 被同时逐出,从而增加升级期间发生停机的风险。

自动 PDB 管理是基于 开源项目的 AKS 扩展,可在升级期间自动执行 PDB 管理。 该方法:

  • 自动创建 PDB,用于没有 PDB 的部署,从而在自愿中断期间保护您的工作负载。
  • 当 PDB 阻止已封锁节点上的 Pod 驱逐时,暂时增加副本数,以便满足中断预算并可以继续排空。
  • 逐出完成后将副本数缩减,这样你就无需为升级所需之外的额外容量付费。

结果是,无需强制绕过 PDB 保护或手动解析隔离节点,即可完全可靠地升级。 有关 AKS 升级如何耗尽节点以及 PDB 如何影响该过程的背景,请参阅 AKS 群集升级的工作原理

何时使用自动 PDB 管理

请考虑在以下情况下启用自动 PDB 管理:

  • 部署缺少 PDB。 在升级期间,Pod 可能会在不保证可用性的情况下被逐出,因此存在停机风险。
  • PDB 会阻止节点排空。 minAvailable 等于副本数(或 maxUnavailable: 0)的 PDB 会阻止任何 Pod 被逐出,导致升级失败并出现类似 Cannot evict pod as it would violate the pod's disruption budget 的错误。
  • 副本数量不足,无法满足中断预算要求。 PDB 存在且配置正确,但该部署没有足够的副本来承受哪怕一次驱逐。
  • 您频繁遇到升级排空失败,并且希望采用自动化、主动式的解决方案,而不是手动清理。

在启用自动 PDB 管理之前,请检查群集是否遇到与 PDB 相关的排水故障:

  • Azure活动日志。 在Azure门户中,打开 AKS 群集资源并选择“活动日志”。 查找状态为 Failed 且消息中提及 Pod 中断预算或驱逐错误的失败升级操作。

  • Kubernetes 事件。 运行以下命令以查找最近的逐出和清空事件:

    kubectl get events --sort-by='.lastTimestamp' -A | grep -i "disruption\|evict\|drain"
    

    有关使用 Kubernetes 事件的完整指南,请参阅 Kubernetes 事件

它与其他选项的比较方式

方法 Behavior 权衡
强制升级 完全绕过 PDB 保护 Pod 同时被驱逐和服务中断的风险
不可排空节点行为 封锁操作和隔离操作阻止了这些节点;其他节点上的升级继续进行 升级后需要手动清理隔离节点
过度预配 永久运行额外的部署副本(比工作负载所需的 Pod 更多),使 PDB 始终有余量允许逐出 仅在升级期间才需要的应用 Pod 容量所产生的持续成本
自动 PDB 管理 (预览版) 为未受 PDB 保护的部署创建 PDB,并临时增加副本数以满足 PDB 约束,然后再缩减回原来的数量 需要扩展;仅在清空期间添加暂时性容量

工作原理

PDB 自动管理具有两种互补机制:自动创建 PDB(主动)和排空期间的副本扩缩(响应式)。

自动创建 PDB

启用 PDB 自动创建时(controllerConfig.pdb.create=true),该扩展会持续监视没有 PDB 的部署。 该扩展通过将 PDB 的标签选择器与部署的 Pod 模板标签进行比较来确定匹配项。 这种比较可确保每个部署都只会被保护一次,并避免重复创建 PDB。 在启用的命名空间中找到未受保护的部署时,它会创建 PDB。 对于没有 HPA 或 KEDA 的部署,minAvailable 会被设置为该部署当前的副本数。 对于使用 HPA 或 KEDA 的部署,minAvailable 会跟踪自动扩缩器的最小副本数下限,从而使 PDB 的行为与自动扩缩器的约束保持一致。 扩展会持续协调自动创建的 PDB,因此,如果部署的副本计数发生更改(例如,通过手动更新或外部缩放程序),PDB minAvailable 的值将更新为匹配。 这种保护措施确保在自愿中断期间不会同时逐出 Pod。

自动创建的 PDB 由扩展在整个生命周期内进行管理。 有关所有权、清理以及如何进行手动控制的详细信息,请参阅 PDB 所有权和清理

注释

当每个部署仅由一个自动缩放程序管理时,自动 PDB 管理可以安全地与 HPA 和 KEDA 协调。 有关该扩展如何与各自动扩缩器交互(包括一种不受支持的配置)的详细信息,请参阅 与自动扩缩器(HPA 和 KEDA)的协调

清空期间的副本缩放

该扩展会监视集群中在节点清空操作期间受 PDB 保护的 Pod 无法被逐出的情况。 下面是在典型升级过程中发生的情况:

  1. AKS 将节点封锁 为升级过程的一部分,将其标记为不可计划。
  2. 该扩展会检测节点是否已被封锁,并检查该节点上任何受 PDB 保护的 Pod 的允许中断数是否为零。
  3. 如果 PDB 阻止逐出,扩展会按已封锁节点上受 PDB 保护的 Pod 数量,暂时增加该部署的副本数(最多增加到该部署配置的 maxSurge 上限),从而确保额外扩容量恰到好处,避免过度预配。 额外副本被调度到其他可用节点上。
  4. PDB 允许的中断数超过零,因为正常 Pod 总数现在超过 PDB 的 minAvailable 阈值。
  5. 节点排空正常进行。 逐出 API 现在可以从已封锁节点上移除 Pod,而不违反 PDB。
  6. 逐出信号停止且允许的中断数恢复到大于零之后,该扩展会将部署的副本数缩放回其原始值。 如果仍封锁了更多节点,或者是否正在进行排水,则纵向缩减不会继续。 此条件可防止在多节点排出期间发生不必要的改动。 缩减在冷却期(默认为 60 秒)后自动进行,无需手动干预。

注释

自动 PDB 管理仅适用于 自愿中断 ,例如升级清空和手动封锁/排水操作。 它不会响应节点故障、Pod 崩溃或其他非主动干扰。

与自动缩放程序协调(HPA 和 KEDA)

部署通常由自动缩放程序管理。 为了避免自动缩放程序在逐出完成之前缩减部署的争用条件,扩展会调整自动缩放程序的 最小值 (而不仅仅是副本计数),并在清空完成后还原更改。

配置 扩展激增的方式 扩展的还原方式 注释
仅限部署 直接增加部署的 replicas 还原冷却后的原始副本计数。 未附加自动缩放程序时的默认行为。
部署 + HPA 提高 HPA 的下限 minReplicas,并立即增加一个副本,这样 HPA 就不会在排空过程中又缩容,也无需等待其指标采集周期。 恢复原始的 minReplicas;HPA 自然处理缩减。 与单个 HPA 的安全协调。
部署 + KEDA 提高 minReplicaCount 上的 ScaledObject 并立即添加一个副本,因为 KEDA 有一个额外的延迟跃点(KEDA 同步到其 HPA,然后 HPA 同步到部署)。 恢复为原始的 minReplicaCount;KEDA 及其 HPA 负责缩容。 与单个 KEDA ScaledObject 的安全协调。
部署 + KEDA + 单独的 HPA 不支持。 KEDA 已经创建了自己的 HPA,因此第二个 HPA 会向同一部署产生冲突的写入。 扩展在 Degraded 状态上将自身标记为 EvictionAutoScaler,并且不会增加副本,因为它无法安全地协调两个写入同一目标的自动缩放程序。 检查 EvictionAutoScaler 资源状态,并删除多余的 HPA 以进行修复。

要检查扩展对部署的视图,包括来自不受支持的自动缩放器配置的任何 Degraded 状态:

kubectl get evictionautoscalers -A -o yaml

先决条件

在安装自动 PDB 管理扩展之前,请确保具有以下各项:

  • 运行受支持的 Kubernetes 版本的 AKS 群集。
  • 使用部署的工作负载。 不支持 StatefulSet,不建议对 StatefulSet 使用自动 PDB 管理。
  • Azure CLI 2.64.0 或更高版本。 运行 az --version 以检查。 若要安装或升级,请参阅安装 Azure CLI
  • 在订阅中注册的 Microsoft.KubernetesConfiguration 提供程序。
  • AKS 群集必须使用 托管标识 (而不是服务主体)。 群集扩展不适用于基于服务主体的群集。 有关详细信息,请参阅 AKS 群集扩展

注释

自动 PDB 管理仅作用于 Pod 中断预算和部署副本数。 它与节点池升级设置(如 max-surge、节点排空超时、节点浸泡时间和升级策略(滚动与蓝绿))正交。 适用于群集的任何节点池配置将继续启用此扩展。

扩展权限

自动 PDB 管理扩展程序需要具备在其管理的命名空间中读取和写入 Deployment、Pod Disruption Budget 和 Event 的权限。 该扩展在安装过程中安装自己的服务帐户和 RBAC 角色。 有关角色和权限的完整列表,请参阅GitHub上的项目存储库

注册配置提供程序

如果以前未使用过 Azure Kubernetes 扩展,请注册所需的提供程序:

az feature register --namespace Microsoft.KubernetesConfiguration --name Extensions

# Verify registration status
az feature show --namespace Microsoft.KubernetesConfiguration --name Extensions

# After the feature shows "Registered", refresh the provider
az provider register -n Microsoft.KubernetesConfiguration

安装自动 PDB 管理

自动 PDB 管理作为扩展安装在 AKS 群集上。 根据需求选择安装选项。

基本安装

使用默认设置安装扩展。 在此模式下,扩展会监视 kube-system 命名空间中被 PDB 阻止的逐出事件,但不会自动为未受 PDB 保护的部署创建 PDB。 kube-system 命名空间默认包含在内,因为 AKS 管理的系统组件也使用 PDB,这些 PDB 可能在升级期间阻止节点排空:

az k8s-extension create \
    --cluster-name <cluster-name> \
    --cluster-type managedClusters \
    --extension-type microsoft.evictionautoscaler \
    --name eviction-autoscaler \
    --resource-group <resource-group-name> \
    --release-train stable \
    --auto-upgrade-minor-version true

安装时为特定命名空间自动创建 PDB

启用自动 PDB 创建并指定扩展应保护的命名空间。 这是适用于大多数群集的推荐配置:

az k8s-extension create \
    --cluster-name <cluster-name> \
    --cluster-type managedClusters \
    --extension-type microsoft.evictionautoscaler \
    --name eviction-autoscaler \
    --resource-group <resource-group-name> \
    --release-train stable \
    --configuration-settings controllerConfig.pdb.create=true controllerConfig.namespaces.actionedNamespaces="{kube-system,production}" \
    --auto-upgrade-minor-version true

使用群集范围的保护进行安装

在所有命名空间中启用自动 PDB 创建:

az k8s-extension create \
    --cluster-name <cluster-name> \
    --cluster-type managedClusters \
    --extension-type microsoft.evictionautoscaler \
    --name eviction-autoscaler \
    --resource-group <resource-group-name> \
    --release-train stable \
    --configuration-settings controllerConfig.pdb.create=true controllerConfig.namespaces.enabledByDefault=true \
    --auto-upgrade-minor-version true

配置选项

以下设置控制自动 PDB 管理的行为方式:

设置 说明 默认
controllerConfig.pdb.create 为尚未配置 PDB 的部署自动创建 PDB。 false
controllerConfig.namespaces.enabledByDefault 在所有命名空间中启用自动 PDB 管理,包括已存在的命名空间和以后创建的任何命名空间。 false
controllerConfig.namespaces.actionedNamespaces enabledByDefaultfalse 时启用的命名空间列表,以逗号分隔。 命名空间数量没有硬性限制,但应用 Kubernetes API 对象大小限制(每对象约 1 MiB)。 {kube-system}

常见配置模式

图案 Settings 用例
保守 pdb.create=falseenabledByDefault=falseactionedNamespaces={kube-system} 你手动管理 PDB,并且希望仅为系统工作负载自动缩放。
定向自动保护 (建议) pdb.create=trueenabledByDefault=falseactionedNamespaces={production,staging} 你需要在特定命名空间中创建和自动缩放 PDB。
群集范围的保护 pdb.create=trueenabledByDefault=true 希望每个命名空间都自动受到保护。
仅监控 pdb.create=falseenabledByDefault=true 您希望在所有命名空间中启用自动扩缩容,但由您自行管理 PDB。

命名空间控制

该扩展根据 enabledByDefault 设置以两种模式之一运行。

两个互补的控制项决定扩展对哪些命名空间生效:

  • controllerConfig.namespaces.actionedNamespaces 在安装时设置基线列表,是启用已知命名空间集的最简单方法。
  • eviction-autoscaler.azure.com/enable (或disable) 命名空间注释允许群集操作员选择在运行时进出命名空间,而无需重新安装扩展。

选择启用模式(默认)

enabledByDefaultfalse 时,仅启用 actionedNamespaces 中列出的命名空间。 可以通过添加注释单独启用其他命名空间:

apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace
  annotations:
    eviction-autoscaler.azure.com/enable: "true"

选择退出模式

enabledByDefaulttrue 时,将启用所有命名空间。 可以通过添加批注来排除特定命名空间:

apiVersion: v1
kind: Namespace
metadata:
  name: my-excluded-namespace
  annotations:
    eviction-autoscaler.azure.com/enable: "false"

排除特定部署

若要防止扩展为特定部署创建 PDB,请将以下注释添加到部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  annotations:
    eviction-autoscaler.azure.com/pdb-create: "false"

注释

自动 PDB 管理会自动跳过针对其滚动更新策略中具有 maxUnavailable (非 0)的部署的 PDB 创建,因为此类部署已经容忍某种级别的停机时间。

自动创建 PDB

如果 controllerConfig.pdb.create 设置为 true,该扩展将为满足以下所有条件的部署创建 PDB:

  • 该部署尚不存在与之匹配的 PDB。
  • 部署位于已启用的命名空间中。
  • 该部署不会因 eviction-autoscaler.azure.com/pdb-create: "false" 注解而被排除。

自动创建的 PDB 会根据工作负载的扩缩来源设置 minAvailable。 对于没有 HPA 或 KEDA 的部署, minAvailable 匹配部署的当前副本计数(不包括扩展添加的任何激增副本)。 对于启用了 HPA 或 KEDA 的部署,minAvailable 与自动扩缩器的最小副本下限保持一致。 这意味着逐出被阻止,直到扩展增加部署的副本数,此时额外的副本满足预算并允许排空继续。

PDB 所有权和清理

由该扩展创建的 PDB 带有 ownedBy: EvictionAutoScaler 注释。 这些控制器拥有的 PDB 会在以下情况下自动删除:

  • 父级部署已被删除。
  • 命名空间将从扩展的范围中删除。
  • 扩展 已从群集中删除。 带有 ownedBy: EvictionAutoScaler 注解的 PDB 会由 Kubernetes 垃圾回收机制清理。

你手动创建的 PDB 永远不会被扩展修改或删除。

若要手动控制扩展创建的 PDB,请删除所有权注释。 删除此批注后,该扩展不再管理该 PDB,并且你负责更新或删除它:

kubectl annotate pdb <pdb-name> -n <namespace> ownedBy-

验证安装

安装扩展后,请验证自动 PDB 管理是否正常工作。

  1. 检查是否已创建 PDB,用于已启用的命名空间中的部署。 筛选出由该扩展创建的 PDB:

    kubectl get pdb -A -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace,MIN-AVAILABLE:.spec.minAvailable,OWNER:.metadata.annotations.ownedBy | grep EvictionAutoScaler
    
  2. 检查自动管理 PDB 的自定义资源

    kubectl get evictionautoscalers --all-namespaces
    
  3. 使用节点线进行测试 (可选)。 在测试或预生产环境中,封锁一个节点并验证扩展会增加部署的副本数,并且 PDB 的允许中断数升至零以上:

    # Cordon a node
    NODE=$(kubectl get pods -n <namespace> -l app=<app-label> -o=jsonpath='{.items[0].spec.nodeName}')
    kubectl cordon $NODE
    
    # Watch for automatic PDB management events
    kubectl get events -n <namespace> --sort-by='.lastTimestamp'
    
    # Check that the deployment scaled up
    kubectl get pods -n <namespace>
    
    # Verify PDB allowed disruptions
    kubectl get poddisruptionbudget <pdb-name> -n <namespace> -o yaml
    
    # After verification, uncordon the node
    kubectl uncordon $NODE
    

更新或删除扩展

更新配置

若要更改配置设置,请使用新设置删除并重新创建扩展:

# Delete the existing extension
az k8s-extension delete \
    --resource-group <resource-group-name> \
    --cluster-name <cluster-name> \
    --cluster-type managedClusters \
    --name eviction-autoscaler \
    --yes

# Recreate with new configuration
az k8s-extension create \
    --cluster-name <cluster-name> \
    --cluster-type managedClusters \
    --extension-type microsoft.evictionautoscaler \
    --name eviction-autoscaler \
    --resource-group <resource-group-name> \
    --release-train stable \
    --configuration-settings controllerConfig.pdb.create=true controllerConfig.namespaces.enabledByDefault=true \
    --auto-upgrade-minor-version true

删除扩展

若要卸载自动 PDB 管理,请执行以下操作:

az k8s-extension delete \
    --resource-group <resource-group-name> \
    --cluster-name <cluster-name> \
    --cluster-type managedClusters \
    --name eviction-autoscaler \
    --yes

注释

删除扩展时,会自动清理自动创建的 PDB(标有 ownedBy: EvictionAutoScaler 批注)。 有关详细信息,请参阅 PDB 所有权和清理

限制和注意事项

  • 配置更新需要删除并重新创建扩展。
  • 自动 PDB 管理仅适用于 部署不支持 StatefulSet,不建议将此扩展用于 StatefulSets。
  • 自动 PDB 管理不会替代或修改现有的 PDB。 它通过调整副本数量与它们协同工作。
  • 自动 PDB 管理与每个部署的单个自动扩缩器(HPA KEDA)协同工作。 由 KEDA 单独 HPA 管理的部署不受支持;扩展将自身标记为 Degraded 并跳过副本激增。 请参阅 与自动缩放程序(HPA 和 KEDA)的协调
  • 自动 PDB 管理独立于节点池升级设置。 像 max-surge、节点排空超时、节点静置时间以及升级策略(滚动升级或蓝绿部署)这样的设置,无需更改即可使此扩展正常工作,而且该扩展也不会改变这些设置的行为。
  • 临时副本扩容需要群集内有可用容量。 如果没有节点能容纳额外的 Pod,请考虑启用群集自动缩放程序节点自动预配 (NAP),以便可以预配新节点。

Troubleshooting

有关症状、原因和解决方法,请参阅 AKS 故障排除中心:排查Azure Kubernetes 服务问题

若要直接在群集上检查扩展活动,请运行:

kubectl get evictionautoscalers -A -o yaml
kubectl get events -A --sort-by='.lastTimestamp'