本指南介绍了如何使用 Hyperdisk ML 简化和加速在 Google Kubernetes Engine (GKE) 上加载 AI/机器学习模型权重的操作。Compute Engine Persistent Disk CSI 驱动程序是您访问使用 GKE 集群的 Hyperdisk ML 存储的主要方式。
概览
Hyperdisk ML 是一种高性能存储解决方案,可用于扩容应用。它可为许多虚拟机同时提供高聚合吞吐量,使它非常适合您希望运行需要访问大量数据的 AI/机器学习工作负载的情况。
在只读多次模式下启用后,您可以使用 Hyperdisk ML 将模型权重的加载速度加快多达 11.9 倍(相对于直接从模型注册表加载)。这种加速是通过 Google Cloud Hyperdisk 架构实现的,该架构允许以 1.2 TB/s 的速度扩容到 2,500 个并发节点。这样,您就可以为 AI/机器学习推理工作负载缩短加载时间并减少 Pod 过度预配。
创建和使用 Hyperdisk ML 的概要步骤如下所示:
- 在 Persistent Disk 磁盘映像中预缓存或水合数据:使用可用于服务的外部数据源(例如从 Cloud Storage 加载的 Gemma 权重)中的数据加载 Hyperdisk ML 卷。用于磁盘映像的 Persistent Disk 必须与 Google Cloud Hyperdisk 兼容。
- 使用原有 Google Cloud Hyperdisk 创建 Hyperdisk ML 卷:创建一个引用随数据加载的 Hyperdisk ML 卷的 Kubernetes 卷。或者,您可以创建多可用区存储类别,以确保您的数据在 Pod 将运行的所有可用区中可用。
- 创建 Kubernetes Deployment 以使用 Hyperdisk ML 卷:引用 Hyperdisk ML 卷并加速数据加载,以供应用使用。
多可用区 Hyperdisk ML 卷
Hyperdisk ML 磁盘只能在单个可用区中使用。(可选)您可以使用 Hyperdisk ML 多可用区功能,在单个逻辑 PersistentVolumeClaim 和 PersistentVolume 中动态链接包含相同内容的多个可用区级磁盘。多可用区功能引用的可用区级磁盘必须位于同一区域中。例如,如果您的区域级集群在 us-central1
中创建,则多可用区磁盘必须位于同一区域(例如 us-central1-a
、us-central1-b
)。
AI/机器学习推理的一个常见应用场景是使用 Spot 虚拟机跨可用区运行 Pod,以提高加速器可用性并提升成本效益。由于 Hyperdisk ML 是可用区级的,因此如果推理服务器跨可用区运行多个 Pod,GKE 会自动跨可用区克隆磁盘,以确保您的数据遵循您的应用。
多可用区 Hyperdisk ML 卷具有以下限制:
- 不支持卷大小调整和卷快照操作。
- 只有在只读模式下才支持多可用区 Hyperdisk ML 卷。
- 将原有磁盘与多可用区 Hyperdisk ML 卷搭配使用时,GKE 不会执行检查来验证各个可用区的磁盘内容是否相同。如果任何磁盘包含不同的内容,请确保您的应用考虑了可用区之间潜在的不一致性。
如需了解详情,请参阅通过 VolumeSnapshot 创建多可用区 ReadOnlyMany Hyperdisk ML 卷。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
- 将您的默认区域和可用区设置为某个支持的值。
- 确保您的 Google Cloud 项目具有足够的配额,以便创建本指南中所需的节点。用于 GKE 集群和 Kubernetes 资源创建的示例代码在您选择的区域中需要以下最低配额:88 个 C3 CPU、8 个 NVIDIA L4 GPU。
要求
如需在 GKE 中使用 Hyperdisk ML 卷,您的集群必须满足以下要求:
- 使用运行 GKE 1.30.2-gke.1394000 版或更高版本的 Linux 集群。如果您使用发布渠道,请确保该渠道具有此驱动程序所需的最低 GKE 版本或更高版本。
- 确保已启用 Compute Engine Persistent Disk CSI 驱动程序。默认情况下,Compute Engine Persistent Disk 驱动程序会在新的 Autopilot 和 Standard 集群中启用,并且在使用 Autopilot 时无法停用或修改。如果您需要在集群中启用 Compute Engine Persistent Disk CSI 驱动程序,请参阅在现有集群上启用 Compute Engine Persistent Disk CSI 驱动程序。
- 如果您要对 readahead 值进行调优,请使用 GKE 1.29.2-gke.1217000 版或更高版本。
- 如果您要使用多可用区动态预配功能,请使用 GKE 1.30.2-gke.1394000 版或更高版本。
- Hyperdisk ML 仅在特定节点类型和可用区中受支持。如需了解详情,请参阅 Compute Engine 文档中的 Google Cloud Hyperdisk 简介。
获取对模型的访问权限
如需获取对 Gemma 模型的访问权限以便部署到 GKE,您必须先签署许可同意协议,然后生成 Huggging Face 访问令牌。
签署许可同意协议
您必须签署同意协议才能使用 Gemma。请按照以下说明操作:
- 访问 Kaggle.com 上的模型同意页面。
- 使用您的 Hugging Face 账号验证同意情况。
- 接受模型条款。
生成一个访问令牌
如需通过 Hugging Face 访问模型,您需要 Hugging Face 令牌。
如果您还没有令牌,请按照以下步骤生成新令牌:
- 点击您的个人资料 > 设置 > 访问令牌。
- 选择新建令牌 (New Token)。
- 指定您选择的名称和一个至少为
Read
的角色。 - 选择生成令牌。
- 将生成的令牌复制到剪贴板。
创建 GKE 集群
您可以在 GKE Autopilot 或 Standard 集群中的 GPU 上应用 LLM。我们建议您使用 Autopilot 集群获得全托管式 Kubernetes 体验。如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式。
Autopilot
在 Cloud Shell 中,运行以下命令:
gcloud container clusters create-auto hdml-gpu-l4 \ --project=PROJECT \ --region=REGION \ --release-channel=rapid \ --cluster-version=1.30.2-gke.1394000
替换以下值:
- PROJECT:Google Cloud 项目 ID。
- REGION:支持要使用的加速器类型的区域,例如适用于 L4 GPU 的
us-east4
。
GKE 会根据所部署的工作负载的请求,创建具有所需 CPU 和 GPU 节点的 Autopilot 集群。
配置
kubectl
以与您的集群通信:gcloud container clusters get-credentials hdml-gpu-l4 \ --region=REGION
标准
在 Cloud Shell 中,运行以下命令以创建 Standard 集群和节点池:
gcloud container clusters create hdml-gpu-l4 \ --location=REGION \ --num-nodes=1 \ --machine-type=c3-standard-44 \ --release-channel=rapid \ --cluster-version=CLUSTER_VERSION \ --node-locations=ZONES \ --project=PROJECT gcloud container node-pools create gpupool \ --accelerator type=nvidia-l4,count=2,gpu-driver-version=latest \ --location=REGION \ --project=PROJECT \ --node-locations=ZONES \ --cluster=hdml-gpu-l4 \ --machine-type=g2-standard-24 \ --num-nodes=2
替换以下值:
- CLUSTER_VERSION:GKE 集群的版本(例如 1.30.2-gke.1394000)。
- REGION:集群控制层面的计算区域。 该区域必须支持您要使用的加速器,例如适用于 L4 GPU 的
us-east4
。查看 L4 GPU 在哪些区域中可用。 - ZONES:在其中创建节点的可用区。您可以根据集群的需要指定任意数量的可用区。所有可用区必须与集群的控制平面位于同一区域,由
--zone
标志指定。对于可用区级集群,--node-locations
必须包含集群的主要可用区。 - PROJECT:Google Cloud 项目 ID。
集群创建可能需要几分钟的时间。
配置
kubectl
以与您的集群通信:gcloud container clusters get-credentials hdml-gpu-l4
将数据预缓存到 Persistent Disk 磁盘映像
如需使用 Hyperdisk ML,您可以在磁盘映像中预缓存数据,并创建 Hyperdisk ML 卷以供 GKE 中的工作负载进行读取访问。此方法(也称为数据水合)可确保数据在工作负载需要时可供使用。
如需将数据从 Cloud Storage 复制到预缓存 Persistent Disk 磁盘映像,请按以下步骤操作:
创建支持 Hyperdisk ML 的 StorageClass
将以下 StorageClass 清单保存在名为
hyperdisk-ml.yaml
的文件中。apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hyperdisk-ml parameters: type: hyperdisk-ml provisioner: pd.csi.storage.gke.io allowVolumeExpansion: false reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer
运行以下命令以创建 StorageClass:
kubectl create -f hyperdisk-ml.yaml
创建 ReadWriteOnce (RWO) PersistentVolumeClaim
将以下 PersistentVolumeClaim 清单保存在名为
producer-pvc.yaml
的文件中。您将使用之前创建的 StorageClass。请确保您的磁盘有足够的容量来存储数据。kind: PersistentVolumeClaim apiVersion: v1 metadata: name: producer-pvc spec: storageClassName: hyperdisk-ml accessModes: - ReadWriteOnce resources: requests: storage: 300Gi
运行以下命令以创建 PersistentVolumeClaim:
kubectl create -f producer-pvc.yaml
创建 Kubernetes 作业以填充已装载的 Google Cloud Hyperdisk 卷
本部分展示了一个创建 Kubernetes 作业的示例,该作业会预配磁盘并将 Gemma 7B 指令调优模型从 Hugging Face 下载到已装载的 Google Cloud Hyperdisk 卷上。
如需访问本指南中示例使用的 Gemma LLM,请创建包含 Hugging Face 令牌的 Kubernetes Secret:
kubectl create secret generic hf-secret \ --from-literal=hf_api_token=HF_TOKEN\ --dry-run=client -o yaml | kubectl apply -f -
将 HF_TOKEN 替换为您之前生成的 Hugging Face 令牌。
将以下示例清单保存为
producer-job.yaml
:apiVersion: batch/v1 kind: Job metadata: name: producer-job spec: template: # Template for the Pods the Job will create spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/compute-class operator: In values: - "Performance" - matchExpressions: - key: cloud.google.com/machine-family operator: In values: - "c3" - matchExpressions: - key: topology.kubernetes.io/zone operator: In values: - "ZONE" containers: - name: copy resources: requests: cpu: "32" limits: cpu: "32" image: huggingface/downloader:0.17.3 command: [ "huggingface-cli" ] args: - download - google/gemma-1.1-7b-it - --local-dir=/data/gemma-7b - --local-dir-use-symlinks=False env: - name: HUGGING_FACE_HUB_TOKEN valueFrom: secretKeyRef: name: hf-secret key: hf_api_token volumeMounts: - mountPath: "/data" name: volume restartPolicy: Never volumes: - name: volume persistentVolumeClaim: claimName: producer-pvc parallelism: 1 # Run 1 Pods concurrently completions: 1 # Once 1 Pods complete successfully, the Job is done backoffLimit: 4 # Max retries on failure
将 ZONE 替换为要在其中创建 Hyperdisk 的计算可用区。如果您要将其与 Deployment 示例搭配使用,请确保它是具有 G2 机器容量的可用区。
运行以下命令以创建作业:
kubectl apply -f producer-job.yaml
作业可能需要几分钟时间才能完成将数据复制到 Persistent Disk 卷的过程。作业完成预配后,其状态会被标记为“完成”。
如需检查作业状态的进度,请运行以下命令:
kubectl get job producer-job
作业完成后,您可以运行以下命令来清理作业:
kubectl delete job producer-job
通过原有 Google Cloud Hyperdisk 创建 ReadOnlyMany Hyperdisk ML 卷
本部分介绍了通过原有 Google Cloud Hyperdisk 卷创建 ReadOnlyMany (ROM) PersistentVolume 和 PersistentVolumeClaim 对的步骤。如需了解详情,请参阅将原有永久性磁盘用作 PersistentVolume。
在 GKE 1.30.2-gke.1394000 版及更高版本中,GKE 会自动将
READ_WRITE_SINGLE
Google Cloud Hyperdisk 卷的访问模式转换为READ_ONLY_MANY
。如果您在较低版本的 GKE 上使用原有 Google Cloud Hyperdisk 卷,则必须通过运行以下命令手动修改访问模式:
gcloud compute disks update HDML_DISK_NAME \ --zone=ZONE \ --access-mode=READ_ONLY_MANY
替换以下值:
- HDML_DISK_NAME:Hyperdisk ML 卷的名称。
- ZONE:在其中创建原有 Google Cloud Hyperdisk 卷的计算可用区。
创建 PersistentVolume 和 PersistentVolumeClaim 对(引用您之前填充的磁盘)。
将以下清单保存为
hdml-static-pv.yaml
:apiVersion: v1 kind: PersistentVolume metadata: name: hdml-static-pv spec: storageClassName: "hyperdisk-ml" capacity: storage: 300Gi accessModes: - ReadOnlyMany claimRef: namespace: default name: hdml-static-pvc csi: driver: pd.csi.storage.gke.io volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME fsType: ext4 readOnly: true nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: topology.gke.io/zone operator: In values: - ZONE --- apiVersion: v1 kind: PersistentVolumeClaim metadata: namespace: default name: hdml-static-pvc spec: storageClassName: "hyperdisk-ml" volumeName: hdml-static-pv accessModes: - ReadOnlyMany resources: requests: storage: 300Gi
替换以下值:
- PROJECT:在其中创建 GKE 集群的项目。
- ZONE:在其中创建原有 Google Cloud Hyperdisk 卷的可用区。
- DISK_NAME:原有 Google Cloud Hyperdisk 卷的名称。
运行以下命令以创建 PersistentVolume 和 PersistentVolumeClaim 资源:
kubectl apply -f hdml-static-pv.yaml
通过 VolumeSnapshot 创建多可用区 ReadOnlyMany Hyperdisk ML 卷
本部分介绍了在 ReadOnlyMany 访问模式下创建多可用区 Hyperdisk ML 卷的步骤。您可以为原有 Persistent Disk 磁盘映像使用 VolumeSnapshot。如需了解详情,请参阅使用卷快照备份 Persistent Disk 存储空间。
如需创建多可用区 Hyperdisk ML 卷,请按照以下步骤操作:
创建磁盘的 VolumeSnapshot
将以下清单保存为名为
disk-image-vsc.yaml
的文件。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: disk-image-vsc driver: pd.csi.storage.gke.io deletionPolicy: Delete parameters: snapshot-type: images
运行以下命令以创建 VolumeSnapshotClass:
kubectl apply -f disk-image-vsc.yaml
将以下清单保存为名为
my-snapshot.yaml
的文件。您将引用之前在创建 ReadWriteOnce (RWO) PersistentVolumeClaim 中创建的 PersistentVolumeClaim。apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: my-snapshot spec: volumeSnapshotClassName: disk-image-vsc source: persistentVolumeClaimName: producer-pvc
运行以下命令以创建 VolumeSnapshot:
kubectl apply -f my-snapshot.yaml
当 VolumeSnapshot 被标记为“准备就绪”时,请运行以下命令以创建 Hyperdisk ML 卷:
kubectl wait --for=jsonpath='{.status.readyToUse}'=true \ --timeout=300s volumesnapshot my-snapshot
创建多可用区 StorageClass
如果您希望能够在多个可用区中访问数据的副本,请在 StorageClass 中指定 enable-multi-zone-provisioning
参数,该参数会在您在 allowedTopologies
字段中指定的可用区中创建磁盘。
如需创建 StorageClass,请按以下步骤操作:
将以下清单保存为名为
hyperdisk-ml-multi-zone.yaml
的文件。apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: hyperdisk-ml-multi-zone parameters: type: hyperdisk-ml provisioned-throughput-on-create: "2400Mi" enable-multi-zone-provisioning: "true" provisioner: pd.csi.storage.gke.io allowVolumeExpansion: false reclaimPolicy: Delete volumeBindingMode: Immediate allowedTopologies: - matchLabelExpressions: - key: topology.gke.io/zone values: - ZONE_1 - ZONE_2
将 ZONE_1、ZONE_2、...、ZONE_N 替换为可访问您的存储空间的可用区。
此示例将 volumeBindingMode 设置为
Immediate
,以允许 GKE 在任何使用方进行引用之前预配 PersistentVolumeClaim。运行以下命令以创建 StorageClass:
kubectl apply -f hyperdisk-ml-multi-zone.yaml
创建使用多可用区 StorageClass 的 PersistentVolumeClaim
下一步是创建一个引用 StorageClass 的 PersistentVolumeClaim。
GKE 会使用指定的磁盘映像内容,在快照中指定的每个可用区中自动预配 Hyperdisk ML 卷。
如需创建 PersistentVolumeClaim,请按以下步骤操作:
将以下清单保存为名为
hdml-consumer-pvc.yaml
的文件。kind: PersistentVolumeClaim apiVersion: v1 metadata: name: hdml-consumer-pvc spec: dataSource: name: my-snapshot kind: VolumeSnapshot apiGroup: snapshot.storage.k8s.io accessModes: - ReadOnlyMany storageClassName: hyperdisk-ml-multi-zone resources: requests: storage: 300Gi
运行以下命令以创建 PersistentVolumeClaim:
kubectl apply -f hdml-consumer-pvc.yaml
创建 Deployment 以使用 Hyperdisk ML 卷
将 Pod 与 PersistentVolume 搭配使用时,我们建议您使用工作负载控制器(例如 Deployment 或 StatefulSet)。
如果要将处于 ReadOnlyMany 模式的原有 PersistentVolume 与 Deployment 搭配使用,请参阅将永久性磁盘与多个读取方配合使用。
如需创建和测试 Deployment,请按以下步骤操作:
将以下示例清单保存为
vllm-gemma-deployment
。apiVersion: apps/v1 kind: Deployment metadata: name: vllm-gemma-deployment spec: replicas: 2 selector: matchLabels: app: gemma-server template: metadata: labels: app: gemma-server ai.gke.io/model: gemma-7b ai.gke.io/inference-server: vllm spec: affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: topology.kubernetes.io/zone containers: - name: inference-server image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:latest resources: requests: cpu: "2" memory: "25Gi" ephemeral-storage: "25Gi" nvidia.com/gpu: 2 limits: cpu: "2" memory: "25Gi" ephemeral-storage: "25Gi" nvidia.com/gpu: 2 command: ["python3", "-m", "vllm.entrypoints.api_server"] args: - --model=$(MODEL_ID) - --tensor-parallel-size=2 env: - name: MODEL_ID value: /models/gemma-7b volumeMounts: - mountPath: /dev/shm name: dshm - mountPath: /models name: gemma-7b volumes: - name: dshm emptyDir: medium: Memory - name: gemma-7b persistentVolumeClaim: claimName: CLAIM_NAME nodeSelector: cloud.google.com/gke-accelerator: nvidia-l4 --- apiVersion: v1 kind: Service metadata: name: llm-service spec: selector: app: gemma-server type: ClusterIP ports: - protocol: TCP port: 8000 targetPort: 8000
将 CLAIM_NAME 替换为以下某个值:
hdml-static-pvc
:如果您使用现有 Google Cloud Hyperdisk 中的 Hyperdisk ML 卷。hdml-consumer-pvc
:如果您使用 VolumeSnapshot 磁盘映像中的 Hyperdisk ML 卷。
运行以下命令,等待推理服务器可用:
kubectl wait --for=condition=Available --timeout=700s deployment/vllm-gemma-deployment
如需测试 vLLM 服务器是否已启动且正在运行,请按以下步骤操作:
运行以下命令以设置到模型的端口转发:
kubectl port-forward service/llm-service 8000:8000
运行
curl
命令以向模型发送请求:USER_PROMPT="I'm new to coding. If you could only recommend one programming language to start with, what would it be and why?" curl -X POST http://localhost:8000/generate \ -H "Content-Type: application/json" \ -d @- <<EOF { "prompt": "<start_of_turn>user\n${USER_PROMPT}<end_of_turn>\n", "temperature": 0.90, "top_p": 1.0, "max_tokens": 128 } EOF
以下输出显示了模型响应的示例:
{"predictions":["Prompt:\n<start_of_turn>user\nI'm new to coding. If you could only recommend one programming language to start with, what would it be and why?<end_of_turn>\nOutput:\nPython is often recommended for beginners due to its clear, readable syntax, simple data types, and extensive libraries.\n\n**Reasons why Python is a great language for beginners:**\n\n* **Easy to read:** Python's syntax is straightforward and uses natural language conventions, making it easier for beginners to understand the code.\n* **Simple data types:** Python has basic data types like integers, strings, and lists that are easy to grasp and manipulate.\n* **Extensive libraries:** Python has a vast collection of well-documented libraries covering various tasks, allowing beginners to build projects without reinventing the wheel.\n* **Large supportive community:**"]}
对 readahead 值进行调优
如果您的工作负载执行顺序 I/O,则对 readahead 值进行调优可能会有益于这些工作负载。这通常适用于需要将 AI/机器学习模型权重加载到内存中的推理或训练工作负载。大多数具有顺序 I/O 的工作负载通常会在 readahead 值为 1024 KB 或更高时获得性能提升。
在静态预配新的 PersistentVolume 或修改现有动态预配的 PersistentVolume 时,您可以通过 read_ahead_kb
装载选项指定此选项。
以下示例展示了如何将 readahead 值调优为 4096 KB。
apiVersion: v1
kind: PersistentVolume
name: DISK_NAME
spec:
accessModes:
- ReadOnlyMany
capacity:
storage: 300Gi
csi:
driver: pd.csi.storage.gke.io
fsType: ext4
readOnly: true
volumeHandle: projects/PROJECT/zones/ZONE/disks/DISK_NAME
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.gke.io/zone
operator: In
values:
- ZONE
storageClassName: hyperdisk-ml
mountOptions:
- read_ahead_kb=4096
替换以下值:
- DISK_NAME:原有 Google Cloud Hyperdisk 卷的名称。
- ZONE:在其中创建原有 Google Cloud Hyperdisk 卷的可用区。
对 Hyperdisk ML 卷性能进行测试和基准测试
本部分介绍了如何使用灵活的 I/O 测试工具 (FIO) 对 Hyperdisk ML 卷在读取原有数据方面的性能进行基准测试。您可以使用这些指标针对特定工作负载和配置来评估卷的性能。
将以下示例清单保存为
benchmark-job.yaml
:apiVersion: batch/v1 kind: Job metadata: name: benchmark-job spec: template: # Template for the Pods the Job will create spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: cloud.google.com/compute-class operator: In values: - "Performance" - matchExpressions: - key: cloud.google.com/machine-family operator: In values: - "c3" containers: - name: fio resources: requests: cpu: "32" image: litmuschaos/fio args: - fio - --filename - /models/gemma-7b/model-00001-of-00004.safetensors:/models/gemma-7b/model-00002-of-00004.safetensors:/models/gemma-7b/model-00003-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors:/models/gemma-7b/model-00004-of-00004.safetensors - --direct=1 - --rw=read - --readonly - --bs=4096k - --ioengine=libaio - --iodepth=8 - --runtime=60 - --numjobs=1 - --name=read_benchmark volumeMounts: - mountPath: "/models" name: volume restartPolicy: Never volumes: - name: volume persistentVolumeClaim: claimName: hdml-static-pvc parallelism: 1 # Run 1 Pods concurrently completions: 1 # Once 1 Pods complete successfully, the Job is done backoffLimit: 1 # Max retries on failure
将 CLAIM_NAME 替换为您的 PersistentVolumeClaim 的名称(例如
hdml-static-pvc
)。运行以下命令以创建作业:
kubectl apply -f benchmark-job.yaml.
使用
kubectl
日志查看fio
工具的输出:kubectl logs benchmark-job-nrk88 -f
输出类似于以下内容:
read_benchmark: (g=0): rw=read, bs=4M-4M/4M-4M/4M-4M, ioengine=libaio, iodepth=8 fio-2.2.10 Starting 1 process read_benchmark: (groupid=0, jobs=1): err= 0: pid=32: Fri Jul 12 21:29:32 2024 read : io=18300MB, bw=2407.3MB/s, iops=601, runt= 7602msec slat (usec): min=86, max=1614, avg=111.17, stdev=64.46 clat (msec): min=2, max=33, avg=13.17, stdev= 1.08 lat (msec): min=2, max=33, avg=13.28, stdev= 1.06 clat percentiles (usec): | 1.00th=[11072], 5.00th=[12352], 10.00th=[12608], 20.00th=[12736], | 30.00th=[12992], 40.00th=[13120], 50.00th=[13248], 60.00th=[13376], | 70.00th=[13504], 80.00th=[13632], 90.00th=[13888], 95.00th=[14016], | 99.00th=[14400], 99.50th=[15296], 99.90th=[22144], 99.95th=[25728], | 99.99th=[33024] bw (MB /s): min= 2395, max= 2514, per=100.00%, avg=2409.79, stdev=29.34 lat (msec) : 4=0.39%, 10=0.31%, 20=99.15%, 50=0.15% cpu : usr=0.28%, sys=8.08%, ctx=4555, majf=0, minf=8203 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=99.8%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.1%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=4575/w=0/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=8 Run status group 0 (all jobs): READ: io=18300MB, aggrb=2407.3MB/s, minb=2407.3MB/s, maxb=2407.3MB/s, mint=7602msec, maxt=7602msec Disk stats (read/write): nvme0n2: ios=71239/0, merge=0/0, ticks=868737/0, in_queue=868737, util=98.72%
监控 Hyperdisk ML 卷上的吞吐量或 IOPS
如需监控 Hyperdisk ML 卷的预配性能,请参阅 Compute Engine 文档中的分析预配的 IOPS 和吞吐量。
如需更新现有 Hyperdisk ML 卷的预配吞吐量或 IOPS,或者了解您可以在 StorageClass 中指定的其他 Google Cloud Hyperdisk 参数,请参阅使用 Google Cloud Hyperdisk 扩缩存储性能。
问题排查
本部分提供了解决 GKE 上的 Hyperdisk ML 卷问题的问题排查指南。
无法更新磁盘访问模式
如果 Hyperdisk ML 卷已由处于 ReadWriteOnce 访问模式的节点使用和挂接,则会出现以下错误。
AttachVolume.Attach failed for volume ... Failed to update access mode:
failed to set access mode for zonal volume ...
'Access mode cannot be updated when the disk is attached to instance(s).'., invalidResourceUsage
当 ReadOnlyMany 访问模式 PersistentVolume 使用 Hyperdisk ML 卷时,GKE 会自动将卷的 accessMode 从 READ_WRITE_SINGLE
更新为 READ_ONLY_MANY
。此更新在磁盘挂接到新节点时完成。
如需解决此问题,请删除使用处于 ReadWriteOnce 模式的 PersistentVolume 引用磁盘的所有 Pod。等待磁盘分离,然后重新创建使用处于 ReadOnlyMany 模式的 PersistentVolume 的工作负载。
无法以 READ_WRITE
模式挂接磁盘
以下错误表示 GKE 尝试将处于 READ_ONLY_MANY
访问模式的 Hyperdisk ML 卷挂接到使用 ReadWriteOnce 访问模式的 GKE 节点。
AttachVolume.Attach failed for volume ...
Failed to Attach: failed cloud service attach disk call ...
The disk cannot be attached with READ_WRITE mode., badRequest
当 ReadOnlyMany 访问模式 PersistentVolume 使用 Hyperdisk ML 卷时,GKE 会自动将卷的 accessMode 从 READ_WRITE_SINGLE
更新为 READ_ONLY_MANY
。不过,GKE 不会自动将访问模式从 READ_ONLY_MANY
更新为 READ_WRITE_SINGLE
。这是一种安全机制,可确保不会意外写入多可用区磁盘,因为这可能会导致多可用区磁盘之间的内容不同。
如需解决此问题,如果您需要更新内容,我们建议您按照将数据预缓存到 Persistent Disk 磁盘映像工作流进行操作。如果您需要更好地控制 Hyperdisk ML 卷的访问模式和其他设置,请参阅修改 Google Cloud Hyperdisk 卷的设置。
已超出配额 - 吞吐量配额不足
以下错误表明预配磁盘时 Hyperdisk ML 吞吐量配额不足。
failed to provision volume with StorageClass ... failed (QUOTA_EXCEEDED): Quota 'HDML_TOTAL_THROUGHPUT' exceeded
如需解决此问题,请参阅磁盘配额,详细了解 Hyperdisk 配额以及如何在项目中增加磁盘配额。
如需更多问题排查指南,请参阅使用 Google Cloud Hyperdisk 扩缩存储性能。