排查集群自动扩缩器未扩容问题


本页面介绍如何发现和解决 Google Kubernetes Engine (GKE) 集群中的集群自动扩缩器未扩容节点的问题。

本页面适用于希望解决应用或服务出现的意外或负面情况的应用开发者,以及希望防止产品和服务交付中断的平台管理员和运维人员。

了解集群自动扩缩器何时会扩容节点

在继续执行问题排查步骤之前,了解集群自动扩缩器何时会尝试扩容节点可能会有所帮助。集群自动扩缩器仅在现有资源不足时才会添加节点。

集群自动扩缩器每 10 秒检查一次是否存在任何不可调度的 Pod。如果 Kubernetes 调度器因资源不足、节点限制或未满足 Pod 要求而无法将 Pod 放置在任何现有节点上,则 Pod 会变为不可调度状态。

当集群自动扩缩器发现不可调度的 Pod 时,会评估添加节点是否会使 Pod 可以进行调度。如果添加节点会使 Pod 可以进行调度,集群自动扩缩器会向托管式实例组 (MIG) 添加新节点。Kubernetes 调度器随后便可以将 Pod 调度到新预配的节点上。

检查您是否有不可调度的 Pod

如需确定集群是否需要扩容,请检查是否有不可调度的 Pod:

  1. 在 Google Cloud 控制台中,前往工作负载页面。

    转到“工作负载”

  2. 过滤条件字段中,输入 unschedulable,然后按 Enter

    如果列出了任何 Pod,则表示您有不可调度的 Pod。如需排查不可调度的 Pod 问题,请参阅错误:Pod 不可调度。解决不可调度的 Pod 的根本原因通常可以使集群自动扩缩器能够进行扩容。如需识别和解决特定于集群自动扩缩器的错误,请参阅以下部分。

    如果未列出任何 Pod,则集群自动扩缩器无需进行扩容,在按预期正常运行。

检查您之前是否有不可调度的 Pod

如果您要调查过去导致集群自动扩缩器失败的原因,请检查之前是否有不可调度的 Pod:

  1. 在 Google Cloud 控制台中,前往 Logs Explorer 页面。

    转到日志浏览器

  2. 为要查看的日志条目指定时间范围。

  3. 在查询窗格中,输入以下查询:

    logName="projects/PROJECT_ID/logs/events"
    jsonPayload.source.component="default-scheduler"
    jsonPayload.reason="FailedScheduling"
    

    PROJECT_ID 替换为您的项目 ID。

  4. 点击运行查询

    如果列出了任何结果,则表示您在指定的时间范围内有不可调度的 Pod。

检查问题是否是由限制引起的

确认您有不可调度的 Pod 后,请确保集群自动扩缩器的问题不是由集群自动扩缩器的限制之一引起的。

查看错误

您通常可以通过查看错误消息来诊断扩容问题的原因:

在通知中查看错误

如果您发现的问题发生在 72 小时以内,请在 Google Cloud 控制台中查看有关错误的通知。这些通知可提供有关集群自动扩缩器未扩容的原因的宝贵分析洞见,并提供有关如何解决错误以及如何查看相关日志以进行进一步调查的建议。

如需在 Google Cloud 控制台中查看通知,请完成以下步骤:

  1. 在 Google Cloud 控制台中,前往 Kubernetes 集群页面。

    转到 KUBERNETES 集群

  2. 查看通知列。以下通知与扩容问题相关:

    • Can't scale up
    • Can't scale up pods
    • Can't scale up a node pool
  3. 点击相关通知即可看到一个窗格,其中包含导致问题的原因的详细信息以及解决问题的建议措施。

  4. 可选:如需查看此事件的日志,请点击日志。此操作会使您前往 Logs Explorer,其中预先填充了查询,以帮助您进一步调查扩缩事件。如需详细了解扩容事件的工作情况,请参阅查看集群自动扩缩器事件

如果您在通知中查看建议后仍遇到问题,请参阅错误消息表格以获取更多帮助。

在事件中查看错误

如果您发现的问题发生在 72 小时之前,请在 Cloud Logging 中查看事件。如果发生错误,系统通常会在事件中记录相应错误。

如需在 Google Cloud 控制台中查看集群自动扩缩器日志,请完成以下步骤:

  1. 在 Google Cloud 控制台中,前往 Kubernetes 集群页面。

    转到 KUBERNETES 集群

  2. 选择要调查的集群的名称,以查看其集群详情页面。

  3. 集群详情页面上,点击日志标签页。

  4. 日志标签页上,点击自动扩缩器日志标签页以查看日志。

  5. 可选:如需应用更高级的过滤条件来缩小结果范围,请点击页面右侧带有箭头的按钮以在 Logs Explorer 中查看日志。

