AI 智能体时代的动态容量管理:预订、回退与资源切片

2026-08-26 44 预计阅读时间: 1 分钟
来源: cloud.google.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:11 分钟

企业开始把大量 AI 智能体接入业务系统,基础设施面对的已不只是推理流量增长。智能体会持续调用模型、数据库和内部应用,负载既消耗 GPU、TPU 等稀缺资源,又具有明显的突发性。若仍把应用绑定到单一机型、单一区域或整块加速卡,结果通常是两个极端:高峰期申请不到容量,低谷期则有大量资源闲置。

动态容量管理的核心不是无限扩容,而是把需求分成可预测与不可预测两类:前者提前调度容量,后者通过自动回退和细粒度分配吸收变化。

把确定的需求放进日历

计划内训练、离线微调、产品发布和季节性流量并不应该采用同一种容量策略。Dynamic Workload Scheduler 提供了两种互补模式。

Flex-start 模式适合允许延迟启动的任务,例如批处理、模型训练和离线微调。提交任务时给出运行时长,调度器在资源可用后启动作业。它牺牲精确的开始时间,换取更高的稀缺加速器获取概率和更好的成本效率。

Calendar 模式面向有明确时间窗口的关键事件,例如大型版本发布、迁移窗口或促销活动。团队预先声明开始和结束时间,在指定时段获得有保障的容量。

选择模式时,可以用一个简单的判断表:

工作负载 能否推迟 是否有固定窗口 建议策略
夜间批量推理 可以 Flex-start
离线训练 通常可以 Flex-start
产品发布 不可以 Calendar
常驻在线服务 不可以 按需容量加自动回退

预订容量并不能解决所有问题。计划外热点、新闻事件和市场变化仍可能让首选机型瞬间耗尽,因此每个在线应用还需要一条经过批准的回退路径。

回退列表比单一机型更可靠

回退策略应当描述业务可以接受的计算能力,而不是只写一个具体 VM 型号。对于 Compute Engine 工作负载,托管实例组 MIG 的 instance flexibility 可以声明多个可兼容机型;再结合跨可用区的位置灵活性,系统能根据实时容量选择替代项。使用 Spot VM 时,平台还可以结合 Spot 容量信号,优先选择预计运行时间更长、抢占风险更低的选项。

这类策略带来三个直接效果:

  • 应用不再因某个 VM shape 暂时缺货而停止扩容。
  • 新一代机型可以成为首选,旧一代机型继续作为自动回退,实现渐进式技术更新。
  • 机型、可用区以及按需或 Spot 的选择可以纳入同一套优先级策略。

存储也要进入兼容性检查。短生命周期的启动盘通常可以使用平台默认值;需要跨 VM 生命周期保留的数据盘,则要确认回退机型均支持所选持久化存储。来源中提到的 Hyperdisk,正适合用于需要跨多个 VM 世代保持快速、持久的数据盘场景。

用 GKE 统一编排容量生命周期

容器化工作负载可以通过 GKE Custom ComputeClasses 把机型家族、规格、区域以及按需或 Spot 资源编排成多维优先级列表。当首选节点不可用时,GKE 按策略尝试后续选项;启用 active migration 后,首选容量恢复时,工作负载还可以平滑迁回高优先级节点。

这让平台团队和应用团队之间形成清晰边界:平台团队定义哪些硬件组合合规、可用和可承担成本,应用团队只声明性能需求,不必在 Deployment 中硬编码某个具体 VM 型号。

Dynamic Resource Allocation 进一步处理设备利用率问题。传统配置往往让一个 Pod 独占整块 GPU 或 TPU,即使它只使用一部分显存或核心。动态资源分配允许工作负载描述内存、核心数等具体参数,由系统分配合适的硬件切片。对于大量生命周期短、需求各异的智能体沙箱,这种方式比整卡分配更容易提高利用率。

不过,切片并非免费收益。共享加速器可能引入性能抖动和资源争用,模型框架与设备驱动也必须支持对应的隔离机制。延迟敏感推理服务需要通过压测决定是否共享,而不是只根据平均利用率做判断。

