在 GKE 中配置 Pod 爆发


本页面介绍如何配置 Pod,使其能够爆发为使用 Google Kubernetes Engine (GKE) 节点上的可用未使用容量

什么是爆发?

“爆发”描述的是 Pod 在节点上暂时使用超出最初请求的计算容量的行为。

通过 Kubernetes,您可以为 Pod 请求特定容量的资源,例如 CPU 或内存。您可以在 Pod 清单中设置这些请求。Kubernetes 调度器会将 Pod 放置在具有足够容量的节点上来应对这些资源请求。

某些工作负载在整个运行时中并不会完全使用请求的资源。例如,在启动期间消耗额外 CPU 的工作负载在执行正常操作时可能并不需要同样数量的资源。在这些情况下,您可以将工作负载的资源限额设置为高于资源请求的值,或者不设置限额。GKE 允许工作负载临时使用超出请求中所指定数量的资源(如果该容量可用)。

如需详细了解此过程在 GKE 中的工作原理,请参阅本文档中的爆发的工作原理

Pod 爆发的优势

如果您的 Pod 只是在短时间内需要额外资源来应对资源使用高峰,爆发就很有用。示例场景包括:

  • 您有一组工作负载通常处于空闲状态,每秒发送少量请求,但偶尔会遇到流量高峰,并且可以受益于使用额外资源来处理这些请求。
  • 您的工作负载在启动期间需要的资源比正常操作期间多。
  • 您希望最大限度地提高预配的计算容量的利用率。

通过爆发,您可以仅请求 Pod 在其大部分运行时所需的资源,同时也能确保您的 Pod 可在需要时消耗更多资源。爆发具有以下优势:

  • 降低运行费用:您无需请求工作负载的预期资源消耗量峰值。您的请求可以是较低的稳定状态值。在 Autopilot 中,您需要为 Pod 资源请求的总和付费,这样一来运行费用就会降低。
  • 更高效的资源利用:您可以避免空闲计算容量,因为 Pod 爆发为使用未使用的容量。您的工作负载更有可能使用所有付费资源。
  • 提升性能:Pod 可以根据需要使用额外的资源,以缩短处理传入请求的时间,或在纵向扩容事件期间加快启动速度。

何时不应使用爆发

Kubernetes 会将 Burstable 服务质量 (QoS) 类分配给指定资源限额高于请求量的 Pod。当 Kubernetes 需要收回节点上的资源时,Burstable QoS Pod 更有可能被逐出。如需了解详情,请参阅 Kubernetes 文档中的可爆发 QoS 类

准备工作

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

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。
  • 确保您拥有运行 1.29.2-gke.1060000 版或更高版本的 GKE Autopilot 集群,或者拥有任何版本的 GKE Standard 集群。如需创建新集群,请参阅创建 Autopilot 集群

GKE 中的爆发可用性

工作负载在以下情况下可能会爆发:

爆发可用性
GKE Autopilot 模式

使用 Performance 计算类或 Accelerator 计算类的 Pod 可以在支持该计算类的任何 GKE 版本中爆发。

在任何其他计算类中,以及对于未指定计算类的 Pod,只有在集群同时满足以下两项条件时,才能使用爆发:

  • 您最初是使用 GKE 1.26 版或更高版本创建的集群
  • 集群运行的是 GKE 1.29.2-gke.1060000 或更高版本

存在此限制的原因是,在 Autopilot 集群中,爆发需要 cgroup v2。cgroup v2 仅在最初使用 1.26 版及更高版本创建的集群中可用。

GKE Standard 模式 Pod 可在任何 GKE 版本中爆发。

最初使用低于 1.26 版的版本创建但后来升级到 1.29.2-gke.1060000 及更高版本的 Autopilot 集群不支持爆发。如需查看原始集群版本,请运行以下命令:

gcloud container clusters describe CLUSTER_NAME \
    --location=LOCATION \
    --format="value(initialClusterVersion)"

输出必须为 GKE 1.26 版或更高版本。

