本页面介绍如何配置 Pod,使其能够爆发为使用 Google Kubernetes Engine (GKE) 节点上的可用未使用容量。
什么是爆发?
“爆发”描述的是 Pod 在节点上暂时使用超出最初请求的计算容量的行为。
通过 Kubernetes,您可以为 Pod 请求特定容量的资源,例如 CPU 或内存。您可以在 Pod 清单中设置这些请求。Kubernetes 调度器会将 Pod 放置在具有足够容量的节点上来应对这些资源请求。
某些工作负载在整个运行时中并不会完全使用请求的资源。例如,在启动期间消耗额外 CPU 的工作负载在执行正常操作时可能并不需要同样数量的资源。在这些情况下,您可以将工作负载的资源限额设置为高于资源请求的值,或者不设置限额。GKE 允许工作负载临时使用超出请求中所指定数量的资源(如果该容量可用)。
如需详细了解此过程在 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.30.2-gke.1394000 版或更高版本的 GKE Autopilot 集群,或者拥有任何版本的 GKE Standard 集群。如需创建新集群,请参阅创建 Autopilot 集群。
GKE 中的爆发可用性
工作负载在以下情况下可能会爆发:
爆发可用性 | |
---|---|
GKE Autopilot 模式 | 使用 Performance 计算类或 Accelerator 计算类的 Pod 可以在支持该计算类的任何 GKE 版本中爆发。 在任何其他计算类中,以及对于未指定计算类的 Pod,只有在集群同时满足以下两项条件时,才能使用爆发:
存在此限制的原因是,在 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 会随着时间的推移升级工作器节点以与控制平面版本匹配。必须重启控制平面才能启用爆发,并且必须在所有节点都运行受支持的版本后重启。在扩缩、升级或维护等操作期间,控制平面大约每周自动重启一次。
如需手动触发控制平面重启,请执行以下操作:
检查是否所有节点都运行 1.30.2-gke.1394000 版或更高版本:
kubectl get nodes
输出类似于以下内容:
NAME STATUS ROLES AGE VERSION gk3-ap-cluster-1-default-pool-18092e49-mllk Ready <none> 4m26s v1.30.2-gke.1349000
输出中的所有节点都必须显示所需的版本或更高版本。
手动启动控制平面升级到集群已在使用的版本。如需查看相关说明,请参阅手动升级控制平面。
连接到集群
运行以下命令:
gcloud container clusters get-credentials CLUSTER_NAME \
--location=LOCATION
替换以下内容:
CLUSTER_NAME
:现有集群的名称。LOCATION
:您的集群的位置。
部署可爆发工作负载
将以下清单保存为
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.nodeSelector
和spec.tolerations
:可选。 指示 GKE 创建新节点来运行可爆发的 Pod。GKE 会将污点应用于这些新节点,以防止其他 Pod(例如关键工作负载)在同一节点上运行。如需了解详情,请参阅在 GKE 中配置工作负载隔离。
部署工作负载:
kubectl apply -f burstable-deployment.yaml
工作负载可能需要几分钟才能启动。
检查 Pod 的 QoS 类:
kubectl describe pod helloweb | grep -m 1 "QoS"
输出如下所示:
QoS Class: Burstable
GKE 中的可爆发容量
为帮助 Pod 爆发,GKE 会计算集群中每个节点的可爆发容量。特定节点的计算方法如下:
Autopilot 集群:
- 请求加速器或请求特定机器系列的 Pod:节点可分配的资源容量,即可供工作负载使用的容量。如需了解详情,请参阅节点可分配资源。
- 所有其他 Pod:该节点上所有 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 节点压力逐出终止。