通过灵活启动(带已排队的预配)运行大规模工作负载


本页面介绍了如何使用灵活启动(带已排队的预配)(由动态工作负载调度器提供支持)优化 GPU 大规模批量工作负载和 AI 工作负载的 GPU 可获取性。

在阅读本页面之前,请确保您熟悉以下内容:

本指南适用于机器学习 (ML) 工程师、平台管理员和运维人员,以及对使用 Kubernetes 容器编排功能运行批量工作负载感兴趣的数据和 AI 专家。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务

灵活启动(带已排队的预配)的工作原理

如果使用灵活启动(带已排队的预配),GKE 会同时分配所有请求的资源。灵活启动(带已排队的预配)使用以下工具:

如需使用灵活启动(带已排队的预配),您必须在创建节点池时添加 --flex-start--enable-queued-provisioning 标志。

最佳实践

如果工作负载满足以下条件,请使用“灵活启动(带已排队的预配)”来处理大规模批处理和 AI 工作负载:

  • 工作负载的开始时间灵活。
  • 您的工作负载需要同时在多个节点上运行。

对于可在单个节点上运行的较小工作负载,请使用灵活启动。如需详细了解如何在 GKE 中预配 GPU,请参阅为 AI 工作负载获取加速器

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

使用启用了灵活启动(带已排队的预配)的节点池

本部分仅适用于 Standard 集群。

您可以使用以下任一方法来指定灵活启动(带已排队的预配)可用于集群中的特定节点池:

创建节点池

使用 gcloud CLI 创建一个启用了灵活启动(带已排队的预配)的节点池:

gcloud container node-pools create NODEPOOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=LOCATION \
    --enable-queued-provisioning \
    --accelerator type=GPU_TYPE,count=AMOUNT,gpu-driver-version=DRIVER_VERSION \
    --machine-type=MACHINE_TYPE \
    --flex-start \
    --enable-autoscaling  \
    --num-nodes=0   \
    --total-max-nodes TOTAL_MAX_NODES  \
    --location-policy=ANY  \
    --reservation-affinity=none  \
    --no-enable-autorepair

替换以下内容:

  • NODEPOOL_NAME:您为节点池选择的名称。
  • CLUSTER_NAME:集群的名称。
  • LOCATION:集群的 Compute Engine 区域,例如 us-central1
  • GPU_TYPEGPU 类型
  • AMOUNT:要挂接到节点池中节点的 GPU 数量。
  • DRIVER_VERSION:要安装的 NVIDIA 驱动程序版本。可以是以下各项之一:
    • default:为您的 GKE 版本安装默认驱动程序版本。
    • latest:为您的 GKE 版本安装最新可用的驱动程序版本。仅适用于使用 Container-Optimized OS 的节点。
  • TOTAL_MAX_NODES:整个节点池自动扩缩的节点数上限。
  • MACHINE_TYPE:节点的 Compute Engine 机器类型。

    最佳实践

    使用加速器优化机器类型可提高 AI/ML 工作负载的性能和效率。

您可以视需要使用以下标志:

  • --node-locations=COMPUTE_ZONES:GKE 在其中创建 GPU 节点的一个或多个可用区的英文逗号分隔列表。可用区必须与集群位于同一区域。选择有可用 GPU 的可用区。
  • --enable-gvnic:此标志用于在 GPU 节点池上启用 gVNIC,以提高网络流量速度。

此命令会创建具有以下配置的节点池:

  • --flex-start 标志与 --enable-queued-provisioning 标志结合使用时,会指示 GKE 创建一个启用了灵活启动(带已排队的预配)的节点池,并向该节点池添加 cloud.google.com/gke-queued 污点。
  • GKE 支持排队预配和集群自动扩缩。
  • 节点池最初没有节点。
  • --no-enable-autorepair 标志会停用自动修复功能,这可能会中断在修复后的节点上运行的工作负载。

