Google Kubernetes Engine (GKE) 포드 스냅샷은 실행 중인 포드의 스냅샷을 복원하여 워크로드 시작 지연 시간을 개선하는 데 도움이 됩니다. 포드 스냅샷은 메모리 및 루트 파일 시스템의 변경사항을 포함한 전체 포드 상태를 저장합니다. 새 복제본이 생성되면 초기 상태에서 포드를 초기화하는 대신 스냅샷이 복원됩니다. 그러면 포드가 스냅샷이 생성된 시점부터 실행을 재개합니다.
이 문서에서는 워크로드에 대해 GKE 포드 스냅샷을 사용 설정하고 구성하는 방법을 설명합니다.
포드 스냅샷 작동 방식에 대한 자세한 내용은 포드 스냅샷 정보를 참고하세요.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면
gcloud components update명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
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입니다.
기존 클러스터에서 포드 스냅샷을 사용 설정하려면 다음 단계를 완료하세요.
클러스터를 버전 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 이상이어야 합니다.
클러스터에서 포드 스냅샷을 사용 설정합니다.
gcloud container clusters update CLUSTER_NAME \ --workload-pool=PROJECT_ID .svc.id.goog" \ --enable-pod-snapshotsPROJECT_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를 사용하여 워크로드 격리를 참고하세요.
스냅샷 저장
포드 스냅샷은 메모리 및 (선택적으로) GPU 상태를 포함하는 Cloud Storage 버킷에 저장됩니다. 포드 스냅샷을 사용하려면 GKE용 워크로드 아이덴티티 제휴를 사용하여 포드의 서비스 계정을 사용 설정하고 Cloud Storage에 인증해야 합니다.
Pod 스냅샷에는 버킷에 다음 구성이 필요합니다.
- 계층적 네임스페이스: 초당 읽기 및 쓰기 쿼리 수를 늘리려면 사용 설정해야 합니다. 계층적 네임스페이스를 사용하려면 균일한 버킷 수준 액세스도 사용 설정해야 합니다.
- 소프트 삭제: 포드 스냅샷은 병렬 복합 업로드를 사용하므로 소프트 삭제와 같은 데이터 보호 기능을 사용 중지해야 합니다. 사용 설정된 상태로 두면 임시 객체 삭제로 인해 스토리지 요금이 크게 증가할 수 있습니다.
- 위치: 스냅샷이 서로 다른 리전 간에 전송되면 성능에 영향을 미칠 수 있으므로 Cloud Storage 버킷 위치는 GKE 클러스터와 동일한 위치여야 합니다.
Cloud Storage 버킷 만들기
버킷과 필요한 권한을 만들려면 다음 단계를 완료하세요.
Cloud Storage 버킷을 만듭니다. 다음 명령어는 필요한 구성으로 버킷을 만듭니다.
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에 액세스할 수 있는 권한이 없습니다. 스냅샷 파일을 읽고 쓰려면 워크로드 포드에서 사용하는 Kubernetes 서비스 계정 (KSA)에 IAM 권한을 부여해야 합니다.
kubectl명령어로 클러스터와 통신할 수 있도록 사용자 인증 정보를 가져옵니다.gcloud container clusters get-credentials "CLUSTER_NAME"각 Pod에 대해 다음 단계를 완료합니다.
각 포드의 KSA를 만듭니다.
kubectl create serviceaccount "KSA_NAME" \ --namespace "NAMESPACE"다음을 바꿉니다.
KSA_NAME: KSA의 이름입니다.NAMESPACE: 포드의 네임스페이스입니다.
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 버킷의 관리 폴더 만들기
폴더를 만들면 서로 신뢰할 수 없는 포드의 스냅샷 권한을 격리할 수 있으며 이는 멀티 테넌트 사용 사례에 유용합니다. 관리 폴더를 설정하려면 다음 단계를 완료하세요.
Pod 스냅샷에 필요한 권한만 포함된 커스텀 IAM 역할을 만듭니다.
gcloud iam roles create podSnapshotGcsReadWriter \ --project="PROJECT_ID" \ --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"타겟 네임스페이스의 모든 KSA에
roles/storage.bucketViewer역할을 부여합니다. 이 역할을 사용하면 KSA가 버킷 메타데이터를 읽을 수 있지만 버킷의 객체에 대한 읽기 또는 쓰기 권한은 부여되지 않습니다.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입니다.
포드 스냅샷을 저장해야 하는 각 KSA에 대해 다음 단계를 완료합니다.
KSA의 관리형 폴더를 만듭니다.
gcloud storage managed-folders create "gs://BUCKET_NAME/FOLDER_PATH/"FOLDER_PATH을 관리 폴더의 경로로 바꿉니다(예:my-app-snapshots).관리 폴더에 KSA에 맞춤
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/KSA_NAME" \ --role="projects/PROJECT_ID/roles/podSnapshotGcsReadWriter"KSA_NAME을 KSA 이름으로 바꿉니다.
스냅샷 스토리지 구성
스냅샷 파일을 저장할 위치를 지정하려면 PodSnapshotStorageConfig 리소스를 만드세요.
다음 예에서는 Cloud Storage 버킷 BUCKET_NAME 내의
FOLDER_PATH/경로에 포드 스냅샷을 저장하도록 GKE를 구성합니다. 다음 매니페스트를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: 포드의 네임스페이스입니다. 기본적으로default입니다.BUCKET_NAME: Cloud Storage 버킷 이름.FOLDER_PATH: Cloud Storage 관리 폴더의 경로입니다.
매니페스트를 적용합니다.
kubectl apply -f example-pod-snapshot-storage-config.yaml
스냅샷 정책 만들기
포드의 스냅샷을 사용 설정하려면 포드의 라벨과 일치하는 선택기가 있는 PodSnapshotPolicy 리소스를 만듭니다.
다음 예시에서는
app: my-app라벨이 있는 포드에 적용되고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
스냅샷 크기 최적화
포드 스냅샷이 트리거되면 gVisor는 다음을 비롯한 모든 컨테이너의 전체 상태를 캡처합니다.
- 메모리, 레지스터와 같은 애플리케이션 상태
- 루트 파일 시스템 및
tmpfs(emptyDir볼륨 포함) 변경사항 - 열린 파일 설명자, 스레드, 소켓과 같은 커널 상태
스냅샷의 크기는 이러한 요인에 따라 결정됩니다. 스냅샷이 클수록 저장하고 복원하는 데 시간이 오래 걸립니다. 성능을 최적화하려면 스냅샷을 트리거하기 전에 스냅샷에서 포드가 복원된 후 필요하지 않은 애플리케이션 상태나 파일을 정리해야 합니다.
스냅샷 크기 최적화는 특히 대규모 언어 모델 (LLM)과 같은 워크로드에 중요합니다. LLM 서버는 GPU에 로드하기 전에 모델 가중치를 로컬 스토리지 (rootfs 또는 tmpfs)에 다운로드하는 경우가 많습니다. 스냅샷을 찍으면 GPU 상태와 모델 가중치 파일이 모두 저장됩니다. 이 시나리오에서 모델이 100GB인 경우 결과 스냅샷은 약 200GB (100GB의 모델 파일과 GPU 상태를 나타내는 100GB)입니다. 모델 가중치가 GPU에 로드된 후에는 애플리케이션을 실행하는 데 파일 시스템의 파일이 필요하지 않은 경우가 많습니다. 스냅샷을 트리거하기 전에 이러한 모델 파일을 삭제하면 스냅샷 크기를 절반으로 줄이고 지연 시간이 훨씬 짧은 애플리케이션을 복원할 수 있습니다.
스냅샷 트리거
애플리케이션이 준비되면 워크로드 내에서 스냅샷을 트리거하거나 특정 포드에 대해 요청 시 스냅샷을 수동으로 트리거할 수 있습니다.
워크로드에서 스냅샷 트리거
애플리케이션 코드 내에서 스냅샷을 트리거하려면 스냅샷을 준비할 때 신호를 전송하도록 애플리케이션을 구성합니다. 준비되었음을 알리려면 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
수동으로 스냅샷 트리거
특정 포드의 주문형 스냅샷을 수동으로 트리거하려면 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을 포드 이름(예: my-app 또는 my-pod)으로 바꿉니다.
다음과 유사한 결과가 출력됩니다.
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
스냅샷 관리
포드 스냅샷을 만들면 해당 시점의 포드 상태를 저장하는 PodSnapshot CRD 리소스가 생성됩니다. 이 리소스의 status 필드는 스냅샷 작업이 성공했는지, 스냅샷을 복원할 수 있는지 나타냅니다.
네임스페이스의 모든 PodSnapshot 리소스를 보려면 다음 명령어를 실행합니다.
kubectl get podsnapshots.gke.io --namespace NAMESPACE
다음과 유사한 결과가 출력됩니다.
NAME STATUS POLICY AGE
de334898-1e7a-4cdb-9f2e-7cc2181c29e4 AllSnapshotsAvailable example-policy 47h
스냅샷에서 워크로드 복원
최신 스냅샷에서 워크로드를 복원하려면 스냅샷을 생성한 후 기존 포드를 삭제한 다음 포드를 다시 배포하면 됩니다. 또는 동일한 사양으로 새 포드를 배포할 수 있습니다. GKE는 일치하는 스냅샷에서 포드를 자동으로 복원합니다.
다음 단계에서는 포드를 삭제하고 다시 배포하여 일치하는 스냅샷에서 포드를 복원하는 방법을 보여줍니다.
포드를 삭제합니다.
kubectl delete -f POD_NAME.yamlPOD_NAME을 포드 이름(예:my-app)으로 바꿉니다.포드를 다시 적용합니다.
kubectl apply -f POD_NAME.yaml로그를 확인하여 스냅샷 복원을 확인합니다.
kubectl logs my-app --namespace NAMESPACE출력은 애플리케이션을 구성한 방식에 따라 다릅니다. 예시 애플리케이션에서 복원 작업이 발생하면 로그에
GKE Pod Snapshot: restore가 표시됩니다.
특정 스냅샷에서 복원
기본적으로 GKE는 포드와 일치하는 가장 최근의 PodSnapshot 리소스에서 워크로드를 복원합니다. 스냅샷이 생성되면 GKE에서 PodSnapshot 리소스의 고유 이름 (UUID)을 자동 생성하며, kubectl get podsnapshots.gke.io --namespace NAMESPACE을 실행하여 이를 확인할 수 있습니다.
이전 또는 특정 PodSnapshot 리소스에서 워크로드를 복원하려면 워크로드 포드 사양에 podsnapshot.gke.io/ps-name 주석을 추가하여 워크로드 복원에 사용할 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이어야 하며 포드와 동일한 네임스페이스에 있어야 합니다. PodSnapshot이 Ready이 아니거나 포드와 동일한 네임스페이스에 없는 경우 워크로드는 스냅샷에서 복원하는 대신 콜드 스타트를 실행합니다.
스냅샷 사용 중지
PodSnapshotPolicy CRD를 삭제하면 포드의 스냅샷을 생성하고 복원할 수 없습니다. 실행 중인 포드는 리소스 삭제의 영향을 받지 않습니다. 하지만 포드가 저장되거나 복원되는 동안 정책을 삭제하면 포드가 실패 상태가 될 수 있습니다.
정책에 따라 관리되는 새 포드의 스냅샷 및 복원을 사용 중지하려면 다음 명령어를 실행하여 PodSnapshotPolicy를 삭제합니다.
kubectl delete podsnapshotpolicies.podsnapshot.gke.io SNAPSHOT_POLICY --namespace=NAMESPACE
SNAPSHOT_POLICY을 삭제할 PodSnapshotPolicy의 이름으로 바꿉니다(예: example-pod-snapshot-policy).
포드가 더 이상 특정 스냅샷에서 복원되지 않도록 특정 PodSnapshot 리소스를 삭제할 수도 있습니다. PodSnapshot 리소스를 삭제하면 Cloud Storage에 저장된 파일도 삭제됩니다.
특정 스냅샷이 향후 복원에 사용되지 않도록 하려면 다음 명령어를 실행하여 PodSnapshot 객체를 삭제합니다.
kubectl delete podsnapshots.podsnapshot.gke.io POD_SNAPSHOT_NAME --namespace=NAMESPACE
POD_SNAPSHOT_NAME을 삭제할 스냅샷의 이름으로 바꿉니다(예: example-podsnapshot).
다음 단계
- 포드 스냅샷 개념을 자세히 알아보세요.
- Pod 스냅샷 커스텀 리소스 정의 (CRD)를 참고하세요.