如需详细了解扩容事件的工作情况,请参阅查看集群自动扩缩器事件。如需了解如何使用 Cloud Logging 的示例,请参阅以下问题排查示例

示例:排查 72 小时以前的问题

以下示例展示了如何调查和解决集群未扩容的问题。

场景:在过去一小时内,某个 Pod 被标记为不可调度。集群自动扩缩器未预配任何新节点来调度该 Pod。

解决方案

  1. 由于问题发生在 72 小时之前,因此您使用 Cloud Logging 而不是通过查看通知消息来调查问题。
  2. 在 Cloud Logging 中,您可以找到集群自动扩缩器事件的日志记录详细信息,如在事件中查看错误中所述。
  3. 您需搜索 triggeringPods 字段中包含您要调查的 Pod 的 scaleUp 事件。您可以过滤日志条目,包括按特定 JSON 字段值进行过滤。如需了解详情,请参阅高级日志查询

  4. 您未找到任何扩容事件。不过,如果您确实找到了相应事件,可以尝试查找包含与 scaleUp 事件相同的 eventIdEventResult。然后,您可以查看 errorMsg 字段并查阅可能出现的 scaleUp 错误消息列表。

  5. 由于您未找到任何 scaleUp 事件,因此您继续搜索 noScaleUp 事件并查看以下字段:

    • unhandledPodGroups:包含有关 Pod(或 Pod 的控制器)的信息。
    • reason:提供可能会阻止纵向扩容的全局原因。
    • skippedMigs:提供可能会跳过某些 MIG 的原因。
  6. 您找到了针对您的 Pod 的 noScaleUp 事件,同时 rejectedMigs 字段中的所有 MIG 都具有相同的 "no.scale.up.mig.failing.predicate" 原因信息 ID 以及下列两个参数:"NodeAffinity""node(s) did not match node selector"

解决方法

查阅错误消息列表后,您会发现由于待处理 Pod 的调度谓词失败,集群自动扩缩器无法扩容节点池。参数为失败谓词的名称以及失败的原因。

为了解决此问题,您会查看相应 Pod 的清单,并发现它有一个节点选择器与集群中的任何 MIG 都不匹配。您可从 Pod 的清单中删除该选择器,然后重新创建 Pod。集群自动扩缩器会添加新节点,Pod 会得到调度。

解决扩容错误

确定错误后,请使用以下各表来帮助了解导致错误的原因以及如何解决该错误。

ScaleUp 错误

您可以在相应 eventResult 事件的 resultInfo.results[].errorMsg 字段中找到针对 scaleUp 事件的事件错误消息。

消息 详细信息 参数 应对措施
"scale.up.error.out.of.resources" 由于某项 Compute Engine 资源(如 GPU 或 CPU)当前不可用,当您尝试在无法容纳您的请求的可用区中请求新资源时,会发生资源错误。 失败 MIG ID。 按照 Compute Engine 文档中的资源可用性问题排查步骤进行操作。
"scale.up.error.quota.exceeded" 由于超出了 Compute Engine 配额,部分 MIG 无法增加,导致 scaleUp 事件失败。 失败 MIG ID。 检查 Google Cloud 控制台中 MIG 的错误标签页,查看超出的配额。了解超出的配额后,请按照说明申请增加配额
"scale.up.error.waiting.for.instances.timeout" 由于超时,托管式实例组的扩容失败。 失败 MIG ID。 此消息应该是暂时性的。 如果它持续存在,请与 Cloud Customer Care 团队联系以进行进一步调查。
"scale.up.error.ip.space.exhausted" 由于某些托管式实例组中的实例用尽了 IP,因此无法扩容。这意味着集群没有足够的未分配 IP 地址空间来用于添加新节点或 Pod。 失败 MIG ID。 请按照 Pod 没有足够的可用 IP 地址空间中的问题排查步骤进行操作。
"scale.up.error.service.account.deleted" 由于服务账号已被删除,因此无法扩容。 失败 MIG ID。 尝试恢复删除的服务账号。 如果该过程未能成功,请与 Cloud Customer Care 团队联系以进行进一步调查。

noScaleUp 事件的原因

当集群中有不可调度的 Pod 且集群自动扩缩器无法扩容集群以调度 Pod 时,系统会定期发出 noScaleUp 事件。noScaleUp 事件是尽力而为事件,无法涵盖所有可能的情况。