启用节点自动预配功能,以创建用于灵活启动(带已排队的预配)的节点池

对于运行 1.29.2-gke.1553000 版或更高版本的集群,您可以使用节点自动预配来管理节点池,以实现灵活启动(带已排队的预配)。启用节点自动预配后,GKE 会创建包含关联工作负载所需资源的节点池。

如需启用节点自动预配功能,请考虑以下设置,并完成预配 GPU 限制中的步骤:

  • 启用该功能时,请指定灵活启动(带已排队的预配)所需的资源。如需列出可用的 resourceTypes,请运行 gcloud compute accelerator-types list 命令。
  • 使用 --no-enable-autoprovisioning-autorepair 标志可停用节点自动修复功能。
  • 允许 GKE 在自动预配的 GPU 节点中自动安装 GPU 驱动程序。如需了解详情,请参阅将节点自动预配与 GPU 搭配使用来安装驱动程序

通过灵活启动(带已排队的预配)运行批处理和 AI 工作负载

如需通过灵活启动(带已排队的预配)运行批处理工作负载,请使用以下任一配置:

最佳实践

使用 Kueue 通过灵活启动(带已排队的预配)运行批处理和 AI 工作负载。

使用 Kueue 的作业的灵活启动(带已排队的预配)

以下部分介绍了如何为使用 Kueue 的作业配置灵活启动(带已排队的预配):

  • 灵活启动(带已排队的预配)节点池设置。
  • 预留和灵活启动(带已排队的预配)节点池设置。

本部分使用 ai-on-gke 仓库的 dws-examples 目录中的示例。我们已根据 Apache2 许可在 dws-examples 目录中发布示例。

您需要拥有管理员权限才能安装 Kueue。如需获得这些权限,请确保您已获得 IAM 角色 roles/container.admin。如需详细了解 GKE IAM 角色,请参阅创建 IAM 允许政策指南

准备环境

  1. 在 Cloud Shell 中,运行以下命令:

    git clone https://github.com/GoogleCloudPlatform/ai-on-gke
    cd ai-on-gke/tutorials-and-examples/workflow-orchestration/dws-examples
    
  2. 在集群中安装最新 Kueue 版本:

    VERSION=KUEUE_VERSION
    kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    

    KUEUE_VERSION 替换为最新版 Kueue。

如果您在 0.7.0 之前的版本中使用 Kueue,请通过将 ProvisioningACC 特性门控设置为 true 来更改 Kueue 特性门控配置。如需详细了解说明和默认门控值,请参阅 Kueue 的特性门控。如需详细了解 Kueue 安装,请参阅安装

为动态工作负载调度器节点池专用设置创建 Kueue 资源

使用以下清单时,创建名为 dws-cluster-queue集群级队列和名为 dws-local-queueLocalQueue 命名空间。在此命名空间中引用 dws-cluster-queue 队列的作业使用灵活启动(带已排队的预配)来获取 GPU 资源。

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "default-flavor"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: AdmissionCheck
metadata:
  name: dws-prov
spec:
  controllerName: kueue.x-k8s.io/provisioning-request
  parameters:
    apiGroup: kueue.x-k8s.io
    kind: ProvisioningRequestConfig
    name: dws-config
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ProvisioningRequestConfig
metadata:
  name: dws-config
spec:
  provisioningClassName: queued-provisioning.gke.io
  managedResources:
    - nvidia.com/gpu
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "dws-cluster-queue"
spec:
  namespaceSelector: {}
  resourceGroups:
    - coveredResources: ["cpu", "memory", "nvidia.com/gpu", "ephemeral-storage"]
      flavors:
        - name: "default-flavor"
          resources:
            - name: "cpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "memory"
              nominalQuota: 1000000000Gi # "Infinite" quota
            - name: "nvidia.com/gpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "ephemeral-storage"
              nominalQuota: 1000000000Ti # "Infinite" quota
  admissionChecks:
    - dws-prov
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: "default"
  name: "dws-local-queue"