限制

  • Autopilot 工作负载只能对 CPU 和内存请求使用爆发。
  • Autopilot 控制平面和节点必须使用受支持的 GKE 版本。如果您最近将集群升级到了受支持的版本,在使用爆发之前请确保节点正在运行该版本。

连接到集群

运行以下命令:

gcloud container clusters get-credentials CLUSTER_NAME \
    --location=LOCATION

替换以下内容:

  • CLUSTER_NAME:现有集群的名称。
  • LOCATION:您的集群的位置。

部署可爆发工作负载

  1. 将以下清单保存为 burstable-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloweb
      labels:
        app: hello
    spec:
      selector:
        matchLabels:
          app: hello
          tier: web
      template:
        metadata:
          labels:
            app: hello
            tier: web
        spec:
          nodeSelector:
            pod-type: "non-critical"
          tolerations:
          - key: pod-type
            operator: Equal
            value: "non-critical"
            effect: NoSchedule
          containers:
          - name: hello-app
            image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
            ports:
            - containerPort: 8080
            resources:
              requests:
                cpu: 250m
              limits:
                cpu: 350m
    

    此清单包含以下用于启用爆发的字段:

    • resources.requests:容器正常运行所需的资源。将此值设置为容器在稳定状态下所需的容量。
    • resources.limits:容器可以使用的最大资源容量。将限额设置为高于请求量时,Pod 可爆发为使用不超过指定限额的容量(如果节点上具备该容量)。如果您省略此字段,Pod 可以爆发为使用不超过节点上可用的可爆发容量。此容量的计算方式如下:
      • Autopilot 模式:节点上 Pod 的资源请求总和的未使用容量。
      • Standard 模式:节点资源中未使用的容量。
    • spec.nodeSelectorspec.tolerations:可选。 指示 GKE 创建新节点来运行可爆发的 Pod。GKE 会将污点应用于这些新节点,以防止其他 Pod(例如关键工作负载)在同一节点上运行。如需了解详情,请参阅在 GKE 中配置工作负载隔离
  2. 部署工作负载:

    kubectl apply -f burstable-deployment.yaml
    

    工作负载可能需要几分钟才能启动。

  3. 检查 Pod 的 QoS 类:

    kubectl describe pod helloweb | grep -m 1 "QoS"
    

    输出如下所示:

    QoS Class: Burstable
    

GKE 中的可爆发容量

为帮助 Pod 爆发,GKE 会计算集群中每个节点的可爆发容量。特定节点的计算方法如下:

  • Autopilot 集群:该节点上所有 Pod 的资源请求总和,无论节点的实际资源容量如何。如果 Pod 终止,则可爆发容量会减少该 Pod 的请求。如果其中一个 Pod 需要爆发,则可以分配正在运行的 Pod 未使用的可爆发容量部分。

    Autopilot 还会向可爆发容量添加预定义的缓冲区,使节点上爆发超出其请求量的任何系统 Pod 不影响您自己的可爆发 Pod。

  • Standard 集群:节点虚拟机上可用的总资源容量。

爆发最佳做法

请在 Pod 爆发时采取以下做法:

  • 将资源请求设置为在您的环境中提供关键功能的任何 Pod 的限额。这可确保这些 Pod 获得 Guaranteed Kubernetes 服务质量 (QoS) 类。
  • 确保您仅在适当的 Pod 上配置内存爆发,也就是在 Kubernetes 需要回收节点上的内存时能够处理被逐出操作的 Pod。
  • 请务必请求足够的内存以便 Pod 启动。不要依赖内存爆发来满足您的启动要求。
  • 为了防止可爆发 Pod 持续爆发为其 CPU 请求的数倍,从而可能中断关键工作负载,请使用工作负载隔离来避免将这些 Pod 与关键 Pod 一起放置。

优化 Autopilot 节点中的可爆发容量