NoScaleUp 顶级原因

noScaleUp 事件的顶级原因消息会显示在 noDecisionStatus.noScaleUp.reason 字段中。该消息包含导致集群自动扩缩器无法对集群进行纵向扩容的顶级原因。

消息 详细信息 应对措施
"no.scale.up.in.backoff" 因为扩容处于退避期(暂时阻止),所以未进行扩容。此消息可能会在具有大量 Pod 的扩容事件期间发生。 此消息应该是暂时性的。请过几分钟后再检查此错误。 如果此消息持续存在,请与 Cloud Customer Care 联系以进行进一步调查。

NoScaleUp 顶级节点自动预配原因

noScaleUp 事件的顶级节点自动预配原因消息会显示在 noDecisionStatus.noScaleUp.napFailureReason 字段中。该消息包含导致集群自动扩缩器无法预配新节点池的顶级原因。

消息 详细信息 应对措施
"no.scale.up.nap.disabled"

由于集群级未启用节点自动预配功能,因此节点自动预配功能无法扩容。

如果停用节点自动预配功能,并且如果待处理 Pod 具有任何现有节点池无法满足的要求,则不会自动预配新节点。

查看集群配置,并考虑启用节点自动预配功能

NoScaleUp MIG 级原因

noScaleUp 事件的 MIG 级原因消息会显示在 noDecisionStatus.noScaleUp.skippedMigs[].reasonnoDecisionStatus.noScaleUp.unhandledPodGroups[].rejectedMigs[].reason 字段中。 该消息包含集群自动扩缩器无法增加特定 MIG 大小的原因。

消息 详细信息 参数 应对措施
"no.scale.up.mig.skipped" 由于模拟过程中跳过了 MIG,所以无法对 它进行扩容。 跳过 MIG 的原因(例如,缺少 Pod 要求)。 查看错误消息中包含的参数并解决跳过 MIG 的原因。
"no.scale.up.mig.failing.predicate" 由于待处理 Pod 的调度谓词失败,因此无法扩容节点池。 失败谓词的名称和失败原因。 查看 Pod 要求,例如亲和性规则、污点或容忍设置以及资源要求。

NoScaleUp Pod 组级节点自动预配原因

noScaleUp 事件的 Pod 组级节点自动预配原因消息会显示在 noDecisionStatus.noScaleUp.unhandledPodGroups[].napFailureReasons[] 字段中。该消息包含集群自动扩缩器无法预配新节点池以调度特定 Pod 组的原因。

消息 详细信息 参数 应对措施
"no.scale.up.nap.pod.gpu.no.limit.defined" 节点自动预配无法预配任何节点组,因为待处理 Pod 具有 GPU 请求,但未在集群级定义 GPU 资源限制 请求的 GPU 类型。 查看待处理 Pod 的 GPU 请求,并更新集群级节点自动预配 GPU 限制配置
"no.scale.up.nap.pod.gpu.type.not.supported" 节点自动预配功能没有为 Pod 预配任何节点组,因为它具有未知 GPU 类型的请求。 请求的 GPU 类型。 在待处理 Pod 的配置中检查 GPU 类型,以确保其与受支持的 GPU 类型匹配。
"no.scale.up.nap.pod.zonal.resources.exceeded" 节点自动预配功能没有在此可用区中为 Pod 预配任何节点组,因为这样做会违反集群范围的资源上限、超出可用区中的可用资源或没有适合请求的机器类型。 所考虑的可用区的名称。 查看并更新集群范围的资源上限、Pod 资源请求或节点自动预配的可用区
"no.scale.up.nap.pod.zonal.failing.predicates" 由于谓词失败,节点自动预配功能未在此可用区中为 Pod 预配任何节点组。 所考虑的可用区的名称,以及导致谓词失败的原因。 查看待处理 Pod 的要求,例如亲和性规则、污点、容忍或资源要求。

进行进一步调查

以下部分提供了有关如何使用 Logs Explorer 和 gcpdiag 进一步了解错误的指导。

在 Logs Explorer 中调查错误

如果您想进一步调查错误消息,请查看特定于错误的日志:

  1. 在 Google Cloud 控制台中,前往 Logs Explorer 页面。

    转到日志浏览器

  2. 查询窗格中,输入以下查询:

    resource.type="k8s_cluster"
    log_id("container.googleapis.com/cluster-autoscaler-visibility")
    jsonPayload.resultInfo.results.errorMsg.messageId="ERROR_MESSAGE"
    

    ERROR_MESSAGE 替换为您要调查的消息。例如 scale.up.error.out.of.resources

  3. 点击运行查询