spec:
  clusterQueue: "dws-cluster-queue"
---
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  labels:
    control-plane: controller-manager
  name: controller-manager-metrics-monitor
  namespace: kueue-system
spec:
  endpoints:
    - path: /metrics
      port: 8080
      scheme: http
      interval: 30s
  selector:
    matchLabels:
      control-plane: controller-manager
---

此集群的队列具有较高的配额限制,并且仅启用了灵活启动(带已排队的预配)集成。如需详细了解 Kueue API 以及如何设置限制,请参阅 Kueue 概念

部署 LocalQueue:

kubectl create -f ./dws-queues.yaml

输出类似于以下内容:

resourceflavor.kueue.x-k8s.io/default-flavor created
admissioncheck.kueue.x-k8s.io/dws-prov created
provisioningrequestconfig.kueue.x-k8s.io/dws-config created
clusterqueue.kueue.x-k8s.io/dws-cluster-queue created
localqueue.kueue.x-k8s.io/dws-local-queue created

如果您要运行在其他命名空间中使用灵活启动(带已排队的预配)的作业,可以使用上述模板创建其他 LocalQueues

运行 Job

在以下清单中,示例作业使用灵活启动(带已排队的预配):

apiVersion: batch/v1
kind: Job
metadata:
  name: sample-job
  namespace: default
  labels:
    kueue.x-k8s.io/queue-name: dws-local-queue
  annotations:
    provreq.kueue.x-k8s.io/maxRunDurationSeconds: "600"
spec:
  parallelism: 1
  completions: 1
  suspend: true
  template:
    spec:
      nodeSelector:
        cloud.google.com/gke-nodepool: NODEPOOL_NAME
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: dummy-job
          image: gcr.io/k8s-staging-perf-tests/sleep:v0.0.3
          args: ["120s"]
          resources:
            requests:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
            limits:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
      restartPolicy: Never

此清单包含以下与灵活启动(带已排队的预配)配置相关的字段:

  • kueue.x-k8s.io/queue-name: dws-local-queue 标签指示 GKE 由 Kueue 负责编排该 Job。此标签还定义了 Job 排入的队列。
  • suspend: true 标志指示 GKE 创建 Job 资源,但尚不调度 Pod。在节点准备好执行 Job 时,Kueue 会将此标志更改为 false
  • nodeSelector 会告知 GKE 仅在指定的节点池上调度作业。该值应与启用了已排队预配的节点池的名称 NODEPOOL_NAME 匹配。
  1. 运行 Job:

    kubectl create -f ./job.yaml
    

    输出类似于以下内容:

    job.batch/sample-job created
    
  2. 检查作业的状态:

    kubectl describe job sample-job
    

    输出类似于以下内容:

    Events:
      Type    Reason            Age    From                        Message
      ----    ------            ----   ----                        -------
      Normal  Suspended         5m17s  job-controller              Job suspended
      Normal  CreatedWorkload   5m17s  batch/job-kueue-controller  Created Workload: default/job-sample-job-7f173
      Normal  Started           3m27s  batch/job-kueue-controller  Admitted by clusterQueue dws-cluster-queue
      Normal  SuccessfulCreate  3m27s  job-controller              Created pod: sample-job-9qsfd
      Normal  Resumed           3m27s  job-controller              Job resumed
      Normal  Completed         12s    job-controller              Job completed
    

灵活启动(带已排队的预配)的 Kueue 集成还支持开源生态系统中提供的其他工作负载类型,如下所示:

  • RayJob
  • JobSet v0.5.2 或更高版本
  • Kubeflow MPIJob、TFJob、PyTorchJob.
  • 工作流编排器常用的 Kubernetes Pod
  • Flux 迷你集群

如需详细了解此支持,请参阅 Kueue 的批处理用户