Autopilot 将爆发容量计算为特定节点上所有 Pod(包括系统 Pod 和 DaemonSet)的资源请求总和。您可以通过以下方式优化节点上的可爆发容量。但是,爆发是需要找到机会的,不能得到保证。

  • 如需增加特定工作负载在节点上的可爆发容量,请使用 Pod 亲和性将特定 Pod 放在同一节点上。
  • 为确保每个节点上始终具有特定的可爆发容量,请创建 DaemonSets 以在集群中的所有节点上运行。

爆发工作原理示例

本部分使用一个具有以下可爆发 Pod 的示例 Deployment 来演示 Pod 爆发在 GKE Autopilot 集群中的工作原理:

  • Pod 1 请求 250m CPU 且没有 CPU 限制。Pod 1 使用 100m CPU 来运行。
  • Pod 2 请求 200m CPU 并具有 250m CPU 的限制。Pod 2 使用 100m CPU 来运行。

两个 Pod 在同一节点上运行。节点上的可爆发总容量为 450m CPU(资源请求总和)。每个 Pod 仅使用 100m CPU 即可运行,这意味着节点剩余的可用可爆发容量为 250m。

请考虑以下会出现流量高峰的场景:

  • Pod 1 需要额外的 300m CPU:它可以爆发并使用 250m CPU,这是可用的可爆发容量。节点不再具有任何可用的可爆发容量。
  • Pod 2 需要额外的 150m CPU:它可能会爆发并使用额外的 150m CPU。然后,节点剩余 100m CPU 的可用可爆发容量。
  • Pod 2 还需要额外的 200m CPU:它可能会爆发并使用 150m CPU,因此 Pod 2 的总 CPU 用量达到 250m。Pod 2 具有 250m CPU 的限额,并且不能超出该限额。

GKE 如何处理超出可爆发容量的 Pod

如果可爆发 Pod 尝试使用的资源超出节点上的爆发容量,则 GKE 会执行以下操作:

  • CPU:如果 CPU 用量超过可爆发容量,则 GKE 会限制某些容器的 CPU 用量,以便节点上的所有容器都获取其请求的 CPU。
  • 内存:如果内存用量超过可爆发容量,则 GKE 会终止容器以收回节点上的内存。GKE 首先会终止 QoS 较低的 Pod 中的资源密集型容器。

我们建议您始终请求足够的内存来执行正常的 Pod 操作。如果某个容器依赖于内存爆发才能正常运行,则该容器可能会在内存不可用的情况下反复崩溃。

将 Pod 爆发与备用容量预配结合使用

借助 GKE,您可以部署空闲 Pod 以预留额外的计算容量,以便在未来的高流量事件(例如网店闪购)期间加快 Pod 扩缩速度。同一节点上的其他 Pod 可能会爆发为使用这类未使用的预留容量,使该容量在发生高流量事件之前不是处于空闲状态。您可以使用各种 Kubernetes 机制来预留此容量。例如,您可以部署具有较低 PriorityClass 的 Pod。如需了解详情,请参阅预配额外的计算容量以实现快速 Pod 扩缩

GKE Standard 集群中的 Pod 爆发

GKE Standard 集群还支持将限额设置为高于请求量或省略限额,从而支持 Pod 爆发。但是,在 Standard 集群中,您必须创建和配置具有适当资源容量的节点池,以支持爆发。如需降低 Standard 集群中的可爆发 Pod 的潜在费用,则需要更仔细的节点规划和 Pod 装箱,因为您需要为底层 Compute Engine 虚拟机付费。

在 Standard 集群中,请考虑以下事项:

  • 触发 Kubernetes 逐出或 CPU 节流的资源消耗量上限是节点上可分配的资源容量。如需确定此值,请参阅规划 GKE Standard 节点大小

  • Standard 集群中的节点资源用量更有可能达到 Kubernetes 逐出阈值,因为在您不指定限额的情况下,GKE 不会自动限制资源用量。因此,爆发为使用内存的 Pod 更有可能被 Kubernetes 节点压力逐出终止。

后续步骤