Os snapshots de pods do Google Kubernetes Engine (GKE) ajudam a melhorar a latência de inicialização da carga de trabalho restaurando snapshots de pods em execução. Um snapshot de pod salva todo o estado do pod, incluindo memória e mudanças no sistema de arquivos raiz. Quando novas réplicas são criadas, em vez de inicializar o pod de um estado novo, o snapshot é restaurado. Em seguida, o pod retoma a execução do ponto em que o snapshot foi tirado.
Neste documento, explicamos como ativar e configurar snapshots de pods do GKE para suas cargas de trabalho.
Para mais informações sobre como os snapshots de pod funcionam, consulte Sobre snapshots de pod.
Antes de começar
Antes de começar, verifique se você realizou as tarefas a seguir:
- Ativar a API Google Kubernetes Engine. Ativar a API Google Kubernetes Engine
- Se você quiser usar a CLI do Google Cloud para essa tarefa,
instale e inicialize a
gcloud CLI. Se você instalou a gcloud CLI anteriormente, instale a versão
mais recente executando o comando
gcloud components update. Talvez as versões anteriores da gcloud CLI não sejam compatíveis com a execução dos comandos neste documento.
Ativar snapshots de pods
Para ativar snapshots de pods, primeiro crie ou atualize um cluster com o recurso de snapshot de pod ativado. Em seguida, crie ou atualize um pool de nós para executar no GKE Sandbox.
Para ativar o recurso em um cluster, siga uma destas etapas:
Para ativar os snapshots de pod em um novo cluster, execute o seguinte comando:
gcloud beta container clusters create CLUSTER_NAME \ --enable-pod-snapshots \ --cluster-version=CLUSTER_VERSION \ --workload-pool=PROJECT_ID.svc.id.goog \ --workload-metadata=GKE_METADATASubstitua:
CLUSTER_NAME: o nome do cluster.CLUSTER_VERSION: a versão do novo cluster, que precisa ser 1.34.1-gke.3084001 ou mais recente.PROJECT_ID: o ID do projeto.
Para ativar os snapshots de pod em um cluster, siga estas etapas:
Atualize o cluster para a versão 1.34.1-gke.3084001 ou mais recente:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=NODEPOOL_NAME \ --cluster-version=CLUSTER_VERSIONSubstitua:
CLUSTER_NAME: o nome do cluster.NODEPOOL_VERSION: o nome do pool de nós.CLUSTER_VERSION: a versão para atualizar o novo cluster, que precisa ser 1.34.1-gke.3084001 ou posterior.
Ative snapshots de pods no cluster:
gcloud container clusters update CLUSTER_NAME \ --workload-pool=PROJECT_ID .svc.id.goog" \ --enable-pod-snapshotsSubstitua
PROJECT_IDpela ID do seu projeto.
Ative o GKE Sandbox no seu cluster Standard:
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=gvisorSubstitua as seguintes variáveis:
NODE_POOL_NAME: o nome do novo pool de nós.NODE_VERSION: a versão a ser usada no pool de nós.MACHINE_TYPE: o tipo de máquina a ser usado para os nós.
Para mais informações sobre como usar o gVisor, consulte Isolar as cargas de trabalho usando o GKE Sandbox.
Armazenar snapshots
Os snapshots de pods são armazenados em um bucket do Cloud Storage, que contém a memória e (opcionalmente) o estado da GPU. Os snapshots de pod exigem a Federação de Identidade da Carga de Trabalho para GKE para ativar e usar a conta de serviço do pod e fazer a autenticação no Cloud Storage.
Os snapshots de pod exigem a seguinte configuração para o bucket:
- Namespaces hierárquicos: precisam estar ativados para permitir consultas de leitura e gravação por segundo mais altas. Os namespaces hierárquicos também exigem que o acesso uniforme no nível do bucket esteja ativado.
- Exclusão reversível: como os snapshots de pod usam uploads compostos paralelos, é recomendável desativar recursos de proteção de dados, como a exclusão reversível. Se essa opção permanecer ativada, as exclusões de objetos temporários poderão aumentar significativamente sua fatura de armazenamento.
- Local: o local do bucket do Cloud Storage precisa ser o mesmo do cluster do GKE, porque o desempenho pode ser afetado se os snapshots forem transferidos entre regiões diferentes.
criar o bucket do Cloud Storage
Para criar o bucket e as permissões necessárias, siga estas etapas:
Criar um bucket do Cloud Storage. O comando a seguir cria um bucket com a configuração necessária:
gcloud storage buckets create "gs://BUCKET_NAME" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="LOCATION"Substitua:
BUCKET_NAME: o nome do bucket.LOCATION: o local do bucket.
Para uma lista completa de opções de criação de buckets, consulte opções de
buckets create.
Conceder permissão às cargas de trabalho para acessar o bucket do Cloud Storage
Por padrão, o GKE não tem permissões para acessar o Cloud Storage. Para ler e gravar arquivos de snapshot, conceda permissões do IAM à conta de serviço do Kubernetes (KSA) usada pelos pods de carga de trabalho.
Receba as credenciais para se comunicar com o cluster usando comandos
kubectl:gcloud container clusters get-credentials "CLUSTER_NAME"Para cada pod, siga estas etapas:
Crie uma KSA para cada pod:
kubectl create serviceaccount "KSA_NAME" \ --namespace "NAMESPACE"Substitua:
KSA_NAME: o nome da KSA.NAMESPACE: o namespace dos pods.
Conceda à KSA permissão para acessar o bucket:
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"Substitua:
PROJECT_NUMBER: o número do projeto.PROJECT_ID: o ID do projeto.
(Opcional) Criar pastas gerenciadas para o bucket do Cloud Storage
A criação de pastas permite isolar permissões para snapshots de pods mutuamente não confiáveis, o que é útil em casos de uso multitenant. Para configurar pastas gerenciadas, siga estas etapas:
Crie um papel personalizado do IAM que contenha apenas as permissões necessárias para snapshots de pod:
gcloud iam roles create podSnapshotGcsReadWriter \ --project="PROJECT_ID" \ --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"Conceda o papel
roles/storage.bucketViewera todos os KSAs no namespace de destino. Com essa função, o KSA pode ler metadados do bucket, mas não tem permissões de leitura ou gravação para objetos no 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"Substitua:
PROJECT_NUMBER: o número do projeto.PROJECT_ID: o ID do projeto.
Para cada KSA que precisa armazenar snapshots de pod, siga estas etapas:
Crie uma pasta gerenciada para a KSA:
gcloud storage managed-folders create "gs://BUCKET_NAME/FOLDER_PATH/"Substitua
FOLDER_PATHpelo caminho da pasta gerenciada, por exemplo,my-app-snapshots.Conceda ao KSA a função personalizada
podSnapshotGcsReadWriterna pasta gerenciada: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"Substitua
KSA_NAMEpelo nome da KSA.
Configurar o armazenamento para snapshots
Para especificar onde armazenar os arquivos de snapshot, crie um recurso PodSnapshotStorageConfig.
O exemplo a seguir configura o GKE para armazenar snapshots de pods no caminho
FOLDER_PATH/dentro do bucket do Cloud Storage BUCKET_NAME. Salve o seguinte manifesto comoexample-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"Substitua:
NAMESPACE: o namespace dos pods. Por padrão, ele édefault.BUCKET_NAME: o nome do bucket do Cloud Storage.FOLDER_PATH: o caminho para a pasta gerenciada do Cloud Storage.
Aplique o manifesto:
kubectl apply -f example-pod-snapshot-storage-config.yaml
Criar uma política de snapshot
Para ativar snapshots em um pod, crie um recurso PodSnapshotPolicy com um
seletor que corresponda aos rótulos do pod.
O exemplo a seguir cria uma política que se aplica a pods com o rótulo
app: my-appe usa a configuração de armazenamentoexample-pod-snapshot-storage-config. Salve o manifesto a seguir comoexample-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: resumeAplique o manifesto:
kubectl apply -f example-pod-snapshot-policy.yaml --namespace NAMESPACE
Otimizar o tamanho do snapshot
Quando um snapshot de pod é acionado, o gVisor captura todo o estado de todos os contêineres, incluindo:
- Estado do aplicativo, como memória e registros
- Mudanças no sistema de arquivos raiz e no
tmpfs(incluindo volumesemptyDir) - Estado do kernel, como descritores de arquivos abertos, linhas de execução e sockets
O tamanho do snapshot é determinado por estes fatores. Snapshots maiores levam mais tempo para serem salvos e restaurados. Para otimizar o desempenho, antes de acionar um snapshot, limpe qualquer estado ou arquivo do aplicativo que não seja necessário depois que o pod for restaurado do snapshot.
A otimização do tamanho do snapshot é particularmente importante para cargas de trabalho como modelos de linguagem grandes (LLMs). Os servidores de LLM geralmente fazem o download dos pesos do modelo para o armazenamento local (rootfs ou tmpfs) antes de carregá-los na GPU. Quando um snapshot
é criado, o estado da GPU e os arquivos de peso do modelo são salvos. Nesse cenário, se o modelo for de 100 GB, o snapshot resultante será de aproximadamente 200 GB (100 GB de arquivos de modelo mais 100 GB representando o estado da GPU). Depois que os pesos do modelo são carregados na GPU, os arquivos no sistema de arquivos geralmente não são necessários para a execução do aplicativo. Ao excluir esses arquivos de modelo antes de
acionar o snapshot, é possível reduzir o tamanho dele pela metade e restaurar o
aplicativo com uma latência significativamente menor.
Acionar um snapshot
É possível acionar um snapshot de dentro de uma carga de trabalho quando o aplicativo estiver pronto ou acionar manualmente um snapshot sob demanda para um pod específico.
Acionar um snapshot de uma carga de trabalho
Para acionar um snapshot no código do aplicativo, configure o aplicativo para enviar um sinal quando ele estiver pronto para um snapshot. Para sinalizar
prontidão, grave 1 no arquivo /proc/gvisor/checkpoint, por exemplo,
echo 1 > /proc/gvisor/checkpoint. A operação de gravação inicia o processo de snapshot
de forma assíncrona e retorna imediatamente. A leitura do mesmo descritor de arquivo
bloqueia o processo de leitura até que o snapshot e a restauração sejam concluídos
e a carga de trabalho esteja pronta para ser retomada.
O uso exato varia de acordo com o aplicativo, mas o exemplo a seguir mostra um gatilho de snapshot para um aplicativo Python. Para acionar um Snapshot deste exemplo de carga de trabalho, conclua as etapas a seguir:
Salve o seguinte manifesto como
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"Implante o aplicativo:
kubectl apply -f my-app.yaml
Acionar um snapshot manualmente
Para acionar manualmente um snapshot sob demanda de um pod específico, crie um
recurso PodSnapshotManualTrigger. O acionamento manual de um snapshot está disponível
nas versões 1.34.1-gke.3556000 e mais recentes do GKE.
O exemplo a seguir aciona um snapshot para um pod chamado
my-pod. Salve o seguinte manifesto comoexample-manual-trigger.yaml:apiVersion: podsnapshot.gke.io/v1alpha1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-podAplique o manifesto:
kubectl apply -f example-manual-trigger.yaml --namespace NAMESPACE
Para confirmar se o snapshot foi acionado, verifique o campo status do recurso PodSnapshotManualTrigger:
kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io example-manual-trigger -n NAMESPACE -o yaml
O campo status indica se o acionamento do snapshot foi concluído ou falhou.
Verificar snapshots
Para confirmar se um snapshot foi criado, verifique o histórico de eventos
de eventos 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
Substitua POD_NAME pelo nome do pod, por exemplo, my-app ou my-pod.
A saída será assim:
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
Gerenciar snapshots
Quando você cria um instantâneo de pod, um recurso CRD PodSnapshot é criado para armazenar o estado do pod naquele momento. O campo status desse recurso indica
se a operação de snapshot foi bem-sucedida e se o snapshot está disponível para restaurações.
Para conferir todos os recursos PodSnapshot em um namespace, execute o seguinte comando:
kubectl get podsnapshots.gke.io --namespace NAMESPACE
A saída será assim:
NAME STATUS POLICY AGE
de334898-1e7a-4cdb-9f2e-7cc2181c29e4 AllSnapshotsAvailable example-policy 47h
Restaurar uma carga de trabalho de um snapshot
Para restaurar sua carga de trabalho do snapshot mais recente, exclua o pod atual depois que um snapshot for criado e, em seguida, implante o pod novamente. Como alternativa, implante um novo pod com uma especificação idêntica. O GKE restaura automaticamente o pod do snapshot correspondente.
As etapas a seguir mostram como um pod é restaurado de um snapshot correspondente excluindo e reimplantando o pod:
Exclua o pod:
kubectl delete -f POD_NAME.yamlSubstitua
POD_NAMEpelo nome do pod, por exemplo,my-app.Aplique o pod novamente:
kubectl apply -f POD_NAME.yamlConfira os registros para confirmar a restauração do snapshot:
kubectl logs my-app --namespace NAMESPACEA saída depende de como você configurou o aplicativo. No aplicativo de exemplo, os registros mostram
GKE Pod Snapshot: restorequando uma operação de restauração ocorre.
Restaurar de um snapshot específico
Por padrão, o GKE restaura cargas de trabalho do recurso PodSnapshot
mais recente que corresponde ao pod. Quando um snapshot é criado, o GKE
gera automaticamente um nome exclusivo (UUID) para o recurso PodSnapshot, que você
pode conferir executando kubectl get podsnapshots.gke.io --namespace NAMESPACE.
Para restaurar uma carga de trabalho de um recurso PodSnapshot mais antigo ou específico, adicione a anotação podsnapshot.gke.io/ps-name à especificação do pod da carga de trabalho, especificando o nome do recurso PodSnapshot a ser usado para restaurar a carga de trabalho:
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:
...
Substitua POD_SNAPSHOT_NAME pelo nome do snapshot
que você quer restaurar. Para saber os nomes dos snapshots, execute o comando
kubectl get podsnapshots.gke.io --namespace NAMESPACE.
Para que o GKE use o snapshot especificado para restauração, a condição de status do recurso PodSnapshot precisa ser Ready e estar no mesmo namespace do pod. Se o PodSnapshot não for Ready ou não existir no
mesmo namespace do pod, a carga de trabalho vai realizar uma inicialização a frio em vez de
restaurar de um snapshot.
Desativar snapshots
Remover o CRD PodSnapshotPolicy impede que os pods sejam capturados e restaurados. Os pods em execução não são afetados pela exclusão de recursos. No entanto, se você excluir a política enquanto um pod estiver sendo salvo ou restaurado, ele poderá entrar em um estado de falha.
Para desativar a criação de snapshots e a restauração de novos pods regidos por uma política,
exclua o PodSnapshotPolicy executando o seguinte comando:
kubectl delete podsnapshotpolicies.podsnapshot.gke.io SNAPSHOT_POLICY --namespace=NAMESPACE
Substitua SNAPSHOT_POLICY pelo nome do
PodSnapshotPolicy que você quer excluir, por exemplo
example-pod-snapshot-policy.
Também é possível excluir um recurso PodSnapshot específico para que os pods não sejam mais
restaurados desse snapshot específico. A exclusão do recurso PodSnapshot também remove os arquivos armazenados no Cloud Storage.
Para impedir que um snapshot específico seja usado em restaurações futuras,
exclua o objeto PodSnapshot executando o seguinte comando:
kubectl delete podsnapshots.podsnapshot.gke.io POD_SNAPSHOT_NAME --namespace=NAMESPACE
Substitua POD_SNAPSHOT_NAME pelo nome do
snapshot que você quer excluir, por exemplo, example-podsnapshot.
A seguir
- Saiba mais sobre os conceitos de snapshot de pod.
- Consulte as definições de recursos personalizados (CRDs) de snapshots de pods.