容量缓冲区通过使用 Kubernetes CapacityBuffer 自定义资源定义 (CRD) 主动管理预配置、预配置容量的备用集群容量和暂停状态,来提高关键工作负载的响应能力和可靠性。使用容量缓冲区可让您明确定义集群中未使用的节点容量的具体数量。此预留容量有助于缩短 Pod 调度时间。
当高优先级工作负载需要快速扩容时,新工作负载可以立即使用空闲容量,而无需等待节点预配。这种方法可最大限度地减少延迟时间,并避免在需求突然激增时出现资源争用。
本页介绍了配置容量缓冲区的各种方法:固定副本缓冲区、资源限制缓冲区和基于百分比的缓冲区。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
- 创建或有权访问版本为 1.35.2-gke.1842000 的 GKE 集群(用于活动缓冲区),以及版本为 1.36.0-gke.2253000 或更高版本的 GKE 集群(用于备用缓冲区)。
- 在 Standard 集群上启用节点自动预配。在 Autopilot 集群中,节点自动预配功能已启用。节点自动预配功能是可选的,但建议用于有效缓冲区,并且必须用于备用缓冲区。
创建前提条件 Kubernetes 对象
如需配置 CapacityBuffer,您需要一个包含所有必需对象的命名空间(CapacityBuffer 本身以及 PodTemplate 或工作负载等其他资源)。PodTemplate 和 CapacityBuffer 必须位于同一命名空间中。您可以创建命名空间,也可以使用现有命名空间,包括 default 命名空间。
根据您配置的 CapacityBuffer 类型,您���需要以下其中一项:
- PodTemplate:定义单个缓冲区容量单位的资源要求。在 CapacityBuffer 对象中指定的配置引用了 Pod 模板。
工作负载:您在 CapacityBuffer 对象中引用的现有工作负载。本指南使用 Deployment 对象作为工作负载示例,但容量缓冲区支持以下任何资源类型:
- 部署
- ReplicaSet
- StatefulSet
- ReplicationController
- 作业
实现
scale子资源的 CustomResourceDefinition (CRD)。
本部分提供了这些对象的示例。如果您已有要配置容量缓冲的工作负载,请继续应用容量缓冲。
如需创建示例 Kubernetes 工作负载,请完成以下步骤:
将以下清单保存为
namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: capacity-buffer-example labels: name: capacity-buffer-example此清单会创建一个名为
capacity-buffer-example的命名空间。可选:如需将容量缓冲区与自定义 ComputeClass 搭配使用,请将以下清单保存为
custom-compute-class.yaml:apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: ccc-example namespace: capacity-buffer-example spec: # Buffers are also created according to these priorities priorities: - machineFamily: n4 - machineFamily: n4d - machineFamily: c4 - machineFamily: c4d nodePoolAutoCreation: enabled: true此清单会创建一个自定义
ComputeClass,用于定义和控制 GKE 配置的节点的计算优先级。如需了解详情,请参阅自定义 ComputeClass。将以下清单保存为
buffer-pod-template.yaml:apiVersion: v1 kind: PodTemplate metadata: name: buffer-unit-template namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer template: spec: terminationGracePeriodSeconds: 0 containers: - name: buffer-container image: registry.k8s.io/pause:3.9 resources: requests: cpu: "1" memory: "1Gi" limits: cpu: "1" memory: "1Gi" # Optional: Using buffers with a custom ComputeClass / # controls the properties of the provisioned nodes. nodeSelector: cloud.google.com/compute-class: ccc-example此清单创建了一个
PodTemplate,用于定义单个缓冲区容量单位(1CPU 和1Gi内存)的资源要求。此配置用于指定 GKE 为缓冲区预配的容量单位的大小。例如,如果集群扩缩,对于此 PodTemplate,GKE 不会将可用资源少于 1 个 CPU 和 1Gi 的节点视为缓冲区的一部分。将以下清单保存为
sample-workload-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: critical-workload-ref namespace: capacity-buffer-example # the namespace must be the same namespace as the CapacityBuffer spec: replicas: 10 selector: matchLabels: app: critical-workload template: metadata: labels: app: critical-workload spec: containers: - name: busybox image: busybox command: ["sleep", "3600"] resources: requests: cpu: 100m # Optional: Using buffers with a custom ComputeClass / # controls the properties of the provisioned nodes. nodeSelector: cloud.google.com/compute-class: ccc-example此清单会创建一个包含 10 个副本的示例 Deployment,该 Deployment 是下一部分中基于百分比的缓冲区示例的参考对象。
将清单应用到您的集群:
kubectl apply -f namespace.yaml -f custom-compute-class.yaml -f buffer-pod-template.yaml -f sample-workload-deployment.yaml验证 GKE 是否已创建对象:
kubectl get podtemplate -n capacity-buffer-example kubectl get deployment critical-workload-ref -n capacity-buffer-example输出类似于以下内容:
NAME AGE buffer-unit-template 1m NAME READY UP-TO-DATE AVAILABLE AGE critical-workload-ref 10/10 10 10 1m
应用容量缓冲
本部分提供了可应用于工作负载的不同类型的容量缓冲区的示例。
配置固定副本缓冲区
配置具有固定副本数的 CapacityBuffer 可指定您基于 PodTemplate 所需的确切缓冲区单元数。
如需创建具有固定副本数的缓冲区,请完成以下步骤:
将以下清单保存为
cb-fixed-replicas.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: fixed-replica-buffer namespace: NAMESPACE spec: podTemplateRef: name: POD_TEMPLATE replicas: 3 provisioningStrategy: "STRATEGY"替换以下内容:
NAMESPACE:命名空间的名称,例如capacity-buffer-example。POD_TEMPLATE:用于定义资源要求的 PodTemplate,例如buffer-unit-template。STRATEGY:预配策略,为"buffer.x-k8s.io/active-capacity"(默认)或"buffer.gke.io/standby-capacity"。
此清单会创建一个 CapacityBuffer 资源,该资源引用一个 PodTemplate 来请求特定数量的缓冲区单元。
应用清单:
kubectl apply -f cb-fixed-replicas.yaml确认 GKE 已应用容量缓冲区:
kubectl get capacitybuffer fixed-replica-buffer -n NAMESPACE状态中的
replicas字段应显示3,这反映了您在清单中定义的副本数量。STATUS字段应显示ReadyForProvisioning。
配置资源限制缓冲区
您可以使用 limits 字段来定义缓冲区应消耗的最大资源量,该资源量是根据您的 PodTemplate 大小计算得出的。
如需创建资源限制缓冲区,请完成以下步骤:
将以下清单保存为
cb-resource-limits.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: resource-limit-buffer namespace: NAMESPACE spec: podTemplateRef: name: POD_TEMPLATE limits: cpu: "5" memory: "5Gi" provisioningStrategy: "STRATEGY"替换以下内容:
NAMESPACE:命名空间的名称,例如capacity-buffer-example。POD_TEMPLATE:用于定义资源要求的 PodTemplate,例如buffer-unit-template。STRATEGY:预配策略,为"buffer.x-k8s.io/active-capacity"(默认)或"buffer.gke.io/standby-capacity"。
此清单会创建一个 CapacityBuffer 资源,其总限制为 5 个 CPU 和 5 GiB 内存。如果您使用的是上一步中的 PodTemplate 示例,则将每个单元定义为
1CPU 和1Gi内存,这应该会产生 5 个缓冲区单元。应用清单:
kubectl apply -f cb-resource-limits.yaml确认 GKE 已应用容量缓冲区:
kubectl get capacitybuffer resource-limit-buffer -n NAMESPACE检查 CapacityBuffer 状态。
replicas字段应显示根据您定义的限值得出的值。如果您使用的是上一部分中的 PodTemplate 示例,则应看到5个缓冲区单位,因为这是在定义的限制范围内可容纳的最大单位数。
配置基于百分比的缓冲区
配置基于百分比的缓冲区会根据现有可伸缩工作负载的百分比动态调整缓冲区的大小。基于百分比的容量缓冲区仅适用于实现伸缩子资源的 Kubernetes 可伸缩对象,例如 Deployment、StatefulSet、ReplicaSet 或 Job。您无法为 Pod 模板定义基于百分比的缓冲区,因为它们没有 replicas 字段。
我们通常建议先采用固定副本或资源限制策略,而不是基于百分比的缓冲区。如果工作负载缩放到较低的数字或零,基于百分比的缓冲区对突然的扩缩响应速度会较慢,因为安全边际会按比例缩放活动 Pod。它们主要适用于永远不会缩减到极低副本数的大规模部署。
如需创建基于百分比的缓冲区,请完成以下步骤:
将以下清单保存为
cb-percentage-based.yaml:apiVersion: autoscaling.x-k8s.io/v1beta1 kind: CapacityBuffer metadata: name: percentage-buffer namespace: NAMESPACE spec: scalableRef: apiGroup: apps kind: Deployment name: SCALABLE_RESOURCE_NAME percentage: 20 provisioningStrategy: "STRATEGY"替换以下内容:
NAMESPACE:您的命名空间名称。SCALABLE_RESOURCE_NAME:可伸缩资源的名称,例如critical-workload-ref。STRATEGY:预配策略,为"buffer.x-k8s.io/active-capacity"(默认)或"buffer.gke.io/standby-capacity"。
此清单会创建一个 CapacityBuffer 资源,该资源请求的缓冲区空间大小相当于所引用资源的副本数的 20%。如果您使用的是上一部分中的部署示例,则副本值设置为
10。应用清单:
kubectl apply -f cb-percentage-based.yaml确认 GKE 已应用容量缓冲区:
kubectl get capacitybuffer percentage-buffer -n NAMESPACE检查 CapacityBuffer 状态。
replicas字段应显示百分比计算得出的值。如果您使用的是上一部分中的部署示例,则应看到2个缓冲区单元,这相当于部署中定义的 10 个副本的 20%。通过手动将部署扩缩到 20 个副本来测试动态伸缩:
kubectl scale deployment critical-workload-ref -n NAMESPACE --replicas=20CapacityBuffer 控制器会做出反应,并自动将缓冲区扩缩为 4 个副本。
自定义待机缓冲区行为
您可以使用注释来自定义备用缓冲区的启动和刷新方式。将以下注解添加到 CapacityBuffer 资源的 metadata.annotations 字段:
buffer.gke.io/standby-capacity-init-time:节点在创建后到被暂停之前保持活动状态的时间量。格式为时长字符串(例如5m或1h)。默认值为5m。buffer.gke.io/standby-capacity-refresh-frequency:刷新已暂停节点的频率。默认值为1d。
以下示例展示了一个包含这些可选字段的清单,用于自定义待机缓冲区的行为:
apiVersion: autoscaling.x-k8s.io/v1beta1
kind: CapacityBuffer
metadata:
name: customized-standby-buffer
namespace: my-namespace
annotations:
buffer.gke.io/standby-capacity-init-time: "15m"
buffer.gke.io/standby-capacity-refresh-frequency: "12h"
spec:
podTemplateRef:
name: buffer-unit-template
replicas: 3
provisioningStrategy: "buffer.gke.io/standby-capacity"
在待机缓冲区中预加载图片
为了缩短备用节点恢复时的工作负载启动时间,您可以使用 DaemonSet 预加载容器映像。DaemonSet 在节点挂起之前的启动期间运行。
如需使用 DaemonSet 预加载映像,请完成以下步骤:
将以下清单保存为
image-puller-daemonset.yaml:apiVersion: apps/v1 kind: DaemonSet metadata: name: image-prefetch-daemonset namespace: NAMESPACE spec: selector: matchLabels: name: image-prefetch template: metadata: labels: name: image-prefetch spec: tolerations: - key: "buffer.gke.io/standby-node-suspended" operator: "Exists" initContainers: - name: image-puller image: IMAGE_NAME command: ["sh", "-c", "true"] containers: - name: pause image: registry.k8s.io/pause:3.9替换以下内容:
NAMESPACE:DaemonSet 的命名空间,例如capacity-buffer-example。IMAGE_NAME:要预加载的映像的名称,例如your-app-image:latest。
将 DaemonSet 清单应用到您的集群:
kubectl apply -f image-puller-daemonset.yaml验证 DaemonSet 是否已创建:
kubectl get daemonset image-prefetch-daemonset -n NAMESPACE验证容量缓冲区是否已创建并可用于配置:
kubectl get capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE查看状态。
STATUS字段应显示ReadyForProvisioning。
监控容量缓冲状态和性能
您可以使用 kubectl 命令和 Cloud Monitoring 指标监控容量缓冲区的状态和健康状况。
验证 CapacityBuffer 资源状态
如需检查容量缓冲区的健康状况并验证它们是否已准备好接收工作负载,请完成以下步骤:
获取整个集群中所有容量缓冲区的状态:
kubectl get capacitybuffer -A检查特定缓冲区的详细状态、条件和事件日志:
kubectl describe capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
识别已暂停的备用缓冲区节点
备用缓冲虚拟机已预先配置,但会保持在暂停状态,以帮助降低费用。您可以识别这些已暂停的节点,因为它们具有自定义条件。如需审核已暂停的节点实例,请运行以下命令:
kubectl get nodes -o custom-columns='NAME:.metadata.name,SUSPENDED:.status.conditions[?(@.type=="Suspended")].status'
状态为 True 表示备用虚拟机已暂停。状态为 False 或 <none> 表示节点处于活跃运行状态。
使用 Cloud Monitoring 监控性能
为了帮助您监控容量缓冲区的性能,请在 Cloud Monitoring 中监控以下资源:
- 响应延迟时间 (
cluster_autoscaler/reaction_time_milliseconds):跟踪集群自动伸缩器根据 CapacityBuffer 待处理需求做出伸缩决策的持续时间。 - 集群自动扩缩器日志:搜索类似
"Capacity pod processor injecting ..."的日志条目,以观察活跃的缓冲区 Pod 替换事件。
移除容量缓冲
如果您不再需要为工作负载提供容量缓冲,请删除 CapacityBuffer 对象。这样会移除占位 Pod,并允许集群自动扩缩器缩容节点。
kubectl delete capacitybuffer CAPACITY_BUFFER_NAME -n NAMESPACE
将 CAPACITY_BUFFER_NAME 替换为您要删除的 CapacityBuffer 的名称。
问题排查
以下部分包含有关解决容量缓冲区的常见问题的信息。
由于结算模式,容量缓冲尚未准备就绪
如果您为使用基于 Pod 的结算模式(按 Pod 付费)的工作负载创建 CapacityBuffer,则容量缓冲区将无法用于预配。
如需确定此问题,请检查 CapacityBuffer 状态:
kubectl describe capacitybuffer BUFFER_NAME -n NAMESPACE
查找类型为 ReadyForProvisioning 且状态为 False 的条件。
如需解决此问题,请确保您的 CapacityBuffer 引用的是与基于节点的结算兼容的工作负载或 PodTemplate。
自定义可伸缩资源的权限错误
如果您配置 CapacityBuffer 以使用自定义可伸缩对象(使用 scalableRef 字段),则集群自动伸缩器可能会因缺少必要的权限而无法伸缩缓冲区。
如需解决此问题,请手动授予所需权限,方法是创建 ClusterRole 和 ClusterRoleBinding,如以下示例所示:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: custom-scale-getter
rules:
- apiGroups: ["api.example.com"]
resources: ["customreplicatedresources/scale"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ca-custom-scale-getter
subjects:
- kind: User
name: "system:cluster-autoscaler"
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: custom-scale-getter
如需详细了解如何配置 RBAC,请参阅 Kubernetes RBAC 文档。
后续步骤
- 详细了解容量缓冲。
- 请参阅 CapacityBuffer CRD 文档。