可以这样实践:先找出集群里的硬绑定

下面的脚本使用 kubectljq 检查当前命名空间中的 Deployment,找出硬编码的节点选择器、节点亲和性和 GPU 请求。运行前将 NAMESPACE 改为目标命名空间,并确保当前 kubectl 上下文指向只读检查所需的集群。

#!/usr/bin/env bash
set -euo pipefail

NAMESPACE="default"

kubectl get deployments -n "$NAMESPACE" -o json | jq -r '
  .items[]
  | {
      deployment: .metadata.name,
      nodeSelector: (.spec.template.spec.nodeSelector // {}),
      requiredNodeAffinity: (
        .spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution // null
      ),
      gpuRequests: [
        .spec.template.spec.containers[]
        | {
            container: .name,
            nvidiaGpu: (.resources.requests["nvidia.com/gpu"] // "0"),
            tpu: (.resources.requests["google.com/tpu"] // "0")
          }
      ]
    }
  | select(
      (.nodeSelector | length) > 0
      or .requiredNodeAffinity != null
      or ([.gpuRequests[].nvidiaGpu, .gpuRequests[].tpu] | any(. != "0"))
    )'

审计后,可以先把非必要的单机型硬约束改成标准 Kubernetes 的软偏好。下面是一个可直接修改的 Deployment 示例:它优先选择指定机器家族,但允许调度器在首选项不可用时选择其他满足要求的节点,同时尽量把副本分散到不同可用区。

运行前需要把 cloud.google.com/machine-family 的值替换为集群中实际存在的节点标签;该示例展示的是应用侧解耦方式,节点供应优先级仍应由 GKE Custom ComputeClasses 或集群自动扩缩策略管理。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: agent-worker
spec:
  replicas: 3
  selector:
    matchLabels:
      app: agent-worker
  template:
    metadata:
      labels:
        app: agent-worker
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: agent-worker
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              preference:
                matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                      - c4
            - weight: 50
              preference:
                matchExpressions:
                  - key: cloud.google.com/machine-family
                    operator: In
                    values:
                      - c3
      containers:
        - name: worker
          image: nginx:1.27-alpine
          resources:
            requests:
              cpu: "500m"
              memory: "512Mi"
            limits:
              cpu: "1"
              memory: "1Gi"

应用配置后检查副本分布:

kubectl apply -f agent-worker.yaml
kubectl get pods -l app=agent-worker -o wide
kubectl get pods -l app=agent-worker \
  -o custom-columns='POD:.metadata.name,NODE:.spec.nodeName,STATUS:.status.phase'

生产环境中不要仅凭 Pod 成功启动就认定回退有效。还应主动模拟首选节点池不可扩容、某个可用区容量不足以及 Spot 节点被回收等场景,并记录扩容耗时、排队时间、迁移期间错误率和单位任务成本。

落地顺序:先解耦,再承诺消费

动态容量管理可以按以下顺序推进:

  1. 盘点与单一 VM 家族、机型或可用区绑定的应用,列出每个应用可接受的替代硬件。
  2. 把训练、批处理和发布活动分类,分别使用 Flex-start、Calendar 或按需加回退策略。
  3. 为在线服务建立有优先级的机型、区域和 Spot 回退列表,并验证故障场景。
  4. 对 GPU 和 TPU 工作负载记录真实显存、核心与运行时需求,再评估动态资源分配和硬件切片。
  5. 在掌握稳定的最低消费基线后,再考虑持续使用折扣或灵活的承诺使用折扣。承诺消费可以降低价格,但无法修复错误的容量架构。

最终目标不是让每个应用都使用最多的硬件选项,而是让它们在资源紧张时仍有路可走,在需求确定时提前锁定容量,在负载下降时避免留下大块闲置资源。只有把预调度、自动回退和细粒度分配组合起来,AI 智能体规模增长才不必等比例推高基础设施预算。


相关推荐