本页面介绍了如何通过在 Google Kubernetes Engine (GKE) 中使用辅助启动磁盘在新节点上预加载数据或容器映像,从而缩短工作负载启动延迟时间。这样一来,工作负载便可以实现快速冷启动,并提高预配资源的总体利用率。
在阅读本页面内容之前,请确保您熟悉 Google Cloud、Kubernetes、容器、YAML、containerd 运行时和 Google Cloud CLI。
概览
从 Standard 集群中的 GKE 1.28.3-gke.1067000 版以及 Autopilot 集群中的 GKE 1.30.1-gke.1329000 版开始,您可以配置具有辅助启动磁盘的节点池。您可以指示 GKE 预配节点并为其预加载数据(例如机器学习 [ML] 模型)或容器映像。对于工作负载,使用辅助磁盘中预加载的容器映像或数据具有以下优势:
- 缩短了拉取大型容器映像或下载数据时的延迟时间
- 更快的自动扩缩
- 更快地从中断(例如维护事件和系统错误)中恢复
以下部分介绍了如何在 GKE Autopilot 和 Standard 集群中配置辅助启动磁盘。
辅助启动磁盘的工作原理
通过使用辅助启动磁盘上预加载的容器映像或数据,您的工作负载可以更快地启动。辅助启动磁盘具有以下特征:
- 辅助启动磁盘是由分布式块存储支持的永久性磁盘。如果磁盘映像已在可用区中使用,则来自同一磁盘映像的所有后续磁盘的创建时间会缩短。
- 辅助启动磁盘类型与节点启动磁盘相同。
- 辅助启动磁盘的大小由磁盘映像大小决定。
将辅助启动磁盘添加到节点池不会增加节点预配时间。GKE 会并行于节点预配流程,从磁盘映像预配辅助启动磁盘。
为了支持预加载的容器映像,GKE 使用可从辅助启动磁盘读取容器映像的插件来扩展 containerd 运行时。容器映像会由基础层重复使用。
将大型基础层预加载到辅助启动磁盘中,而小型较高层可以从容器注册表中拉取。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
启用 Container File System API。
要求
使用辅助启动磁盘时需满足以下要求:
- 您的集群运行的是 GKE Standard 中的 GKE 1.28.3-gke.1067000 版或 GKE Autopilot 中的 1.30.1-gke.1329000 版。
- 修改磁盘映像时,您必须创建新的节点池。 不支持更新现有节点上的磁盘映像。
- 配置映像流式传输以使用辅助启动磁盘功能。
- 将 Container-Optimized OS 与 containerd 节点映像搭配使用。Autopilot 节点默认使用此节点映像。
在构建时或使用预加载的容器映像时,准备好数据的磁盘映像。确保您的集群有权访问磁盘映像,以便在节点中加载。
最佳实践: 在 CI/CD 流水线中自动化处理磁盘映像。
限制
辅助启动磁盘具有以下限制:
- 您无法更新现有节点的辅助启动磁盘。如需附加新的磁盘映像,请创建新的节点池。
准备辅助启动磁盘
如需准备辅助启动磁盘,请选择映像标签页以预加载容器映像,或选择数据标签页以预加载数据,然后完成以下说明:
图片
GKE 提供了一种名为 gke-disk-image-builder
的工具,用于创建虚拟机 (VM) 并拉取磁盘上的容器映像,然后通过该磁盘创建磁盘映像。
如需创建具有多个预加载的容器映像的磁盘映像,请完成以下步骤:
- 创建一个 Cloud Storage 存储桶来存储
gke-disk-image-builder
的执行日志。 - 使用
gke-disk-image-builder
创建磁盘映像。
go run ./cli \
--project-name=PROJECT_ID \
--image-name=DISK_IMAGE_NAME \
--zone=LOCATION \
--gcs-path=gs://LOG_BUCKET_NAME \
--disk-size-gb=10 \
--container-image=docker.io/library/python:latest \
--container-image=docker.io/library/nginx:latest
替换以下内容:
- PROJECT_ID:您的 Google Cloud 项目的名称。
- DISK_IMAGE_NAME:磁盘映像的名称。例如
nginx-python-image
。 - LOCATION:集群位置。
- LOG_BUCKET_NAME:用于存储执行日志的 Cloud Storage 存储桶的名称。例如
gke-secondary-disk-image-logs/
。
使用 gke-disk-image-builder
创建磁盘映像时,Google Cloud 会创建多个资源以完成此过程(例如虚拟机实例、临时磁盘和永久性磁盘)。执行完成后,映像构建器会清理您创建的所有资源(磁盘映像除外)。
数据
通过完成以下步骤创建自定义磁盘映像作为数据源:
配置辅助启动磁盘
您可以在 GKE Autopilot 或 Standard 集群中配置辅助启动磁盘。
使用 Autopilot 集群可获得全托管式 Kubernetes 体验。如需选择最适合您的工作负载的 GKE 操作模式,请参阅选择 GKE 操作模式。
使用 GKE Autopilot
在本部分中,您将创建磁盘映像许可名单以允许现有 GKE Autopilot 集群中的磁盘映像。然后,修改 Pod 节点选择器以使用辅助启动磁盘。
允许您的项目中的磁盘映像
在本部分中,您将创建 GCPResourceAllowlist
以允许 GKE 通过 Google Cloud 项目中的磁盘映像创建具有辅助启动磁盘的节点。
将以下清单保存为
allowlist-disk.yaml
:apiVersion: "node.gke.io/v1" kind: GCPResourceAllowlist metadata: name: gke-secondary-boot-disk-allowlist spec: allowedResourcePatterns: - "projects/PROJECT_ID/global/images/.*"
将 PROJECT_ID 替换为您的项目 ID,以托管磁盘映像。
应用清单:
kubectl apply -f allowlist-disk.yaml
GKE 会通过项目中的所有磁盘映像创建具有辅助启动磁盘的节点。
更新 Pod 节点选择器以使用辅助启动磁盘
在本部分中,您将修改 Pod 规范,以便 GKE 创建具有辅助启动磁盘的节点。
将
nodeSelector
添加到 Pod 模板:nodeSelector: cloud.google.com.node-restriction.kubernetes.io/gke-secondary-boot-disk-DISK_IMAGE_NAME=CONTAINER_IMAGE_CACHE.PROJECT_ID
替换以下内容:
- DISK_IMAGE_NAME:磁盘映像的名称。
- PROJECT_ID:用于托管磁盘映像的项目 ID。
使用
kubectl apply
命令通过 Pod 模板应用 Kubernetes 规范。确认正在使用辅助启动磁盘缓存:
kubectl get events --all-namespaces
输出类似于以下内容:
75s Normal SecondaryDiskCachin node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
检查映像拉取延迟时间:
kubectl describe pod POD_NAME
将 POD_NAME 替换为 Pod 的名称。
输出类似于以下内容:
… Normal Pulled 15m kubelet Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s …
无论映像大小如何,缓存的容器映像的预期映像拉取延迟时间都应显著缩短。
使用 GKE Standard
如需创建 GKE 标准集群和节点池,请完成以下说明,并根据您是要在辅助启动磁盘上预加载容器映像还是数据,选择“Images”标签页或“Data”标签页:
图片
如需配置辅助启动磁盘,请使用 Google Cloud CLI 或 Terraform:
gcloud
创建启用了映像流式传输的 GKE Standard 集群:
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-image-streaming
替换以下内容:
- CLUSTER_NAME:您的集群的名称。
- LOCATION:集群位置。
- VERSION:要使用的 GKE 版本。GKE 版本必须为
1.28.3-gke.1067000
或更高版本。
在同一项目中创建具有辅助启动磁盘的节点池:
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location LOCATION \ --enable-image-streaming \ --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE
替换以下内容:
- NODE_POOL_NAME:节点池的名称。
- CLUSTER_NAME:现有集群的名称。
- LOCATION:集群以英文逗号分隔的计算可用区。
- DISK_IMAGE_NAME:磁盘映像的名称。
如需通过不同项目中的磁盘映像创建具有辅助启动磁盘的节点池,请完成使用不同项目中的辅助启动磁盘中的步骤。
将
nodeSelector
添加到 Pod 模板:nodeSelector: cloud.google.com/gke-nodepool: NODE_POOL_NAME
确认正在使用辅助启动磁盘缓存:
kubectl get events --all-namespaces
输出类似于以下内容:
75s Normal SecondaryDiskCachin node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
通过运行以下命令检查映像拉取延迟时间:
kubectl describe pod POD_NAME
将
POD_NAME
替换为 Pod 的名称。输出类似于以下内容:
… Normal Pulled 15m kubelet Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s …
无论映像大小如何,缓存的容器映像的预期映像拉取延迟时间都不应超过几秒钟。
Terraform
如需使用 Terraform 创建具有默认节点池的集群,请参阅以下示例:
在同一项目中创建具有辅助启动磁盘的节点池:
如需详细了解如何使用 Terraform,请参阅针对 GKE 的 Terraform 支持。
将
nodeSelector
添加到 Pod 模板:nodeSelector: cloud.google.com/gke-nodepool: NODE_POOL_NAME
确认正在使用辅助启动磁盘缓存:
kubectl get events --all-namespaces
输出类似于以下内容:
75s Normal SecondaryDiskCachin node/gke-pd-cache-demo-default-pool-75e78709-zjfm Image gcr.io/k8s-staging-jobsejt/pytorch-mnist:latest is backed by secondary disk cache
通过运行以下命令检查映像拉取延迟时间:
kubectl describe pod POD_NAME
将 POD_NAME 替换为 Pod 的名称。
输出类似于以下内容:
… Normal Pulled 15m kubelet Successfully pulled image "docker.io/library/nginx:latest" in 0.879149587s …
无论映像大小如何,缓存的容器映像的预期映像拉取延迟时间都不应超过几秒钟。
如需详细了解如何使用 Terraform,请参阅针对 GKE 的 Terraform 支持。
数据
您可以使用 Google Cloud CLI 或 Terraform 配置辅助启动磁盘并预加载数据:
gcloud
创建启用了映像流式传输的 GKE Standard 集群:
gcloud container clusters create CLUSTER_NAME \ --location=LOCATION \ --cluster-version=VERSION \ --enable-image-streaming
替换以下内容:
- CLUSTER_NAME:您的集群的名称。
- LOCATION:集群位置。
- VERSION:要使用的 GKE 版本。GKE 版本必须为 1.28.3-gke.1067000 或更高版本。
使用
--secondary-boot-disk
标志创建具有辅助启动磁盘的节点池:gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location LOCATION \ --enable-image-streaming \ --secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME
替换以下内容:
- NODE_POOL_NAME:节点池的名称。
- CLUSTER_NAME:现有集群的名称。
- LOCATION:集群以英文逗号分隔的计算可用区。
- DISK_IMAGE_NAME:磁盘映像的名称。
如需通过不同项目中的磁盘映像创建具有辅助启动磁盘的节点池,请完成使用不同项目中的辅助启动磁盘中的步骤。
GKE 会创建一个节点池,其中每个节点都具有一个包含预加载数据的辅助磁盘。GKE 会挂接辅助启动磁盘并将其装载到节点上。
(可选)您可以使用 hostPath 卷装载将辅助磁盘映像装载到 Pod 容器中。使用以下清单可定义 Pod 资源,并使用 hostPath 卷装载在容器中预加载数据磁盘:
apiVersion: v1 kind: Pod metadata: name: pod-name spec: containers: ... volumeMounts: - mountPath: /usr/local/data_path_sbd name: data_path_sbd ... volumes: - name: data_path_sbd hostPath: path: /mnt/disks/gke-secondary-disks/gke-DISK_IMAGE_NAME-disk
将 DISK_IMAGE_NAME 替换为磁盘映像的名称。
Terraform
如需使用 Terraform 创建具有默认节点池的集群,请参阅以下示例:
在同一项目中创建具有辅助启动磁盘的节点池:
如需详细了解如何使用 Terraform,请参阅针对 GKE 的 Terraform 支持。
(可选)您可以使用 hostPath 卷装载将辅助磁盘映像装载到 Pod 容器中。使用以下清单可定义 Pod 资源,并使用 hostPath 卷装载在容器中预加载数据磁盘:
apiVersion: v1 kind: Pod metadata: name: pod-name spec: containers: ... volumeMounts: - mountPath: /usr/local/data_path_sbd name: data_path_sbd ... volumes: - name: data_path_sbd hostPath: path: /mnt/disks/gke-secondary-disks/gke-DISK_IMAGE_NAME-disk
将 DISK_IMAGE_NAME 替换为磁盘映像的名称。
辅助启动磁盘的集群自动扩缩功能
如需创建节点池并在辅助启动磁盘上配置集群自动扩缩,请使用 Google Cloud CLI:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--location LOCATION \
--enable-image-streaming \
--secondary-boot-disk=disk-image=global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE \
--enable-autoscaling \
--num-nodes NUM_NODES \
--min-nodes MIN_NODES \
--max-nodes MAX_NODES
替换以下内容:
- NODE_POOL_NAME:节点池的名称。
- CLUSTER_NAME:现有集群的名称。
- LOCATION:集群以英文逗号分隔的计算可用区。
- DISK_IMAGE_NAME:磁盘映像的名称。
- MIN_NODES:为每个可用区中指定节点池自动扩缩的节点数下限。如需在 GKE 1.24 及更高版本中指定整个节点池的节点数下限,请使用
--total-min-nodes
。标志--total-min-nodes
和--total-max-nodes
与标志--min-nodes
和--max-nodes
互斥。 - MAX_NODES:为每个可用区中指定节点池自动扩缩的节点数上限。如需在 GKE 1.24 及更高版本中指定整个节点池的节点数上限,请使用
--total-max-nodes
。标志--total-min-nodes
和--total-max-nodes
与标志--min-nodes
和--max-nodes
互斥。
辅助启动磁盘的节点自动预配功能
在 GKE 1.30.1-gke.1329000 及更高版本中,您可以配置节点自动预配以自动创建和删除节点池,从而满足工作负载的资源需求。
为辅助启动磁盘创建磁盘映像许可名单自定义资源以进行 GKE 节点自动预配,如下所示:
apiVersion: "node.gke.io/v1" kind: GCPResourceAllowlist metadata: name: gke-secondary-boot-disk-allowlist spec: allowedResourcePatterns: - "projects/<PROJECT_ID>/global/images/.*"
将 PROJECT_ID 替换为您的项目 ID,以托管磁盘映像。
如需在集群中部署许可名单自定义资源,请运行以下命令:
kubectl apply -f ALLOWLIST_FILE
将 ALLOWLIST_FILE 替换为清单文件名。
更新 Pod 节点选择器以使用辅助启动磁盘:
nodeSelector: cloud.google.com.node-restriction.kubernetes.io/gke-secondary-boot-disk-DISK_IMAGE_NAME=CONTAINER_IMAGE_CACHE.PROJECT_ID
替换以下内容:
- DISK_IMAGE_NAME:磁盘映像的名称。
- PROJECT_ID:用于托管磁盘映像的项目 ID。
使用不同项目中的辅助启动磁盘
创建具有辅助启动磁盘的节点池时,您可以使用 --secondary-boot-disk
标志指示 GKE 使用不同项目中的磁盘映像。
使用
--secondary-boot-disk
标志,根据其他项目中的磁盘映像创建具有辅助启动磁盘的节点池。例如:gcloud beta container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location LOCATION \ --enable-image-streaming \ --secondary-boot-disk=disk-image=projects/IMAGE_PROJECT_ID/global/images/DISK_IMAGE_NAME,mode=CONTAINER_IMAGE_CACHE
请替换以下内容:
- DISK_IMAGE_NAME:磁盘映像的名称。
- IMAGE_PROJECT_ID:磁盘映像所属的项目的名称。
GKE 会创建一个节点池,其中每个节点都具有一个包含预加载数据的辅助磁盘。GKE 会挂接辅助启动磁盘并将其装载到节点上。
通过为集群服务账号添加“Compute Image User”角色,授予对属于不同项目的磁盘映像的访问权限:
- 默认计算服务账号:CLUSTER_PROJECT_NUMBER@cloudservices。gserviceaccount.com
- GKE 服务账号:service-CLUSTER_PROJECT_NUMBER@container-engine-robot。iam.gserviceaccount.com
gcloud projects add-iam-policy-binding IMAGE_PROJECT_ID \ --member serviceAccount:CLUSTER_PROJECT_NUMBER@cloudservices.gserviceaccount.com \ --role roles/compute.imageUser gcloud projects add-iam-policy-binding IMAGE_PROJECT_ID \ --member serviceAccount:service-CLUSTER_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \ --role roles/compute.imageUser
后续步骤
- 按照使用映像流式传输拉取容器映像中的说明,根据工作负载的需要流式传输映像数据,从而拉取容器映像。
- 请参阅使用 NCCL Fast Socket 提高工作负载效率,了解如何使用 NVIDIA Collective Communication Library (NCCL) Fast Socket 插件。