Google Kubernetes Engine (GKE)에서 스냅샷 정책을 만들고 실행 중인 워크로드의 포드 스냅샷을 트리거하는 방법을 알아봅니다.
시작하기 전에
시작하기 전에 다음 태스크를 수행했는지 확인합니다.
- Google Kubernetes Engine API를 사용 설정합니다. Google Kubernetes Engine API 사용 설정
- 이 태스크에 Google Cloud CLI를 사용하려면
설치한 후
초기화합니다.
gcloud CLI를 이전에 gcloud CLI를 설치했으면 최신
버전을
gcloud components update명령어를 실행하여 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
- 기본 요건을 완료하고 클러스터에서 포드 스냅샷을 사용 설정했는지 확인합니다. 자세한 내용은 포드 스냅샷 준비를 참조하세요.
스냅샷 정책 만들기
포드의 스냅샷을 사용 설정하려면 포드의 라벨과 일치하는 선택기가 있는 PodSnapshotPolicy 리소스를 만듭니다.
다음 예에서는
app: my-app라벨이 있는 포드에 적용되고example-pod-snapshot-storage-config스토리지 구성을 사용하는 정책을 만듭니다. 다음 매니페스트를example-pod-snapshot-policy.yaml로 저장합니다.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다음을 바꿉니다.
TRIGGER_TYPE: 트리거 유형입니다. 지원되는 값은 워크로드 기반 트리거의 경우workload이고 주문형 스냅샷의 경우manual입니다.NAMESPACE: 포드의 네임스페이스입니다.
구성할 수 있는 모든 필드의 전체 목록은 PodSnapshotPolicy CustomResourceDefinition (CRD) 문서를 참조하세요.
매니페스트를 적용합니다.
kubectl apply -f example-pod-snapshot-policy.yaml
추가 포드 스냅샷 정책 구성
PodSnapshotPolicy에서 다음과 같은 추가 정책을 구성할 수 있습니다.
스냅샷 범위: 스냅샷에서 캡처할 포드 상태의 일부를 지정하려면
spec.snapshotScope필드를 구성합니다. 지원되는 값은 애플리케이션 상태, 메모리, 파일 시스템을 포함한 전체 포드를 체크포인트하는whole-pod(기본값) 또는 컨테이너 루트 파일 시스템만 체크포인트하는rootfs-only입니다.rootfs-only범위에는 GKE 버전 1.35.3-gke.1031000 이상이 필요합니다.자동 정리: 오래된 포드 스냅샷 리소스를 자동으로 정리하려면
spec.retentionConfig필드를 사용하여 보관 정책을 구성합니다.lastAccessTimeout필드 (예:7d)를 사용하여 기간을 지정할 수 있습니다. 이 기간이 지나면 스냅샷이 삭제됩니다.스냅샷 구성: 스냅샷을 논리적으로 그룹화하여 유사한 환경에서 생성되었지만 컨텍스트가 다른 스냅샷을 구분할 수 있습니다. 예를 들어 기본 포드가 모든 사용자에게 동일한 멀티 테넌트 시나리오에서 사용자 또는 그룹별로 스냅샷을 격리할 수 있습니다. 스냅샷을 격리하려면
snapshotGroupingRules필드를 사용하여 정책에서 그룹화 라벨을 지정합니다. 포드가 복원되면 동일한 라벨 그룹 내의 스냅샷만 일치합니다. 이 그룹화가 복원 중에 호환성 일치에 미치는 영향에 대한 자세한 내용은 그룹화 규칙 일치를 참조하세요.
다음 예에서는 PodSnapshotPolicy에서 보관 및 그룹화 설정을 모두 구성하는 방법을 보여줍니다. 이러한 설정은 독립적으로 설정할 수 있습니다.
# ... other fields omitted
spec:
snapshotScope: rootfs-only
retentionConfig:
lastAccessTimeout: 7d
snapshotGroupingRules:
groupByLabelValue:
labels: ["tenant", "environment"]
groupRetentionPolicy:
maxSnapshotCountPerGroup: 5
구성할 수 있는 모든 필드의 전체 목록은 PodSnapshotPolicy 참고 문서를 참조하세요.
스냅샷 크기 최적화
포드 스냅샷이 트리거되면 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 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"다음을 바꿉니다.
NAMESPACE: 포드의 네임스페이스입니다.KSA_NAME: KSA의 이름입니다.
애플리케이션을 배포합니다.
kubectl apply -f my-app.yaml
수동으로 스냅샷 트리거
특정 포드에 대해 주문형 스냅샷을 수동으로 트리거하려면 PodSnapshotManualTrigger 리소스를 만듭니다.
다음 예에서는
my-pod라는 포드의 스냅샷을 트리거합니다. 다음 매니페스트를example-manual-trigger.yaml로 저장합니다.apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-podNAMESPACE를 포드의 네임스페이스로 바꿉니다.매니페스트를 적용합니다.
kubectl apply -f example-manual-trigger.yaml
스냅샷이 성공적으로 트리거되었는지 확인하려면 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).NAMESPACE: 포드의 네임스페이스입니다.
다음과 유사한 결과가 출력됩니다.
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
다음 단계
포드 스냅샷에서 워크로드를 복원하는 방법을 알아봅니다.