本页面介绍了如何通过在 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 预配节点并为其预加载数据(例如机器学习模型)或容器映像。对于工作负载,使用辅助磁盘中预加载的容器映像或数据具有以下优势:
- 缩短了拉取大型容器映像或下载数据时的延迟时间
- 更快的自动扩缩
- 更快地从中断(例如维护事件和系统错误)中恢复
以下部分介绍了如何在 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 Standard 集群和节点池,请按照以下说明操作,并根据您要在辅助启动磁盘上预加载容器映像还是预加载数据,选择“映像”或“数据”标签页:
图片
您可以使用 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.106700
或更高版本。
在同一项目中创建具有辅助启动磁盘的节点池:
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 创建具有默认节点池的集群,请参阅以下示例:
将
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.106700 或更高版本。
使用
--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 会创建一个节点池,其中每个节点都具有一个包含预加载数据的辅助磁盘。此操作会挂接辅助启动磁盘并将其装载到节点上。
通过为集群服务账号添加“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 插件。