为预留和动态工作负载调度器节点池设置创建 Kueue 资源

使用以下清单,您可以创建两个与两个不同的节点池(reservation-nodepooldws-nodepool)相关联的 ResourceFlavors。这些节点池的名称仅作示例之用。根据您的节点池配置修改这些名称。此外,在 ClusterQueue 配置中,传入作业会尝试使用 reservation-nodepool;如果容量不足,则这些作业使用动态工作负载调度器获取 GPU 资源。

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "reservation"
spec:
  nodeLabels:
    cloud.google.com/gke-nodepool: "reservation-nodepool" # placeholder value
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: "dws"
spec:
  nodeLabels:
    cloud.google.com/gke-nodepool: "dws-nodepool" # placeholder value
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: "cluster-queue"
spec:
  namespaceSelector: {} # match all.
  resourceGroups:
    - coveredResources: ["cpu", "memory", "nvidia.com/gpu"]
      flavors:
        - name: "reservation" # first we try reservation
          resources:
            - name: "cpu"
              nominalQuota: 9
            - name: "memory"
              nominalQuota: 36Gi
            - name: "nvidia.com/gpu"
              nominalQuota: 9
        - name: "dws" # if reservation is saturated we try dws
          resources:
            - name: "cpu"
              nominalQuota: 1000000000 # "Infinite" quota
            - name: "memory"
              nominalQuota: 1000000000Gi # "Infinite" quota
            - name: "nvidia.com/gpu"
              nominalQuota: 1000000000 # "Infinite" quota
  admissionChecksStrategy:
    admissionChecks:
      - name: "dws-prov"
        onFlavors: [dws]
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: "default"
  name: "user-queue"
spec:
  clusterQueue: "cluster-queue"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: AdmissionCheck
metadata:
  name: dws-prov
spec:
  controllerName: kueue.x-k8s.io/provisioning-request
  parameters:
    apiGroup: kueue.x-k8s.io
    kind: ProvisioningRequestConfig
    name: dws-config
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ProvisioningRequestConfig
metadata:
  name: dws-config
spec:
  provisioningClassName: queued-provisioning.gke.io
  managedResources:
    - nvidia.com/gpu

此集群的队列具有较高的配额限制,并且仅启用了灵活启动(带已排队的预配)集成。如需详细了解 Kueue API 以及如何设置限制,请参阅 Kueue 概念

使用以下命令部署清单:

kubectl create -f ./dws_and_reservation.yaml

输出类似于以下内容:

resourceflavor.kueue.x-k8s.io/reservation created
resourceflavor.kueue.x-k8s.io/dws created
clusterqueue.kueue.x-k8s.io/cluster-queue created
localqueue.kueue.x-k8s.io/user-queue created
admissioncheck.kueue.x-k8s.io/dws-prov created
provisioningrequestconfig.kueue.x-k8s.io/dws-config created

运行 Job

与上述设置相反,此清单不包含 nodeSelector 字段,因为它由 Kueue 填充,具体取决于 ClusterQueue 中的可用容量。

apiVersion: batch/v1
kind: Job
metadata:
  generateName: sample-job-
  namespace: default
  labels:
    kueue.x-k8s.io/queue-name: user-queue
  annotations:
    provreq.kueue.x-k8s.io/maxRunDurationSeconds: "600"
spec:
  parallelism: 1
  completions: 1
  suspend: true
  template:
    spec:
      tolerations:
        - key: "nvidia.com/gpu"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: dummy-job
          image: gcr.io/k8s-staging-perf-tests/sleep:v0.0.3
          args: ["120s"]
          resources:
            requests:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
            limits:
              cpu: "100m"
              memory: "100Mi"
              nvidia.com/gpu: 1
      restartPolicy: Never
  1. 运行 Job:

    kubectl create -f ./job-without-node-selector.yaml
    

    输出类似于以下内容:

    job.batch/sample-job-v8xwm created
    

