在 GKE 上扩缩 Managed Lustre 存储空间

本文档介绍了如何在 Google Kubernetes Engine (GKE) 中动态增加有状态工作负载的 Managed Lustre 卷的存储容量,而不会中断应用。

例如,如果长时间运行的 AI/ML 训练作业具有动态且不可预测的存储要求,请启用 Managed Lustre 卷扩展,以增加现有 Managed Lustre PersistentVolume (PV) 的存储容量。

本文档适用于在 GKE 上管理有状态工作负载存储的平台管理员和运维人员、DevOps、存储管理员以及机器学习 (ML) 工程师。

扩展卷后,您的费用会根据新的较大容量增加,具体费用取决于 Google Cloud Managed Lustre 标准价格

准备工作

准备环境

要求

请确保您符合以下要求:

  • 您必须使用 GKE 集群版本 1.35.0-gke.2331000 或更高版本。
  • 您必须在现有集群上启用 Managed Lustre CSI 驱动程序。在 Standard 集群和 Autopilot 集群中,该驱动程序默认处于停用状态。

限制

  • 您只能增加现有卷的大小,而不能减小其大小。
  • 您无法将卷扩展与 ReadOnlyMany 访问模式搭配使用。
  • 调整 Lustre 卷的大小时,请遵循卷的性能层级设置的最小和最大容量限制以及步长。如需了解详情,请参阅性能考虑因素
  • 以 1000 的倍数指定 Lustre 卷的大小(以 GiB 为单位)。Kubernetes 会将 Ti 等单位转换为二进制值(例如,18 Ti 会被解读为 18,432 GiB),这会导致 Lustre API 拒绝请求。

为 StorageClass 启用卷扩展

  1. 验证您的 StorageClass 是否支持卷扩展:

    kubectl get sc STORAGECLASS_NAME -o jsonpath='{.allowVolumeExpansion}{"\n"}'
    

    STORAGECLASS_NAME 替换为您的 StorageClass 的名称。

    如果该命令未输出任何内容或返回 false,您必须明确更新 StorageClass 配置以允许扩展。

  2. 打开 StorageClass 配置进行修改:

    kubectl edit storageclass STORAGECLASS_NAME
    
  3. 在编辑器中,将 allowVolumeExpansion: true 字段添加到 StorageClass 配置:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: lustre-sc
    provisioner: lustre.csi.storage.gke.io
    ...
    allowVolumeExpansion: true

扩展 PersistentVolumeClaim

如需启动卷扩展,请修改 PersistentVolumeClaim (PVC) 以请求增加卷大小。

  1. 按照确定有效的扩展大小中所述,确定新的有效扩展大小。
  2. 打开 PVC 配置进行修改:

    kubectl edit pvc PVC_NAME
    

    PVC_NAME 替换为您的 PVC 的名称。

  3. 在编辑器中,使用有效的扩展大小更新 spec.resources.requests.storage 字段。例如,如需将卷从 9000Gi 扩展到 18000Gi,请按如下方式修改 storage 字段:

    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 18000Gi # Changed from 9000Gi
    

验证卷扩展

  1. 查看 PVC 的事件,监控扩展进度:

    kubectl describe pvc PVC_NAME
    

    PVC 输出中的以下事件表示卷扩展请求的当前进度或结果:

    • ExternalExpanding:表示 Kubernetes 正在等待 external-resizer 扩展 PVC。
    • Resizing:表示调整大小操作正在进行中。如果容量增加幅度较大,此操作最多可能需要 90 分钟才能完成。
    • VolumeResizeSuccessful:确认卷已成功扩展。
    • VolumeResizeFailed:表示发生了错误。事件消息包含来自 Google Cloud Managed Lustre API 的详细信息。此状态可能是暂时性的,可能会自行解决。
  2. 扩展完成后,验证 PVC 的更新配置:

    kubectl get pvc PVC_NAME -o yaml
    
  3. 确保 status.capacity 字段反映了新的增量大小。

如果在扩展过程中遇到任何问题,请参阅问题排查

确定有效的扩展大小

如需确定新的卷大小,请先确定卷的性能层级及其对应的步长。

确定卷的性能层级

您可以使用以下任一选项查找卷的性能层级:

StorageClass

运行以下命令,然后查找 perUnitStorageThroughput 值(例如,1000)。此值表示性能层级(以 MBps/TiB 为单位)。

kubectl get sc STORAGECLASS_NAME -o yaml

STORAGECLASS_NAME 替换为您的 StorageClass 的名称。

Lustre 实例

通过直接检查底层 Managed Lustre 实例的属性来确定卷的性能层级:

  1. 查找绑定到 PVC 的 PV 的名称:

    kubectl get pvc PVC_NAME
    

    PVC_NAME 替换为您的 PVC 的名称。

    输出类似于以下内容。请注意 VOLUME 列中的 PV 名称,例如 pv-lustre

    NAME         STATUS   VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
    pvc-lustre   Bound    pv-lustre   9000Gi     RWX            lustre-rwx     <unset>                 26m
    
  2. volumeHandle 字段中查找卷的位置和实例名称:

    kubectl get pv PV_NAME -o yaml
    

    PV_NAME 替换为上一步中的 PV 名称。

    volumeHandle 值的格式为 PROJECT_ID/LOCATION/INSTANCE_NAME。请记下 INSTANCE_NAMELOCATION,以供下一步使用。

  3. 通过描述 Managed Lustre 实例来检查性能层级属性:

    gcloud lustre instances describe INSTANCE_NAME --location=LOCATION
    

    INSTANCE_NAMELOCATION 替换为上一步中的值。

    在输出中,查找 perUnitStorageThroughput 字段。此值表示性能层级(以 MBps/TiB 为单位)。