使用 gcpdiag 调试某些错误

gcpdiag 是一种在 Google Cloud技术工程师的支持下创建的开源工具。它不是由官方提供支持的 Google Cloud 产品。

如果您遇到以下某个错误消息,可以使用 gcpdiag 来帮助排查问题:

  • scale.up.error.out.of.resources
  • scale.up.error.quota.exceeded
  • scale.up.error.waiting.for.instances.timeout
  • scale.up.error.ip.space.exhausted
  • scale.up.error.service.account.deleted

如需查看所有 gcpdiag 工具标志的列表和说明,请参阅 gcpdiag 使用说明

解决复杂的扩容错误

以下部分提供了相关指导,用于解决缓解措施涉及多个步骤的错误,以及没有相关集群自动扩缩器事件消息的错误。

问题:Pod 不适合在节点上运行

只有当某个节点具有足够的资源(例如 GPU、内存和存储空间)来满足 Pod 的要求时,集群自动调节器才会将 Pod 调度到该节点上。如需确定这是否为集群自动扩缩器未扩容的原因,请将资源请求与提供的资源进行比较。

以下示例展示了如何检查 CPU 资源,但相同的步骤也适用于 GPU、内存和存储资源。如需将 CPU 请求与预配的 CPU 进行比较,请完成以下步骤:

  1. 在 Google Cloud 控制台中,前往工作负载页面。

    转到“工作负载”

  2. 点击 PodUnschedulable 错误消息。

  3. 详细信息窗格中,点击 Pod 的名称。如果有多个 Pod,请从第一个 Pod 开始,并对每个 Pod 重复以下过程。

  4. 在 Pod 详细信息页面中,前往事件标签页。

  5. 事件标签页中,前往 YAML 标签页。

  6. 记下 Pod 中每个容器的资源请求,以得到资源请求总数。例如,在以下 Pod 配置中,Pod 需要 2 个 vCPU:

    resources:
      limits:
        cpu: "3"
     requests:
        cpu: "2"
    
  7. 查看包含不可调度的 Pod 的集群的节点池详细信息:

    1. 在 Google Cloud 控制台中,前往 Kubernetes 集群页面。

      转到 KUBERNETES 集群

    2. 点击具有 Pods unschedulable 错误消息的集群的名称。

    3. 集群详情页面中,前往节点标签页。

  8. 节点池部分中,记下机器类型列中的值。例如 n1-standard-1

  9. 将资源请求与机器类型提供的 vCPU 进行比较。例如,如果 Pod 请求 2 个 vCPU,但可用节点具有 n1-standard-1 机器类型,则这些节点只有 1 个 vCPU。使用此类配置时,集群自动扩缩器不会触发扩容,因为即使它添加了新节点,此 Pod 也不适合在节点上运行。如需详细了解可用机器类型,请参阅 Compute Engine 文档中的机器家族资源和比较指南

另请注意,节点的可分配资源少于总资源,因为需要一部分资源来运行系统组件。如需详细了解这部分资源的计算方式,请参阅节点可分配资源

如需解决此问题,请确定为工作负载定义的资源请求是否适合您的需求。如果不应更改机器类型,请使用可支持来自 Pod 的请求的机器类型创建节点池。如果 Pod 资源请求不准确,请更新 Pod 的定义,以便 Pod 适合在节点上运行。

问题:健康状况不佳的集群阻止了扩容

如果集群自动扩缩器认为集群健康状况不佳,则可能不会执行扩容。集群健康状况不佳不取决于控制平面的健康状况,而是取决于健康状况良好节点和就绪节点的比率。如果集群中 45% 的节点健康状况不佳或未就绪,集群自动扩缩器会停止所有操作。

如果这是集群自动扩缩器未扩容的原因,则集群自动扩缩器 ConfigMap 中会有一个类型为 Warning 的事件,其中将 ClusterUnhealthy 列为原因。

如需查看 ConfigMap,请运行以下命令:

kubectl describe configmap cluster-autoscaler-status -n kube-system

如需解决此问题,请减少健康状况不佳节点的数量。

也有可能某些节点已就绪,但集群自动扩缩器未将其视为已就绪。当节点上存在前缀为 ignore-taint.cluster-autoscaler.kubernetes.io/ 的污点时,会发生这种情况。只要存在该污点,集群自动扩缩器就会将节点视为 NotReady

如果此行为是由存在 ignore-taint.cluster-autoscaler.kubernetes.io/.* 污点所导致的,请将其移除。

后续步骤