Las copias de seguridad de pods de Google Kubernetes Engine (GKE) ayudan a mejorar la latencia de inicio de las cargas de trabajo restaurando copias de seguridad de los pods en ejecución. Una captura de un pod guarda todo el estado del pod, incluida la memoria y los cambios en el sistema de archivos raíz. Cuando se crean réplicas nuevas, en lugar de inicializar el pod desde un estado nuevo, se restaura la captura. A continuación, el pod reanuda la ejecución desde el punto en el que se tomó la captura.
En este documento se explica cómo habilitar y configurar las instantáneas de pods de GKE para sus cargas de trabajo.
Para obtener más información sobre cómo funcionan las capturas de pods, consulta el artículo Acerca de las capturas de pods.
Antes de empezar
Antes de empezar, asegúrate de que has realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la CLI de gcloud, obtén la versión más reciente ejecutando el comando
gcloud components update. Es posible que las versiones anteriores de la interfaz de línea de comandos de gcloud no admitan la ejecución de los comandos de este documento.
Habilitar las copias de seguridad de pods
Para habilitar las capturas de pods, primero crea o actualiza un clúster con la función de captura de pods habilitada. A continuación, crea o actualiza un grupo de nodos para que se ejecute en GKE Sandbox.
Para habilitar la función en un clúster, sigue uno de estos pasos:
Para habilitar las instantáneas de pods en un clúster nuevo, ejecuta el siguiente 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_METADATAHaz los cambios siguientes:
CLUSTER_NAME: el nombre de tu clúster.CLUSTER_VERSION: la versión de tu nuevo clúster, que debe ser 1.34.1-gke.3084001 o posterior.PROJECT_ID: tu ID de proyecto.
Para habilitar las instantáneas de pods en un clúster, sigue estos pasos:
Actualiza el clúster a la versión 1.34.1-gke.3084001 o una posterior:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=NODEPOOL_NAME \ --cluster-version=CLUSTER_VERSIONHaz los cambios siguientes:
CLUSTER_NAME: el nombre de tu clúster.NODEPOOL_VERSION: el nombre de tu grupo de nodos.CLUSTER_VERSION: la versión a la que se debe actualizar el nuevo clúster, que debe ser 1.34.1-gke.3084001 o una posterior.
Habilita las capturas de pods en el clúster:
gcloud container clusters update CLUSTER_NAME \ --workload-pool=PROJECT_ID .svc.id.goog" \ --enable-pod-snapshotsSustituye
PROJECT_IDpor el ID del proyecto.
Habilita GKE Sandbox en tu clúster estándar:
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=gvisorSustituye las siguientes variables:
NODE_POOL_NAME: el nombre del nuevo grupo de nodos.NODE_VERSION: la versión que se va a usar en el grupo de nodos.MACHINE_TYPE: el tipo de máquina que se va a usar en los nodos.
Para obtener más información sobre el uso de gVisor, consulta Aísla tus cargas de trabajo con GKE Sandbox.
Almacenar capturas
Las copias de los pods se almacenan en un segmento de Cloud Storage, que contiene la memoria y (opcionalmente) el estado de la GPU. Las copias de seguridad de pods requieren Workload Identity Federation for GKE para habilitar y usar la cuenta de servicio del pod con el fin de autenticarse en Cloud Storage.
Las instantáneas de pods requieren la siguiente configuración para el bucket:
- Espacios de nombres jerárquicos: deben habilitarse para permitir un mayor número de consultas de lectura y escritura por segundo. Los espacios de nombres jerárquicos también requieren que se habilite el acceso uniforme a nivel de segmento.
- Eliminación no definitiva: como las copias de seguridad de pods usan subidas compuestas paralelas, debes inhabilitar las funciones de protección de datos, como la eliminación no definitiva. Si se deja habilitada, la eliminación de los objetos temporales puede aumentar significativamente la factura de almacenamiento.
- Ubicación: la ubicación del segmento de Cloud Storage debe ser la misma que la del clúster de GKE, ya que el rendimiento puede verse afectado si las copias de seguridad se transfieren entre regiones diferentes.
Crear un segmento de Cloud Storage
Para crear el segmento y los permisos necesarios, siga estos pasos:
Crea un segmento de Cloud Storage. El siguiente comando crea un bucket con la configuración necesaria:
gcloud storage buckets create "gs://BUCKET_NAME" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="LOCATION"Haz los cambios siguientes:
BUCKET_NAME: el nombre de tu segmento.LOCATION: la ubicación de tu segmento.
Para ver una lista completa de las opciones de creación de segmentos, consulta las opciones de
buckets create.
Concede permiso a las cargas de trabajo para acceder al segmento de Cloud Storage
De forma predeterminada, GKE no tiene permisos para acceder a Cloud Storage. Para leer y escribir archivos de instantáneas, debes conceder permisos de gestión de identidades y accesos a la cuenta de servicio de Kubernetes (KSA) que usan los pods de tu carga de trabajo.
Obtén las credenciales para comunicarte con tu clúster mediante comandos de
kubectl:gcloud container clusters get-credentials "CLUSTER_NAME"Sigue estos pasos con cada pod:
Crea un KSA para cada Pod:
kubectl create serviceaccount "KSA_NAME" \ --namespace "NAMESPACE"Haz los cambios siguientes:
KSA_NAME: el nombre de tu KSA.NAMESPACE: el espacio de nombres de tus pods.
Concede al KSA permiso para acceder al segmento:
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"Haz los cambios siguientes:
PROJECT_NUMBER: tu número de proyecto.PROJECT_ID: tu ID de proyecto.
(Opcional) Crear carpetas gestionadas para el segmento de Cloud Storage
Crear carpetas te permite aislar los permisos de las instantáneas de los pods que no son de confianza entre sí, lo que resulta útil en casos prácticos de varios arrendatarios. Para configurar carpetas gestionadas, sigue estos pasos:
Crea un rol de gestión de identidades y accesos personalizado que solo contenga los permisos necesarios para las capturas de Pod:
gcloud iam roles create podSnapshotGcsReadWriter \ --project="PROJECT_ID" \ --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"Concede el rol
roles/storage.bucketViewera todos los KSA del espacio de nombres de destino. Este rol permite a las KSAs leer metadatos de segmentos, pero no les concede permisos de lectura o escritura para los objetos del segmento.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"Haz los cambios siguientes:
PROJECT_NUMBER: tu número de proyecto.PROJECT_ID: tu ID de proyecto.
Para cada KSA que necesite almacenar snapshots de pods, sigue estos pasos:
Crea una carpeta gestionada para la KSA:
gcloud storage managed-folders create "gs://BUCKET_NAME/FOLDER_PATH/"Sustituye
FOLDER_PATHpor la ruta de la carpeta gestionada (por ejemplo,my-app-snapshots).Asigna a la cuenta de servicio con autorización el rol personalizado
podSnapshotGcsReadWriteren la carpeta gestionada: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"Sustituye
KSA_NAMEpor el nombre de la KSA.
Configurar el almacenamiento de las instantáneas
Para especificar dónde se almacenarán los archivos de la captura, crea un PodSnapshotStorageConfig
recurso.
En el siguiente ejemplo se configura GKE para almacenar las copias de seguridad de los pods en la ruta
FOLDER_PATH/del segmento de Cloud Storage BUCKET_NAME. Guarda el siguiente archivo de manifiesto 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"Haz los cambios siguientes:
NAMESPACE: el espacio de nombres de tus pods. El valor predeterminado esdefault.BUCKET_NAME: el nombre de tu segmento de Cloud Storage.FOLDER_PATH: la ruta de la carpeta gestionada de Cloud Storage.
Aplica el archivo de manifiesto:
kubectl apply -f example-pod-snapshot-storage-config.yaml
Crear una política de capturas
Para habilitar las copias de seguridad de un pod, crea un recurso PodSnapshotPolicy con un selector que coincida con las etiquetas del pod.
En el siguiente ejemplo se crea una política que se aplica a los pods con la etiqueta
app: my-appy usa la configuración de almacenamientoexample-pod-snapshot-storage-config. Guarda el siguiente manifiesto 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: resumeAplica el archivo de manifiesto:
kubectl apply -f example-pod-snapshot-policy.yaml --namespace NAMESPACE
Optimizar el tamaño de las capturas
Cuando se activa una captura de un pod, gVisor registra todo el estado de todos los contenedores, incluidos los siguientes:
- Estado de la aplicación, como la memoria y los registros
- Cambios en el sistema de archivos raíz y en
tmpfs(incluidos los volúmenes deemptyDir) - Estado del kernel, como descriptores de archivos abiertos, hilos y sockets
El tamaño de la instantánea se determina en función de estos factores. Las instantáneas más grandes tardan más en guardarse y restaurarse. Para optimizar el rendimiento, antes de activar una instantánea, debes limpiar cualquier estado o archivo de la aplicación que no sea necesario después de que se restaure el pod a partir de la instantánea.
Optimizar el tamaño de las copias de seguridad es especialmente importante para cargas de trabajo como los modelos de lenguaje extensos (LLMs). Los servidores de LLM suelen descargar los pesos del modelo en el almacenamiento local (rootfs o tmpfs) antes de cargarlos en la GPU. Cuando se hace una captura, se guardan tanto el estado de la GPU como los archivos de pesos del modelo. En este caso, si el modelo es de 100 GB, la instantánea resultante será de unos 200 GB (100 GB de archivos del modelo más 100 GB que representan el estado de la GPU). Una vez que los pesos del modelo se han cargado en la GPU, los archivos del sistema de archivos no suelen ser necesarios para que se ejecute la aplicación. Si eliminas estos archivos de modelo antes de activar la instantánea, puedes reducir su tamaño a la mitad y restaurar la aplicación con una latencia significativamente menor.
Activar una captura
Puedes activar una instantánea desde una carga de trabajo cuando la aplicación esté lista o puedes activar manualmente una instantánea bajo demanda de un Pod específico.
Activar una captura de una carga de trabajo
Para activar una captura desde el código de tu aplicación, configúrala para que envíe una señal cuando esté lista para hacer una captura. Para indicar que está listo, escribe 1 en el archivo /proc/gvisor/checkpoint. Por ejemplo, echo 1 > /proc/gvisor/checkpoint.. La operación de escritura inicia el proceso de creación de la captura de forma asíncrona y devuelve el resultado de inmediato. La lectura del mismo descriptor de archivo bloqueará el proceso de lectura hasta que se completen tanto la instantánea como la restauración y la carga de trabajo esté lista para reanudarse.
El uso exacto variará en función de tu aplicación, pero en el siguiente ejemplo se muestra un activador de instantáneas para una aplicación de Python. Para activar una instantánea de esta carga de trabajo de ejemplo, sigue estos pasos:
Guarda el siguiente archivo de manifiesto 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"Despliega la aplicación:
kubectl apply -f my-app.yaml
Activar una instantánea manualmente
Para activar manualmente una captura de disco a petición de un pod específico, crea un recurso PodSnapshotManualTrigger. La activación manual de una instantánea está disponible en las versiones 1.34.1-gke.3556000 y posteriores de GKE.
En el siguiente ejemplo se activa una instantánea de un Pod llamado
my-pod. Guarda el siguiente manifiesto comoexample-manual-trigger.yaml:apiVersion: podsnapshot.gke.io/v1alpha1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-podAplica el archivo de manifiesto:
kubectl apply -f example-manual-trigger.yaml --namespace NAMESPACE
Para confirmar si la creación de la captura se ha activado correctamente, comprueba el campo status
del recurso PodSnapshotManualTrigger:
kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io example-manual-trigger -n NAMESPACE -o yaml
El campo status indica si se ha podido activar la instantánea o no.
Verificar las instantáneas
Para confirmar que se ha hecho una captura, consulta el historial 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
Sustituye POD_NAME por el nombre de tu pod (por ejemplo, my-app o my-pod).
La salida es similar a la siguiente:
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
Gestionar capturas
Cuando creas una instantánea de un pod, se crea un recurso CRD PodSnapshot para almacenar el estado del pod en ese momento. El campo status de este recurso indica si la operación de creación de la captura se ha realizado correctamente y si la captura está disponible para restauraciones.
Para ver todos los recursos de PodSnapshot de un espacio de nombres, ejecuta el siguiente comando:
kubectl get podsnapshots.gke.io --namespace NAMESPACE
La salida es similar a la siguiente:
NAME STATUS POLICY AGE
de334898-1e7a-4cdb-9f2e-7cc2181c29e4 AllSnapshotsAvailable example-policy 47h
Restaurar una carga de trabajo a partir de una captura
Para restaurar tu carga de trabajo a partir de la última captura, puedes eliminar el pod después de hacer una captura y, a continuación, volver a implementarlo. También puedes desplegar un nuevo pod con una especificación idéntica. GKE restaura automáticamente el pod a partir de la captura correspondiente.
En los siguientes pasos se muestra cómo se restaura un pod a partir de una instantánea coincidente eliminando y volviendo a implementar el pod:
Elimina el pod:
kubectl delete -f POD_NAME.yamlSustituye
POD_NAMEpor el nombre de tu pod (por ejemplo,my-app).Vuelve a aplicar el pod:
kubectl apply -f POD_NAME.yamlConsulta los registros para confirmar la restauración de la instantánea:
kubectl logs my-app --namespace NAMESPACEEl resultado depende de cómo hayas configurado tu aplicación. En la aplicación de ejemplo, los registros muestran
GKE Pod Snapshot: restorecuando se produce una operación de restauración.
Restaurar desde una captura específica
De forma predeterminada, GKE restaura las cargas de trabajo a partir del PodSnapshot
recurso más reciente que coincida con el pod. Cuando se crea una instantánea, GKE genera automáticamente un nombre único (UUID) para el recurso PodSnapshot, que puedes ver ejecutando kubectl get podsnapshots.gke.io --namespace NAMESPACE.
Para restaurar una carga de trabajo a partir de un recurso PodSnapshot anterior o específico, añade la anotación podsnapshot.gke.io/ps-name a la especificación del pod de la carga de trabajo. Especifica el nombre del recurso PodSnapshot que se va a usar para restaurar la carga de trabajo:
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:
...
Sustituye POD_SNAPSHOT_NAME por el nombre de la instantánea desde la que quieras restaurar. Para obtener los nombres de las instantáneas, ejecuta el comando
kubectl get podsnapshots.gke.io --namespace NAMESPACE.
Para que GKE use la instantánea especificada en la restauración, el estado del recurso PodSnapshot debe ser Ready y debe estar en el mismo espacio de nombres que el pod. Si PodSnapshot no es Ready o no existe en el mismo espacio de nombres que el pod, la carga de trabajo realizará un arranque en frío en lugar de restaurar desde una instantánea.
Inhabilitar las instantáneas
Si se elimina el PodSnapshotPolicy CRD, no se podrán crear instantáneas de los pods ni restaurarlos. Los pods en ejecución no se ven afectados por la eliminación de recursos. Sin embargo, si eliminas la política mientras se guarda o se restaura un Pod, es posible que este pase a un estado de error.
Para inhabilitar la creación de instantáneas y la restauración de los nuevos pods regidos por una política, elimina el PodSnapshotPolicy ejecutando el siguiente comando:
kubectl delete podsnapshotpolicies.podsnapshot.gke.io SNAPSHOT_POLICY --namespace=NAMESPACE
Sustituye SNAPSHOT_POLICY por el nombre del PodSnapshotPolicy que quieras eliminar (por ejemplo, example-pod-snapshot-policy).
También puedes eliminar un recurso PodSnapshot específico para que los pods ya no se restauren a partir de esa instantánea. Si eliminas el recurso PodSnapshot, también se eliminarán los archivos almacenados en Cloud Storage.
Para evitar que se use una instantánea específica en restauraciones futuras, elimina el objeto PodSnapshot ejecutando el siguiente comando:
kubectl delete podsnapshots.podsnapshot.gke.io POD_SNAPSHOT_NAME --namespace=NAMESPACE
Sustituye POD_SNAPSHOT_NAME por el nombre de la instantánea que quieras eliminar, por ejemplo, example-podsnapshot.
Siguientes pasos
- Consulta más información sobre los conceptos de las capturas de pods.
- Consulta las definiciones de recursos personalizados (CRDs) de la vista general de pods.