如需确定作业使用的节点池,您需要了解作业使用的 ResourceFlavor

问题排查

如需详细了解 Kueue 的问题排查,请参阅排查 Kueue 中的 Provisioning Request 问题

不使用 Kueue 的作业的灵活启动(带已排队的预配)

定义 ProvisioningRequest 对象

通过 Provisioning Request 为每个作业创建请求。灵活启动(带已排队的预配)不会启动 Pod,只会预配节点。

  1. 创建以下 provisioning-request.yaml 清单:

    标准

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
      labels:
        cloud.google.com/apply-warden-policies: "true"
    template:
      spec:
        nodeSelector:
          cloud.google.com/gke-nodepool: NODEPOOL_NAME
          cloud.google.com/gke-flex-start: "true"
        tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
        containers:
          - name: pi
            image: perl
            command: ["/bin/sh"]
            resources:
              limits:
                cpu: "700m"
                nvidia.com/gpu: 1
              requests:
                cpu: "700m"
                nvidia.com/gpu: 1
        restartPolicy: Never
    ---
    apiVersion: autoscaling.x-k8s.io/API_VERSION
    kind: ProvisioningRequest
    metadata:
      name: PROVISIONING_REQUEST_NAME
      namespace: NAMESPACE_NAME
    spec:
      provisioningClassName: queued-provisioning.gke.io
      parameters:
        maxRunDurationSeconds: "MAX_RUN_DURATION_SECONDS"
      podSets:
      - count: COUNT
        podTemplateRef:
          name: POD_TEMPLATE_NAME
    

    替换以下内容:

    • API_VERSION:API 的版本,可以是 v1v1beta1。为了保持稳定并使用最新功能,我们建议您使用 v1
    • NAMESPACE_NAME:Kubernetes 命名空间的名称。命名空间必须与 Pod 的命名空间相同。
    • PROVISIONING_REQUEST_NAMEProvisioningRequest 的名称。您将在 Pod 注解中引用此名称。
    • MAX_RUN_DURATION_SECONDS:(可选)节点的最长运行时(以秒为单位),最长为 7 天(默认值)。如需了解详情,请参阅灵活启动(带已排队的预配)的工作原理。创建请求后,您无法更改此值。GKE 1.28.5-gke.1355000 版或更高版本支持此字段。
    • COUNT:请求的 Pod 数量。节点以原子方式调度到一个可用区中。
    • POD_TEMPLATE_NAMEPodTemplate 的名称。
    • NODEPOOL_NAME:您为节点池选择的名称。 如果您想使用自动预配的节点池,请移除此参数。

    GKE 可能会在创建 Pod 期间对其应用验证和变更。cloud.google.com/apply-warden-policies 标签可让 GKE 对 PodTemplate 对象应用相同的验证和变更。GKE 需要此标签才能计算 Pod 的节点资源需求。灵活启动(带已排队的预配)集成仅支持一个 PodSet 规范。如果您想混合使用不同的 Pod 模板,请使用请求的资源最多的模板。不支持混用不同的机器类型,例如使用不同 GPU 类型的虚拟机。

    节点自动预配

    apiVersion: v1
    kind: PodTemplate
    metadata:
      name: POD_TEMPLATE_NAME
      namespace: NAMESPACE_NAME
      labels:
        cloud.google.com/apply-warden-policies: "true"
    template:
      spec:
        nodeSelector:
          cloud.google.com/gke-accelerator: GPU_TYPE
          cloud.google.com/gke-flex-start: "true"
        tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
        containers:
          - name: pi
            image: perl
            command: ["/bin/sh"]
            resources:
              limits:
                cpu: "700m"
                nvidia.com/gpu: 1
              requests:
                cpu: "700m"
                nvidia.com/gpu: 1
        restartPolicy: Never
    ---
    apiVersion: autoscaling.x-k8s.io/API_VERSION
    kind: ProvisioningRequest
    metadata:
      name: PROVISIONING_REQUEST_NAME
      namespace: NAMESPACE_NAME
    spec:
      provisioningClassName: queued-provisioning.gke.io
      parameters:
        maxRunDurationSeconds: "MAX_RUN_DURATION_SECONDS"
      podSets:
      - count: COUNT
        podTemplateRef:
          name: POD_TEMPLATE_NAME
    

    替换以下内容:

    • API_VERSION:API 的版本,可以是 v1v1beta1。为了保持稳定并使用最新功能,我们建议您使用 v1
    • NAMESPACE_NAME:Kubernetes 命名空间的名称。命名空间必须与 Pod 的命名空间相同。
    • PROVISIONING_REQUEST_NAMEProvisioningRequest 的名称。您将在 Pod 注解中引用此名称。
    • MAX_RUN_DURATION_SECONDS:(可选)节点的最长运行时(以秒为单位),最长为 7 天(默认值)。如需了解详情,请参阅灵活启动(带已排队的预配)的工作原理。创建请求后,您无法更改此值。GKE 1.28.5-gke.1355000 版或更高版本支持此字段。
    • COUNT:请求的 Pod 数量。节点以原子方式调度到一个可用区中。
    • POD_TEMPLATE_NAMEPodTemplate 的名称。
    • GPU_TYPE:GPU 硬件的类型。

    GKE 可能会在创建 Pod 期间对其应用验证和变更。cloud.google.com/apply-warden-policies 标签可让 GKE 对 PodTemplate 对象应用相同的验证和变更。GKE 需要此标签才能计算 Pod 的节点资源需求。

  2. 应用清单:

    kubectl apply -f provisioning-request.yaml
    