容量限制和步长

确定性能层级后,请参阅下表查找关联的容量限制和所需的步长。

层级 (perUnitStorageThroughput) 最小容量 最大容量 步长
1,000 MBps/TiB 9,000 GiB 954,000 GiB(约 1 PiB) 9,000 GiB
500 MBps/TiB 18,000 GiB 1,908,000 GiB(约 2 PiB) 18,000 GiB
250 MBps/TiB 36,000 GiB 3,816,000 GiB(约 4 PiB) 36,000 GiB
125 MBps/TiB 72,000 GiB 7,632,000 GiB(约 8 PiB) 72,000 GiB

卷必须按照分配给其层级的步长增加。任何容量增加都必须是该特定步长的倍数。 例如,如果您的 1,000 MBps 层级卷的容量为 9,000 GiB,您可以将其增加到 18,000 GiB、27,000 GiB 和其他倍数。

问题排查

本部分提供了扩展 Lustre 卷时可能会遇到的常见问题的解决方案。

扩展失败,并显示“Invalid Argument”错误

症状

  • PVC 进入 Resizing 状态,但随后失败。
  • 运行 kubectl describe pvc PVC_NAME 命令时,您会看到类似于 VolumeResizeFailed: rpc error: code = InvalidArgument desc = ... 的错误。

原因

此错误通常表示请求的存储大小对于 Lustre 卷的性能层级无效,原因如下:

  • 请求的大小不是该层级所需步长的倍数。
  • 请求的大小低于该层级的最小容量或高于最大容量。

解决方法

  1. 查看 容量限制和步长,查找卷的性能层级的有效步长和容量限制。
  2. 再次修改 PVC,请求符合步长和容量限制的有效存储大小。

扩展失败,并显示“Internal Error”

症状

  • PVC 调整大小失败。
  • 运行 kubectl describe pvc PVC_NAME 命令时,您可能会看到 VolumeResizeFailed 事件,其中包含 code = Internal 的错误消息。

原因

此错误表示底层 Managed Lustre 服务存在问题。

解决方法

  1. 使用新的请求大小再次应用 PVC 清单,重试扩展。这可能会解决暂时性的后端问题。
  2. 如果重试失败,请与 Cloud Customer Care 联系

扩展停留在“Resizing”状态

症状

  • PVC 在 Resizing 状态中停留较长时间(对于较小的扩展,超过 30 分钟;对于较大的扩展,超过 90 分钟)。
  • 您可能会看到 VolumeResizeFailed 事件,其中包含 DEADLINE_EXCEEDED 错误消息。

原因

如果容量增加幅度较大,可能会发生此问题,因为完成此操作最多可能需要 90 分钟。即使底层扩展操作仍在进行中,csi-external-resizer 组件在等待 Google Cloud Managed Lustre API 响应时也可能会超时。

解决方法

  • csi-external-resizer 会在退避时间后自动重试该操作。继续监控 PVC 事件,查找 VolumeResizeSuccessful 事件。
  • 如果 PVC 在 Resizing 状态中停留超过 90 分钟,请与 Cloud Customer Care 联系。

扩展未启动,或停留在 ExternalExpanding 状态

症状

  • 您更新了 PVC 中的 spec.resources.requests.storage 字段,但 PVC 状态未更改为 Resizing
  • 运行 kubectl describe pvc PVC_NAME 命令时,事件日志仅显示 ExternalExpanding 状态,而不会进入 Resizing 状态:
Events:
  Type    Reason             Age                From             Message
  ----    ------             ----               ----             -------
  Normal  ExternalExpanding  21m (x2 over 58m)  volume_expand    waiting for an external controller to expand this PVC

原因

此行为通常表示存在以下问题之一:

  • 与 PVC 关联的 StorageClass 不允许卷扩展。
  • 负责启动扩展的 csi-external-resizer 边车容器存在问题。

解决方法

  1. 检查 StorageClass 配置,并验证是否已设置 allowVolumeExpansion: true 字段:

    kubectl get sc STORAGECLASS_NAME -o jsonpath='{.allowVolumeExpansion}{"\n"}'
    
  2. 如果缺少 allowVolumeExpansion 或将其设置为 false,请更新 StorageClass 以允许卷扩展。

  3. 如果 StorageClass 配置正确,则问题很可能出在管理调整大小操作的 GKE 控制平面组件上。请与 Cloud Customer Care 联系以获取帮助。

扩展因配额或容量问题而失败

症状

  • PVC 调整大小失败,并且 PVC 上显示 VolumeResizeFailed 事件。
  • 运行 kubectl describe pvc PVC_NAME 命令时,来自 Managed Lustre 后端的事件消息表示存在配额或容量问题。

原因

请求的有效扩展无法完成,因为它超出了您的项目或区域中可用于 Managed Lustre 服务的总容量或配额。

解决方法

  • 再次修改 PVC,请求较小的存储空间增量。
  • 与您组织的 Google Cloud 管理员联系,请求增加项目的 Lustre 服务总配额或容量。

清理

为避免因本文档中使用的资源导致您的 Google Cloud 账号产生费用,请删除 PVC。如果 reclaimPolicy 设置为 Delete,此操作还会删除关联的 PV 和底层 Managed Lustre 实例。

kubectl delete pvc PVC_NAME

PVC_NAME 替换为您的 PVC 的名称。

后续步骤