借助 Google Kubernetes Engine (GKE) Pod 快照,您可以保存和恢复正在运行的 Pod 状态,从而缩短工作负载启动延迟时间。在捕获工作负载的快照之前,您必须准备好集群和存储环境。
通过本文档,您可以了解如何在集群上启用和配置 Pod 快照,以及如何设置 Cloud Storage 来存储快照。如需详细了解 Pod 快照的工作原理,请参阅 GKE Pod 快照简介。
平台管理员、运维人员和应用开发者可以使用本文档来配置集群、创建存储桶以及为 Pod 快照设置访问权限。如需详细了解我们在 Google Cloud 内容中提及的常见角色和示例任务,请参阅常见的 GKE 用户角色和任务。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如需使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
启用 Pod 快照
您可以在新集群或现有集群上启用 Pod 快照。Pod 快照需要 GKE Sandbox 和 Workload Identity Federation for GKE。Autopilot 集群默认启用这两项功能。对于 Standard 集群,您必须在集群上启用 Workload Identity Federation for GKE,并配置节点池以在 GKE Sandbox 中运行。
如需在集群上启用 Pod 快照,请按照您要使用的 GKE 操作模式的步骤操作:
Autopilot
如需在新集群上启用 Pod 快照,请运行以下命令:
gcloud container clusters create-auto CLUSTER_NAME \ --enable-pod-snapshots \ --location=CONTROL_PLANE_LOCATION \ --cluster-version=CLUSTER_VERSION替换以下内容:
CLUSTER_NAME:您的集群的名称。CONTROL_PLANE_LOCATION:集群控制平面的位置。CLUSTER_VERSION:新集群的版本,必须为 1.35.3-gke.1234000 或更高版本。
如需在现有集群上启用 Pod 快照,请按照以下步骤操作:
将集群升级到 1.35.3-gke.1234000 版或更高版本:
gcloud container clusters upgrade CLUSTER_NAME \ --cluster-version=CLUSTER_VERSION \ --location=CONTROL_PLANE_LOCATION替换以下内容:
CLUSTER_NAME:您的集群的名称。CLUSTER_VERSION:要将集群升级到的版本,必须为 1.35.3-gke.1234000 或更高版本。CONTROL_PLANE_LOCATION:集群控制平面的位置。
在集群上启用 Pod 快照:
gcloud container clusters update CLUSTER_NAME \ --enable-pod-snapshots \ --location=CONTROL_PLANE_LOCATION替换以下内容:
CLUSTER_NAME:您的集群的名称。CONTROL_PLANE_LOCATION:集群控制平面的位置。
具有默认 whole-pod 范围的 Pod 快照不支持 E2 机器类型,而文件系统快照 (rootfs-only) 支持。在 Autopilot 集群中,GKE 默认可能会在 E2 节点上调度 Pod。如果您使用 whole-pod 范围,请使用 ComputeClass 自定义资源,以帮助确保您的工作负载在兼容的硬件上运行。
如需创建和使用 ComputeClass 自定义资源,请按照以下步骤操作:
将以下清单保存为
non-e2-class.yaml:apiVersion: cloud.google.com/v1 kind: ComputeClass metadata: name: non-e2-class spec: priorities: - machineFamily: n2 - machineFamily: c3 activeMigration: optimizeRulePriority: false whenUnsatisfiable: DoNotScaleUp应用清单:
kubectl apply -f non-e2-class.yaml在 Pod 规范中,使用
cloud.google.com/compute-class节点选择器引用 ComputeClass 自定义资源:spec: nodeSelector: cloud.google.com/compute-class: non-e2-class # Multiple lines are omitted here
标准
如需在新集群上启用 Pod 快照,请运行以下命令:
gcloud container clusters create CLUSTER_NAME \ --enable-pod-snapshots \ --cluster-version=CLUSTER_VERSION \ --workload-pool=PROJECT_ID.svc.id.goog \ --workload-metadata=GKE_METADATA \ --location=CONTROL_PLANE_LOCATION替换以下内容:
CLUSTER_NAME:您的集群的名称。CLUSTER_VERSION:新集群的版本,必须为 1.35.3-gke.1234000 或更高版本。PROJECT_ID:您的项目 ID。CONTROL_PLANE_LOCATION:集群控制平面的位置。
如需在现有集群上启用 Pod 快照,请按照以下步骤操作:
将集群升级到 1.35.3-gke.1234000 版或更高版本:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=NODE_POOL_NAME \ --cluster-version=CLUSTER_VERSION \ --location=CONTROL_PLANE_LOCATION替换以下内容:
CLUSTER_NAME:您的集群的名称。NODE_POOL_NAME:节点池的名称。CLUSTER_VERSION:要将集群升级到的版本,必须为 1.35.3-gke.1234000 或更高版本。CONTROL_PLANE_LOCATION:集群控制平面的位置。
在集群上启用 Pod 快照:
gcloud beta container clusters update CLUSTER_NAME \ --enable-pod-snapshots \ --location=CONTROL_PLANE_LOCATION替换以下内容:
CLUSTER_NAME:您的集群的名称。CONTROL_PLANE_LOCATION:集群控制平面的位置。
如需在 Standard 集群上的 GKE Sandbox 中运行 Pod,您必须创建或更新启用了 GKE Sandbox 的节点池。如需更新节点池,请使用 --sandbox type=gvisor 标志。如需创建已启用 GKE Sandbox 的节点池,请运行以下命令:
gcloud container node-pools create NODE_POOL_NAME \
--cluster=CLUSTER_NAME \
--node-version=NODE_VERSION \
--machine-type=MACHINE_TYPE \
--location=CONTROL_PLANE_LOCATION \
--image-type=cos_containerd \
--sandbox type=gvisor
替换以下内容:
NODE_POOL_NAME:新节点池的名称。CLUSTER_NAME:您的集群的名称。NODE_VERSION:用于节点池的版本。MACHINE_TYPE:用于节点的机器类型。CONTROL_PLANE_LOCATION:集群控制平面的位置。
如需详细了解 GKE Sandbox,请参阅利用 GKE Sandbox 强化工作负载隔离。
存储快照
GKE 会将 Pod 快照存储在 Cloud Storage 存储桶中。每个快照都包含应用内存以及 Pod 的 GPU 状态(可选)。如需向 Cloud Storage 进行身份验证,Pod 快照会使用 Pod 的 ServiceAccount 对象,这需要Workload Identity Federation for GKE。
Pod 快照需要以下存储桶配置:
- 分层命名空间:您必须启用分层命名空间,才能支持更高的每秒读写查询次数。分层命名空间还要求您启用统一存储桶级访问权限。
- 软删除:由于 Pod 快照使用并行复合上传,因此请停用软删除等数据保护功能。如果您让这些功能保持启用状态,则临时对象的软删除可能会大幅增加您的存储费用。
- 位置:Cloud Storage 存储桶位置必须与 GKE 集群位于同一位置,因为跨不同区域传输快照可能会影响性能。
如需创建具有所需配置的存储桶,请运行以下命令:
gcloud storage buckets create gs://BUCKET_NAME \
--uniform-bucket-level-access \
--enable-hierarchical-namespace \
--soft-delete-duration=0d \
--location=LOCATION
替换以下内容:
BUCKET_NAME:存储桶的名称。LOCATION:存储桶的位置。
如需查看存储桶创建的选项的完整列表,请参阅 buckets create 命令文档中的标志。
授予工作负载对 Cloud Storage 存储桶的访问权限
默认情况下,GKE 无权访问 Cloud Storage。如需读取和写入 Pod 快照,您必须向工作负载 Pod 使用的 Kubernetes ServiceAccount 对象授予包含相应权限的 IAM 角色,或使用短期令牌启用多租户。
向特定 Kubernetes ServiceAccount 对象授予角色
如需向特定 Kubernetes ServiceAccount 对象授予角色,请按照以下步骤操作:
如需使用
kubectl命令与集群通信,请获取集群的凭据:gcloud container clusters get-credentials CLUSTER_NAME \ --location=CONTROL_PLANE_LOCATION替换以下内容:
CLUSTER_NAME:您的集群的名称。CONTROL_PLANE_LOCATION:集群控制平面的位置。
对于每个 Pod,请按以下步骤操作:
创建 ServiceAccount 对象:
kubectl create serviceaccount SERVICEACCOUNT_NAME \ --namespace=NAMESPACE替换以下内容:
SERVICEACCOUNT_NAME:ServiceAccount 对象的名称。NAMESPACE:Pod 的命名空间。
向 ServiceAccount 对象授予访问存储桶的权限。根据您的安全要求,选择以下选项之一:
- 标准权限:授予完整的读取、写入和删除权限。
- 单次写入权限:防止覆盖或删除已完成的快照文件,但授予删除并行复合上传的临时对象的权限。
如需授予权限,请运行所选选项对应的命令:
标准权限
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.bucketViewer"gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.objectUser"一次性写入权限
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.bucketViewer"gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.objectCreator"gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.objectViewer"gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.objectUser" \ --condition='expression=resource.type == "storage.googleapis.com/Object" && (resource.name.extract("/pages.img_{part}") != "" || resource.name.extract("/fs_checkpoint_pages.img_{part}") != ""),title=allow_pcu_temp_part_cleanup,description=Allow deleting temporary parallel composite upload part objects only'替换以下内容:
BUCKET_NAME:存储桶的名称。PROJECT_NUMBER:您的项目编号。PROJECT_ID:您的项目 ID。NAMESPACE:Pod 的命名空间。SERVICEACCOUNT_NAME:ServiceAccount 对象的名称。
使用短期 token 启用多租户
除了向单个 ServiceAccount 对象授予权限之外,您还可以使用短期有效的范围受限令牌启用多租户。此方法有助于避免与手动 IAM 绑定相关的传播延迟。您无需向每个 ServiceAccount 对象授予权限,而是向 GKE 节点服务账号一次性授予快照存储桶的 Storage Admin 角色 (roles/storage.admin)。然后,节点服务账号会根据需要为特定路径创建短期有效的令牌。
如需通过 Pod 快照启用令牌,需要使用 GKE 1.35.3-gke.1737000 版或更高版本。
如需启用多租户,请按以下步骤操作:
如需向节点服务账号授予使用存储桶的权限,请运行以下命令:
gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="serviceAccount:service-PROJECT_NUMBER@gcp-sa-gkenode.iam.gserviceaccount.com" \ --role="roles/storage.admin"替换以下内容:
BUCKET_NAME:存储桶的名称。PROJECT_NUMBER:您的项目编号。
为快照配置存储空间时,请将
tokenSource字段的值设置为federatedP4SA。
向 Pod 快照控制器授予对 Cloud Storage 存储桶的访问权限
如需允许 Pod 快照控制器删除 Cloud Storage 存储桶中的快照,您必须向项目中的 GKE 服务代理授予 Storage Object User 角色 (roles/storage.objectUser)。如需授予该角色,请运行以下命令:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com" \
--role="roles/storage.objectUser" \
--condition="expression=resource.name.startsWith(\"projects/_/buckets/BUCKET_NAME\"),title=restrict_to_bucket,description=Restricts access to one bucket only"
替换以下内容:
PROJECT_ID:您的项目 ID。PROJECT_NUMBER:您的项目编号。BUCKET_NAME:存储桶的名称。
可选:为 Cloud Storage 存储桶创建托管式文件夹
如需隔离来自互不信任的 Pod 的快照权限(这在多租户用例中非常有用),请创建托管文件夹。如需设置托管文件夹,请按以下步骤操作:
创建一个自定义 IAM 角色,其中仅包含 Pod 快照所需的权限。运行所选选项对应的命令:
标准权限
gcloud iam roles create podSnapshotGcsReadWriter \ --project=PROJECT_ID \ --permissions="storage.objects.get,storage.objects.list,storage.objects.create,storage.objects.delete,storage.folders.create"一次性写入权限
gcloud iam roles create podSnapshotGcsReadWriter \ --project=PROJECT_ID \ --permissions="storage.objects.get,storage.objects.list,storage.objects.create,storage.folders.create"将
PROJECT_ID替换为您的项目 ID。向目标命名空间中的所有 ServiceAccount 对象授予 Storage Bucket Viewer 角色 (
roles/storage.bucketViewer)。此角色允许 ServiceAccount 对象读取存储桶元数据,但不授予它们读取或写入存储桶中对象的权限。gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \ --member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/namespace/NAMESPACE" \ --role="roles/storage.bucketViewer"替换以下内容:
BUCKET_NAME:存储桶的名称。PROJECT_NUMBER:您的项目编号。PROJECT_ID:您的项目 ID。NAMESPACE:Pod 的命名空间。
对于需要存储 Pod 快照的每个 ServiceAccount 对象,请按照以下步骤操作:
为 ServiceAccount 对象创建托管文件夹:
gcloud storage managed-folders create gs://BUCKET_NAME/FOLDER_PATH/替换以下内容:
BUCKET_NAME:存储桶的名称。FOLDER_PATH:代管式文件夹的路径(例如my-app-snapshots)。
向 ServiceAccount 对象授予对代管文件夹的自定义
podSnapshotGcsReadWriter角色。如需授予权限,请运行所选选项对应的命令:标准权限
gcloud storage managed-folders add-iam-policy-binding gs://BUCKET_NAME/FOLDER_PATH/ \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"一次性写入权限
gcloud storage managed-folders add-iam-policy-binding gs://BUCKET_NAME/FOLDER_PATH/ \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"gcloud storage managed-folders add-iam-policy-binding gs://BUCKET_NAME/FOLDER_PATH/ \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/NAMESPACE/sa/SERVICEACCOUNT_NAME" \ --role="roles/storage.objectUser" \ --condition='expression=resource.type == "storage.googleapis.com/Object" && (resource.name.extract("/pages.img_{part}") != "" || resource.name.extract("/fs_checkpoint_pages.img_{part}") != ""),title=allow_pcu_temp_part_cleanup,description=Allow deleting temporary parallel composite upload part objects only'替换以下内容:
BUCKET_NAME:存储桶的名称。FOLDER_PATH:代管式文件夹的路径(例如my-app-snapshots)。PROJECT_NUMBER:您的项目编号。PROJECT_ID:您的项目 ID。NAMESPACE:Pod 的命名空间。SERVICEACCOUNT_NAME:ServiceAccount 对象的名称。
为快照配置存储空间
如需指定 Pod 快照的存储位置,请创建 PodSnapshotStorageConfig 自定义资源:
将以下清单保存为
example-pod-snapshot-storage-config.yaml。此示例将 GKE 配置为将 Pod 快照存储在 Cloud Storage 存储桶BUCKET_NAME内的FOLDER_PATH/路径中:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config spec: snapshotStorageConfig: gcs: bucket: "BUCKET_NAME" path: "FOLDER_PATH" tokenSource: "TOKEN_SOURCE"替换以下内容:
BUCKET_NAME:Cloud Storage 存储桶的名称。FOLDER_PATH:Cloud Storage 托管文件夹的路径。TOKEN_SOURCE:用于访问的身份提供方。使用podKSA(默认)或federatedP4SA实现多租户。
应用清单:
kubectl apply -f example-pod-snapshot-storage-config.yaml
后续步骤
了解如何触发 Pod 快照。