配置 pod

本部分使用 Kubernetes 作业来配置 Pod。但是,您也可以使用 Kubernetes JobSet 或任何其他框架(例如 Kubeflow、Ray 或自定义控制器)。在作业规范中,使用以下注解将 Pod 关联到 ProvisioningRequest

apiVersion: batch/v1
kind: Job
spec:
  template:
    metadata:
      annotations:
        autoscaling.x-k8s.io/consume-provisioning-request: PROVISIONING_REQUEST_NAME
        autoscaling.x-k8s.io/provisioning-class-name: "queued-provisioning.gke.io"
    spec:
      ...

Pod 注解键 consume-provisioning-request 定义要使用的 ProvisioningRequest。GKE 使用 consume-provisioning-requestprovisioning-class-name 注释来执行以下操作:

  • 仅在通过灵活启动(带已排队的预配)预配的节点中调度 Pod。
  • 为了避免在 Pod 和灵活启动(带已排队的预配)之间重复计算资源请求,集群自动扩缩器会使用排队预配。
  • 注入 safe-to-evict: false 注释,以防止集群自动扩缩器在节点之间移动 Pod 并中断批处理计算。您可以通过在 Pod 注解中指定 safe-to-evict: true 来更改此行为。

观察 Provisioning Request 的状态

Provisioning Request 的状态定义是否可以安排 Pod。您可以使用 Kubernetes 监视功能高效地观察更改,或您已用来跟踪 Kubernetes 对象状态的其他工具。下表介绍了 Provisioning Request 请求的可能状态以及每种可能的结果:

Provisioning Request 状态 说明 可能的结果
待处理 该请求尚未被发现并且未被处理。 处理完毕后,请求会转换为 AcceptedFailed 状态。
Accepted=true 请求被接受,正在等待资源变为可用状态。 如果找到资源并预配了节点,请求应转换为 Provisioned 状态;否则,请求应转换为 Failed 状态。
Provisioned=true 节点已准备就绪。 您可以在 10 分钟内启动 Pod 以使用预配的资源。在此时间之后,集群自动扩缩器会将这些节点视为不需要,并将其移除。
Failed=true 由于出现错误,无法预配节点。Failed=true 是一种终端状态。 根据条件的 ReasonMessage 字段中的信息排查问题。创建并重试新的 Provisioning Request 请求。
Provisioned=false 节点尚未完成预配。

