觸發 Pod 快照

如要縮短 Google Kubernetes Engine (GKE) 工作負載的啟動延遲時間,您可以為執行中的 Pod 建立快照,並從中還原新的 Pod。本文說明如何建立 Pod 快照政策,以及如何從工作負載或手動觸發快照。如要進一步瞭解 Pod 快照的運作方式,請參閱「關於 GKE Pod 快照」。

平台管理員、操作人員和應用程式開發人員,可以參考這份文件設定快照政策及觸發快照。如要進一步瞭解 Cloud de Confiance by S3NS內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。

事前準備

開始之前,請確認您已執行下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝並初始化 gcloud CLI。如果先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 完成必要條件,並在叢集啟用 Pod 快照。如要進一步瞭解如何準備叢集和儲存空間,請參閱「準備 Pod 快照」。

建立快照政策

如要為 Pod 啟用快照,請建立 PodSnapshotPolicy 自訂資源,並使用與 Pod 標籤相符的選取器:

  1. 將下列資訊清單儲存為 example-pod-snapshot-policy.yaml。這個範例會建立適用於具有 app: my-app 標籤的 Pod 的政策。這項政策會使用您在「準備 Pod 快照」中建立的 example-pod-snapshot-storage-config PodSnapshotStorageConfig 自訂資源,定義快照儲存位置:

    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotPolicy
    metadata:
      name: example-pod-snapshot-policy
      namespace: NAMESPACE
    spec:
      storageConfigName: example-pod-snapshot-storage-config
      selector:
        matchLabels:
          app: my-app
      triggerConfig:
        type: TRIGGER_TYPE
        postCheckpoint: resume
    

    更改下列內容:

    • NAMESPACE:Pod 的命名空間。請使用您在「準備 Pod 快照」中授予 Cloud Storage 存取權的命名空間。
    • TRIGGER_TYPE:觸發條件類型。支援的值為 workload (適用於工作負載型觸發條件) 或 manual (適用於隨選快照)。

    在本範例中,postCheckpoint: resume 設定會在 GKE 建立快照後,讓 Pod 保持運作。

    如需可設定欄位的完整清單,請參閱 PodSnapshotPolicy 規格。

  2. 套用資訊清單:

    kubectl apply -f example-pod-snapshot-policy.yaml
    

調整其他 Pod 快照政策設定

除了必要的選取器、儲存空間設定和觸發條件外,PodSnapshotPolicy 自訂資源也支援選用設定。這些額外設定可控管各個快照擷取的內容、GKE 保留快照的時間長度,以及 GKE 如何將快照分組以進行還原:

  • 快照範圍:如要指定快照應擷取 Pod 狀態的哪些部分,請設定 spec.snapshotScope 欄位。支援的值為 whole-pod (預設) 和 rootfs-only。whole-pod 範圍會擷取整個 Pod,包括應用程式狀態、記憶體和檔案系統。rootfs-only 範圍只會擷取容器根檔案系統。rootfs-only 範圍需要 GKE 1.35.3-gke.1031000 以上版本。

  • 自動清除:如要自動清除舊的 PodSnapshot 自訂資源,請使用 spec.retentionConfig 欄位設定保留政策。您可以使用 lastAccessTimeout 欄位指定時間長度,例如 7d。超過這個時間長度後,GKE 就會刪除快照。

  • 快照分組:如要隔離在類似環境但不同情境下擷取的快照,請在 spec.snapshotGroupingRules 欄位中指定分組標籤。舉例來說,在多租戶情境中,如果所有使用者的基礎 Pod 都相同,您可以依使用者或群組隔離快照。還原期間,GKE 只會從同一個標籤群組中選取快照。如要進一步瞭解這項分組作業如何影響還原期間的相容性比對,請參閱「分組規則比對」。

您可以獨立設定快照範圍、保留和分組設定。以下範例顯示 PodSnapshotPolicy 自訂資源中的所有三項設定:

# Multiple lines are omitted here
spec:
  snapshotScope: rootfs-only
  retentionConfig:
    lastAccessTimeout: 7d
  snapshotGroupingRules:
    groupByLabelValue:
      labels: ["tenant", "environment"]
      groupRetentionPolicy:
        maxSnapshotCountPerGroup: 5

如需可設定欄位的完整清單,請參閱 PodSnapshotPolicy 規格。

最佳化快照大小

快照越大,儲存和還原所需的時間就越長。觸發快照前,請先刪除 GKE 從快照還原 Pod 後,應用程式不需要的任何暫存檔案或應用程式狀態,藉此縮減快照大小。

使用預設的 whole-pod 快照範圍時,GKE Sandbox 會擷取所有容器的完整狀態,包括:

  • 應用程式狀態,例如記憶體和暫存器
  • 變更根檔案系統和 tmpfs 掛接 (包括 emptyDir 磁碟區)
  • 核心狀態,例如開啟的檔案描述元、執行緒和通訊端

