Google Kubernetes Engine (GKE) Pod 快照可還原執行中的 Pod 快照,藉此縮短工作負載啟動延遲時間。Pod 快照會儲存整個 Pod 狀態,包括記憶體和對根檔案系統的變更。建立新的副本時,系統會還原快照,而不是從全新狀態初始化 Pod。Pod 隨後會從擷取快照的時間點繼續執行。
本文說明如何為工作負載啟用及設定 GKE Pod 快照。
如要進一步瞭解 Pod 快照的運作方式,請參閱「關於 Pod 快照」。
事前準備
開始之前,請確認你已完成下列工作:
- 啟用 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 中執行。
如要在叢集上啟用這項功能,請完成下列任一步驟:
如要在新叢集上啟用 Pod 快照,請執行下列指令:
gcloud beta container clusters create CLUSTER_NAME \ --enable-pod-snapshots \ --cluster-version=CLUSTER_VERSION \ --workload-pool=PROJECT_ID.svc.id.goog \ --workload-metadata=GKE_METADATA更改下列內容:
CLUSTER_NAME:叢集名稱。CLUSTER_VERSION:新叢集的版本,必須為 1.34.1-gke.3084001 以上版本。PROJECT_ID:您的專案 ID。
如要在現有叢集上啟用 Pod 快照,請完成下列步驟:
將叢集更新至 1.34.1-gke.3084001 以上版本:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=NODEPOOL_NAME \ --cluster-version=CLUSTER_VERSION更改下列內容:
CLUSTER_NAME:叢集名稱。NODEPOOL_VERSION:節點集區名稱。CLUSTER_VERSION:新叢集的更新版本,必須為 1.34.1-gke.3084001 以上版本。
在叢集上啟用 Pod 快照:
gcloud container clusters update CLUSTER_NAME \ --workload-pool=PROJECT_ID .svc.id.goog" \ --enable-pod-snapshots將
PROJECT_ID替換為專案 ID。
在 Standard 叢集上啟用 GKE Sandbox:
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --node-version=NODE_VERSION \ --machine-type=MACHINE_TYPE \ --image-type=cos_containerd \ --sandbox type=gvisor請替換下列變數:
NODE_POOL_NAME:新節點集區的名稱。NODE_VERSION:節點集區使用的版本。MACHINE_TYPE:節點使用的機器類型。
如要進一步瞭解如何使用 gVisor,請參閱「使用 GKE Sandbox 區隔工作負載」。
儲存快照
Pod 快照會儲存在 Cloud Storage bucket 中,其中包含記憶體和 (選用) GPU 狀態。Pod 快照需要 GKE 適用的工作負載身分聯盟,才能啟用及使用 Pod 的服務帳戶向 Cloud Storage 進行驗證。
Pod 快照需要為 bucket 設定下列項目:
- 階層式命名空間:必須啟用,才能提高每秒讀取和寫入查詢次數。階層命名空間也需要啟用統一 bucket 層級存取權。
- 虛刪除:由於 Pod 快照使用平行複合上傳,因此您應停用虛刪除等資料保護功能。如果啟用這項功能,系統刪除暫時物件時可能會大幅增加儲存空間費用。
- 位置:Cloud Storage 值區位置必須與 GKE 叢集位於相同位置,因為如果快照在不同區域之間轉移,效能可能會受到影響。
建立 Cloud Storage bucket
如要建立值區和必要權限,請完成下列步驟:
建立 Cloud Storage bucket。下列指令會建立具有必要設定的值區:
gcloud storage buckets create "gs://BUCKET_NAME" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="LOCATION"更改下列內容:
BUCKET_NAME:bucket 名稱。LOCATION:bucket 的位置。
如需完整的 bucket 建立選項清單,請參閱
buckets create選項。
授予工作負載存取 Cloud Storage bucket 的權限
根據預設,GKE 沒有存取 Cloud Storage 的權限。如要讀取及寫入快照檔案,您必須將 IAM 權限授予工作負載 Pod 使用的 Kubernetes 服務帳戶 (KSA)。
取得憑證,以便使用
kubectl指令與叢集通訊:gcloud container clusters get-credentials "CLUSTER_NAME"針對每個 Pod,完成下列步驟:
為每個 Pod 建立 KSA:
kubectl create serviceaccount "KSA_NAME" \ --namespace "NAMESPACE"更改下列內容:
KSA_NAME:KSA 名稱。NAMESPACE:Pod 的命名空間。
授予 KSA 存取值區的權限:
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/KSA_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/KSA_NAME" \ --role="roles/storage.objectUser"更改下列內容:
PROJECT_NUMBER:您的專案編號。PROJECT_ID:您的專案 ID。
(選用) 為 Cloud Storage bucket 建立受管理資料夾
建立資料夾可讓您隔離互不信任的 Pod 快照權限,這在多租戶用途中非常實用。如要設定代管資料夾,請完成下列步驟:
建立自訂 IAM 角色,僅包含 Pod 快照的必要權限:
gcloud iam roles create podSnapshotGcsReadWriter \ --project="PROJECT_ID" \ --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"將
roles/storage.bucketViewer角色授予目標命名空間中的所有 KSA。這個角色可讓 KSA 讀取 bucket 中繼資料,但不會授予 bucket 中物件的讀取或寫入權限。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"更改下列內容:
PROJECT_NUMBER:您的專案編號。PROJECT_ID:您的專案 ID。
針對每個需要儲存 Pod 快照的 KSA,完成下列步驟:
為 KSA 建立受管理的資料夾:
gcloud storage managed-folders create "gs://BUCKET_NAME/FOLDER_PATH/"將
FOLDER_PATH替換為代管資料夾的路徑,例如my-app-snapshots。在受管理資料夾中,將自訂
podSnapshotGcsReadWriter角色授予 KSA: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/KSA_NAME" \ --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"將
KSA_NAME替換為 KSA 名稱。
設定快照儲存空間
如要指定快照檔案的儲存位置,請建立 PodSnapshotStorageConfig 資源。
以下範例會將 GKE 設定為將 Pod 快照儲存在 Cloud Storage bucket BUCKET_NAME 內的
FOLDER_PATH/路徑中。將下列資訊清單儲存為example-pod-snapshot-storage-config:apiVersion: podsnapshot.gke.io/v1alpha1 kind: PodSnapshotStorageConfig metadata: name: example-pod-snapshot-storage-config namespace: NAMESPACE spec: snapshotStorageConfig: gcs: bucket: "BUCKET_NAME" path: "FOLDER_PATH"更改下列內容:
NAMESPACE:Pod 的命名空間。 預設值為default。BUCKET_NAME:Cloud Storage bucket 的名稱。FOLDER_PATH:Cloud Storage 受管理資料夾的路徑。
套用資訊清單:
kubectl apply -f example-pod-snapshot-storage-config.yaml
建立快照政策
如要為 Pod 啟用快照,請建立 PodSnapshotPolicy 資源,並使用符合 Pod 標籤的選取器。
下列範例會建立適用於具有
app: my-app標籤的 Pod 的政策,並使用example-pod-snapshot-storage-config儲存空間設定。將下列資訊清單儲存為example-pod-snapshot-policy.yaml:apiVersion: podsnapshot.gke.io/v1alpha1 kind: PodSnapshotPolicy metadata: name: example-pod-snapshot-policy namespace: NAMESPACE spec: storageConfigName: example-pod-snapshot-storage-config selector: matchLabels: app: my-app triggerConfig: type: workload postCheckpoint: resume套用資訊清單:
kubectl apply -f example-pod-snapshot-policy.yaml --namespace NAMESPACE
最佳化快照大小
觸發 Pod 快照時,gVisor 會擷取所有容器的完整狀態,包括:
- 應用程式狀態,例如記憶體和暫存器
- 根檔案系統和
tmpfs的變更 (包括emptyDir磁碟區) - 核心狀態,例如開啟的檔案描述元、執行緒和通訊端
快照大小取決於下列因素。快照越大,儲存和還原所需的時間就越長。為提升效能,觸發快照前,您應清除從快照還原 Pod 後不需要的任何應用程式狀態或檔案。
對於大型語言模型 (LLM) 等工作負載,最佳化快照大小尤其重要。LLM 伺服器通常會先將模型權重下載到本機儲存空間 (rootfs 或 tmpfs),再載入 GPU。擷取快照時,系統會儲存 GPU 狀態和模型權重檔案。在這種情況下,如果模型為 100 GB,產生的快照大約為 200 GB (100 GB 的模型檔案,加上代表 GPU 狀態的 100 GB)。將模型權重載入 GPU 後,應用程式通常不需要檔案系統中的檔案即可執行。在觸發快照前刪除這些模型檔案,可將快照大小縮減一半,並以大幅降低的延遲時間還原應用程式。
觸發快照
應用程式準備就緒時,您可以從工作負載內觸發快照,也可以手動觸發特定 Pod 的隨選快照。
從工作負載觸發快照
如要從應用程式程式碼中觸發快照,請將應用程式設定為在準備好建立快照時傳送信號。如要發出就緒信號,請將 1 寫入 /proc/gvisor/checkpoint 檔案,例如 echo 1 > /proc/gvisor/checkpoint.。寫入作業會以非同步方式啟動快照程序,並立即傳回。從相同檔案描述元讀取資料時,讀取程序會遭到封鎖,直到快照和還原作業完成,且工作負載準備好繼續執行為止。
實際用量會因應用程式而異,但下列範例顯示 Python 應用程式的快照觸發程序。如要從這個範例工作負載觸發快照,請完成下列步驟:
將下列資訊清單儲存為
my-app.yaml:apiVersion: v1 kind: Pod metadata: name: my-app namespace: NAMESPACE labels: app: my-app spec: serviceAccountName: KSA_NAME runtimeClassName: gvisor containers: - name: my-container image: python:3.10-slim command: ["python3", "-c"] args: - | import time def trigger_snapshot(): try: with open("/proc/gvisor/checkpoint", "r+") as f: f.write("1") res = f.read().rstrip() print(f"GKE Pod Snapshot: {res}") except FileNotFoundError: print("GKE Pod Snapshot file does not exist -- Pod Snapshots is disabled") return except OSError as e: return e i = 0 while True: print(f"Count: {i}", flush=True) if (i == 20): #simulate the application being ready to snapshot at 20th count trigger_snapshot() i += 1 time.sleep(1) resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "250m" memory: "256Mi"部署應用程式:
kubectl apply -f my-app.yaml
手動觸發快照
如要手動觸發特定 Pod 的隨選快照,請建立 PodSnapshotManualTrigger 資源。手動觸發快照功能適用於 GKE 1.34.1-gke.3556000 以上版本。
以下範例會觸發名為
my-pod的 Pod 快照。將下列資訊清單儲存為example-manual-trigger.yaml:apiVersion: podsnapshot.gke.io/v1alpha1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-pod套用資訊清單:
kubectl apply -f example-manual-trigger.yaml --namespace NAMESPACE
如要確認快照是否已成功觸發,請檢查 PodSnapshotManualTrigger 資源的 status 欄位:
kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io example-manual-trigger -n NAMESPACE -o yaml
status 欄位會指出觸發快照是否成功。
驗證快照
如要確認是否已拍攝快照,請查看 GKEPodSnapshotting 事件的事件記錄:
kubectl get events -o \
custom-columns=NAME:involvedObject.name,CREATIONTIME:.metadata.creationTimestamp,REASON:.reason,MESSAGE:.message \
--namespace NAMESPACE \
--field-selector involvedObject.name=POD_NAME,reason=GKEPodSnapshotting
將 POD_NAME 換成 Pod 的名稱,例如 my-app 或 my-pod。
輸出結果會與下列內容相似:
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
管理快照
建立 Pod 快照時,系統會建立 PodSnapshot CRD 資源,儲存當時的 Pod 狀態。這項資源的 status 欄位會指出快照作業是否成功,以及快照是否可用於還原。
如要查看命名空間中的所有 PodSnapshot 資源,請執行下列指令:
kubectl get podsnapshots.gke.io --namespace NAMESPACE
輸出結果會與下列內容相似:
NAME STATUS POLICY AGE
de334898-1e7a-4cdb-9f2e-7cc2181c29e4 AllSnapshotsAvailable example-policy 47h
從快照還原工作負載
如要從最新快照還原工作負載,您可以在建立快照後刪除現有 Pod,然後重新部署 Pod。或者,您也可以部署規格相同的新 Pod。GKE 會自動從相符的快照還原 Pod。
下列步驟說明如何刪除並重新部署 Pod,從相符的快照還原 Pod:
刪除 Pod:
kubectl delete -f POD_NAME.yaml將
POD_NAME替換為 Pod 名稱,例如my-app。重新套用 Pod:
kubectl apply -f POD_NAME.yaml查看記錄,確認快照還原作業:
kubectl logs my-app --namespace NAMESPACE輸出內容取決於應用程式的設定方式。在範例應用程式中,記錄檔會顯示還原作業發生的時間。
GKE Pod Snapshot: restore
從特定快照還原
根據預設,GKE 會從與 Pod 相符的最新PodSnapshot
資源還原工作負載。系統擷取快照時,GKE 會自動為 PodSnapshot 資源產生專屬名稱 (UUID),您可以執行 kubectl get podsnapshots.gke.io --namespace NAMESPACE 查看。
如要從較舊或特定的 PodSnapshot 資源還原工作負載,請將 podsnapshot.gke.io/ps-name 註解新增至工作負載 Pod 規格,並指定要用於還原工作負載的 PodSnapshot 資源名稱:
apiVersion: v1
kind: Pod
metadata:
name: my-app
namespace: NAMESPACE
labels:
app: my-app
annotations:
podsnapshot.gke.io/ps-name: "POD_SNAPSHOT_NAME"
spec:
serviceAccountName: KSA_NAME
runtimeClassName: gvisor
containers:
...
將 POD_SNAPSHOT_NAME 替換為要還原的快照名稱。您可以執行 kubectl get podsnapshots.gke.io --namespace NAMESPACE 指令來取得快照名稱。
如要讓 GKE 使用指定的快照進行還原,PodSnapshot 資源狀態條件必須為 Ready,且與 Pod 位於相同命名空間。如果 PodSnapshot 不是 Ready,或不存在於與 Pod 相同的命名空間中,工作負載會執行冷啟動,而不是從快照還原。
停用快照
移除 PodSnapshotPolicy CRD 會導致 Pod 無法建立快照和還原。資源刪除作業不會影響正在執行的 Pod。不過,如果在儲存或還原 Pod 時刪除政策,Pod 可能會進入失敗狀態。
如要針對受政策控管的新 Pod 停用快照和還原功能,請執行下列指令刪除 PodSnapshotPolicy:
kubectl delete podsnapshotpolicies.podsnapshot.gke.io SNAPSHOT_POLICY --namespace=NAMESPACE
將 SNAPSHOT_POLICY 替換為要刪除的 PodSnapshotPolicy 名稱,例如 example-pod-snapshot-policy。
您也可以刪除特定PodSnapshot資源,這樣一來,系統就不會再從該特定快照還原 Pod。刪除 PodSnapshot 資源也會移除儲存在 Cloud Storage 中的檔案。
如要避免特定快照用於日後的還原作業,請執行下列指令,刪除 PodSnapshot 物件:
kubectl delete podsnapshots.podsnapshot.gke.io POD_SNAPSHOT_NAME --namespace=NAMESPACE
將 POD_SNAPSHOT_NAME 替換為要刪除的快照名稱,例如 example-podsnapshot。
後續步驟
- 進一步瞭解 Pod 快照概念。
- 請參閱 Pod 快照自訂資源定義 (CRD)。