如果 Reason=NotProvisioned,则表示这是在所有资源可用之前的临时状态。

如果 Reason=QuotaExceeded,请根据此原因和条件 Message 字段中的信息排查相应情况。您可能需要申请增加配额。如需了解详情,请参阅检查 Provisioning Request 是否受配额限制部分。此 Reason 仅适用于 GKE 1.29.2-gke.1181000 版或更高版本。

如果 Reason=ResourcePoolExhausted,且 Message 包含 Expected time is indefinite,请选择其他可用区或区域,或调整所请求的资源。

启动 Pod

当 Provisioning Request 请求达到 Provisioned=true 状态时,您可以运行作业来启动 Pod。这样可避免因待处理或失败的请求而导致无法调度的 Pod 大量增加,从而影响 kube-scheduler 和集群自动扩缩器的性能。

或者,如果您不介意有无法调度的 Pod,则可以与 Provisioning Request 请求并行创建 Pod。

取消 Provisioning Request 请求

如需在预配之前取消请求,您可以删除 ProvisioningRequest

kubectl delete provreq PROVISIONING_REQUEST_NAME -n NAMESPACE

在大多数情况下,删除 ProvisioningRequest 会阻止创建节点。不过,根据时间安排,例如如果节点已在预配,则这些节点可能仍会最终创建。在这些情况下,如果 10 分钟后未创建任何 Pod,集群自动扩缩器会移除节点。

排查配额问题

由 Provisioning Request 请求预配的所有虚拟机都使用抢占式配额

处于 Accepted 状态的 ProvisioningRequests 的数量受专用配额限制。您可以为每个项目配置配额,每个区域对应一个配额配置。

在 Google Cloud 控制台中检查配额

如需在Google Cloud 控制台中检查配额限制的名称和当前用量,请按以下步骤操作:

  1. 前往 Google Cloud 控制台中的配额页面:

    转到“配额”

  2. 过滤条件框中,选择指标属性,输入 active_resize_requests,然后按 Enter 键。

默认值为 100。如需增加配额,请按照申请配额调整中列出的步骤操作。

检查 Provisioning Request 请求是否受配额限制

如果您的 Provisioning Request 请求的完成时间超出预期,请检查该请求是否受配额限制。您可能需要申请增加配额。

对于运行 1.29.2-gke.1181000 版或更高版本的集群,请检查是否存在特定的配额限制,导致您的请求无法得到满足:

kubectl describe provreq PROVISIONING_REQUEST_NAME \
    --namespace NAMESPACE

输出类似于以下内容:

…
Last Transition Time:  2024-01-03T13:56:08Z
    Message:               Quota 'NVIDIA_P4_GPUS' exceeded. Limit: 1.0 in region europe-west4.
    Observed Generation:   1
    Reason:                QuotaExceeded
    Status:                False
    Type:                  Provisioned
…

在此示例中,GKE 无法部署节点,因为 europe-west4 区域中的配额不足。

将节点池从已排队的预配迁移到灵活启动

如需将使用 --enable-queued-provisioning 标志创建的现有节点池迁移到灵活启动,请执行以下步骤:

  1. 确保节点池为空:

    kubectl get nodes -l cloud.google.com/gke-nodepool=NODEPOOL_NAME
    
  2. 将节点池更新为灵活启动:

    gcloud container node-pools update NODEPOOL_NAME \
      --cluster=CLUSTER_NAME --flex-start
    

此操作会执行以下操作:

  • 将节点池更新为灵活启动节点池。
  • 应用灵活启动节点的价格。

在运行 1.32.2-gke.1652000 或更高版本(灵活启动节点的最低版本)的集群上,所有节点都使用短期升级。

后续步骤