對於大型語言模型 (LLM) 等工作負載,最佳化快照大小尤其重要。LLM 伺服器通常會先將模型權重下載到本機儲存空間 (rootfs 或 tmpfs),再載入 GPU。建立快照時,GKE Sandbox 會儲存 GPU 狀態和模型權重檔案。在這種情況下,如果模型為 100 GB,則產生的快照約為 200 GB (100 GB 的模型檔案,加上代表 GPU 狀態的 100 GB)。應用程式將模型權重載入 GPU 後,通常不需要檔案系統中的檔案即可執行。在觸發快照前刪除這些模型檔案,可將快照大小縮減一半,並大幅降低還原應用程式的延遲時間。

觸發快照

選擇下列其中一種方法觸發快照:

  • 工作負載觸發條件:如果可以修改應用程式,在應用程式準備好建立快照時發出信號 (例如初始化完成後),請使用這個方法。這個方法最適合改善水平擴充工作負載的啟動延遲。工作負載觸發條件在工作負載週期中只會執行一次。

  • 手動觸發:如果無法修改應用程式來發出就緒信號,或想視需要建立特定 Pod 的快照,請使用這個方法。您可以視需要建立多個手動觸發條件。

從工作負載觸發快照

如要從應用程式程式碼中觸發快照,請設定應用程式,在準備好建立快照時傳送信號。如要表示準備就緒,請將 1 值寫入 /proc/gvisor/checkpoint 檔案,例如執行 echo 1 > /proc/gvisor/checkpoint 指令。寫入作業會以非同步方式啟動快照程序,並立即傳回。從同一個檔案描述元讀取資料時,系統會封鎖讀取程序,直到快照或還原作業完成,且工作負載準備好繼續執行為止。

從工作負載觸發快照前,請確認快照政策已選取 Pod。該政策中 triggerConfig.type 欄位的值必須設為 workload。

確切用法會因應用程式而異,但以下範例顯示 Python 應用程式的快照觸發條件。如要從這個範例工作負載觸發快照,請按照下列步驟操作:

  1. 將下列資訊清單儲存為 my-app.yaml。在這個範例中,app: my-app 標籤與範例快照政策中的選取器相符,而 runtimeClassName: gvisor 設定會在 GKE Sandbox 中執行 Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-app
      namespace: NAMESPACE
      labels:
        app: my-app
    spec:
      serviceAccountName: SERVICEACCOUNT_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
            i = 0
            while True:
              print(f"Count: {i}", flush=True)
              if (i == 20): # Simulate readiness at the 20th count
                trigger_snapshot()
              i += 1
              time.sleep(1)
        resources:
          limits:
            cpu: "500m"
            memory: "512Mi"
          requests:
            cpu: "250m"
            memory: "256Mi"
    

    更改下列內容:

    • NAMESPACE:Pod 的命名空間。
    • SERVICEACCOUNT_NAME:您在「準備 Pod 快照」中授予 Cloud Storage 存取權的 ServiceAccount 物件名稱。
  2. 部署應用程式:

    kubectl apply -f my-app.yaml
    

    應用程式啟動並發出準備就緒的信號後,GKE Sandbox 就會建立快照。如要確認快照是否成功,請參閱「驗證快照」。

手動觸發快照

手動觸發快照前,請確認目標 Pod 正在運作,且快照政策已選取該 Pod。該政策中 triggerConfig.type 欄位的值必須設為 manual。

如要手動觸發特定 Pod 的隨選快照,請按照下列步驟建立 PodSnapshotManualTrigger 自訂資源:

  1. 將下列資訊清單儲存為 example-manual-trigger.yaml。以下範例會觸發名為 my-pod 的 Pod 快照:

    apiVersion: podsnapshot.gke.io/v1
    kind: PodSnapshotManualTrigger
    metadata:
      name: example-manual-trigger
      namespace: NAMESPACE
    spec:
      targetPod: my-pod
    

    將 NAMESPACE 替換為 Pod 的命名空間。

  2. 套用資訊清單:

    kubectl apply -f example-manual-trigger.yaml
    
  3. 如要確認快照是否成功觸發,請查看 PodSnapshotManualTrigger 自訂資源的 status 部分:

    kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \
        example-manual-trigger \
        --namespace NAMESPACE -o yaml
    

    將 NAMESPACE 替換為 Pod 的命名空間。

    如果觸發成功,status.conditions 欄位會顯示檢查點已完成,status.snapshotCreated 欄位則會顯示已建立的 PodSnapshot 自訂資源名稱。

驗證快照

如要確認 GKE 是否已建立快照,請查看 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

更改下列內容:

  • NAMESPACE:Pod 的命名空間。
  • POD_NAME:Pod 的名稱。

輸出結果會與下列內容相似:

NAME                                    CREATIONTIME           REASON               MESSAGE
default/5b449f9c7c-bd7pc                2025-11-05T16:25:11Z   GKEPodSnapshotting   Successfully checkpointed the pod to PodSnapshot

「MESSAGE」欄會顯示「Successfully checkpointed the pod to PodSnapshot」,確認 GKE 已將 Pod 狀態儲存至 PodSnapshot 自訂資源。如要查看及管理 PodSnapshot 自訂資源,請參閱「管理快照」。

後續步驟