Les instantanés de pods Google Kubernetes Engine (GKE) permettent d'améliorer la latence de démarrage des charges de travail en restaurant les instantanés des pods en cours d'exécution. Un instantané de pod enregistre l'état complet du pod, y compris la mémoire et les modifications apportées au système de fichiers racine. Lorsque de nouveaux réplicas sont créés, l'instantané est restauré au lieu d'initialiser le pod à partir d'un état vierge. Le pod reprend ensuite l'exécution à partir du point où l'instantané a été créé.
Ce document explique comment activer et configurer les snapshots de pods GKE pour vos charges de travail.
Pour en savoir plus sur le fonctionnement des instantanés de pod, consultez À propos des instantanés de pod.
Avant de commencer
Avant de commencer, effectuez les tâches suivantes :
- Activez l'API Google Kubernetes Engine. Activer l'API Google Kubernetes Engine
- Si vous souhaitez utiliser Google Cloud CLI pour cette tâche, installez puis initialisez la gcloud CLI. Si vous avez déjà installé la gcloud CLI, obtenez la dernière version en exécutant la commande
gcloud components update. Il est possible que les versions antérieures de la gcloud CLI ne permettent pas d'exécuter les commandes de ce document.
Activer les instantanés de pods
Pour activer les instantanés de pods, commencez par créer ou mettre à jour un cluster avec la fonctionnalité d'instantanés de pods activée. Créez ou mettez à jour ensuite un pool de nœuds pour qu'il s'exécute dans GKE Sandbox.
Pour activer la fonctionnalité sur un cluster, procédez comme suit :
Pour activer les snapshots de pods sur un nouveau cluster, exécutez la commande suivante :
gcloud beta container clusters create CLUSTER_NAME \ --enable-pod-snapshots \ --cluster-version=CLUSTER_VERSION \ --workload-pool=PROJECT_ID.svc.id.goog \ --workload-metadata=GKE_METADATARemplacez les éléments suivants :
CLUSTER_NAME: nom du clusterCLUSTER_VERSION: version de votre nouveau cluster, qui doit être 1.34.1-gke.3084001 ou ultérieure.PROJECT_ID: ID de votre projet.
Pour activer les snapshots de pods sur un cluster existant, procédez comme suit :
Mettez à jour le cluster vers la version 1.34.1-gke.3084001 ou ultérieure :
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=NODEPOOL_NAME \ --cluster-version=CLUSTER_VERSIONRemplacez les éléments suivants :
CLUSTER_NAME: nom du clusterNODEPOOL_VERSION: nom de votre pool de nœuds.CLUSTER_VERSION: version à utiliser pour mettre à jour votre nouveau cluster, qui doit être 1.34.1-gke.3084001 ou ultérieure.
Activez les instantanés de pod sur votre cluster :
gcloud container clusters update CLUSTER_NAME \ --workload-pool=PROJECT_ID .svc.id.goog" \ --enable-pod-snapshotsRemplacez
PROJECT_IDpar l'ID du projet.
Activez GKE Sandbox sur votre 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=gvisorRemplacez les variables suivantes :
NODE_POOL_NAME: nom de votre nouveau pool de nœuds.NODE_VERSION: version à utiliser pour le pool de nœuds.MACHINE_TYPE: type de machine à utiliser pour les nœuds.
Pour en savoir plus sur l'utilisation de gVisor, consultez Isoler vos charges de travail à l'aide de GKE Sandbox.
Stocker des instantanés
Les instantanés de pods sont stockés dans un bucket Cloud Storage, qui contient l'état de la mémoire et (facultativement) du GPU. Les instantanés de pods nécessitent la fédération d'identité de charge de travail pour GKE afin d'activer et d'utiliser le compte de service du pod pour s'authentifier auprès de Cloud Storage.
Les instantanés de pods nécessitent la configuration suivante pour le bucket :
- Espaces de noms hiérarchiques : ils doivent être activés pour permettre un nombre plus élevé de requêtes de lecture et d'écriture par seconde. Les espaces de noms hiérarchiques nécessitent également que l'accès uniforme au niveau du bucket soit activé.
- Suppression réversible : étant donné que les instantanés de pod utilisent les importations composites parallèles, vous devez désactiver les fonctionnalités de protection des données telles que la suppression réversible. Si vous ne la désactivez pas, la suppression des objets temporaires peut augmenter considérablement votre facture de stockage.
- Emplacement : l'emplacement du bucket Cloud Storage doit être le même que celui du cluster GKE, car les performances peuvent être affectées si les instantanés sont transférés entre différentes régions.
Créer un bucket Cloud Storage
Pour créer le bucket et les autorisations requises, procédez comme suit :
créer un bucket Cloud Storage ; La commande suivante crée un bucket avec la configuration requise :
gcloud storage buckets create "gs://BUCKET_NAME" \ --uniform-bucket-level-access \ --enable-hierarchical-namespace \ --soft-delete-duration=0d \ --location="LOCATION"Remplacez les éléments suivants :
BUCKET_NAME: nom de votre bucket.LOCATION: emplacement de votre bucket.
Pour obtenir la liste complète des options de création de buckets, consultez les options de
buckets create.
Accorder aux charges de travail l'autorisation d'accéder au bucket Cloud Storage
Par défaut, GKE n'est pas autorisé à accéder à Cloud Storage. Pour lire et écrire des fichiers d'instantanés, vous devez accorder des autorisations IAM au compte de service Kubernetes (KSA) utilisé par vos pods de charge de travail.
Obtenez des identifiants pour pouvoir communiquer avec votre cluster à l'aide des commandes
kubectl:gcloud container clusters get-credentials "CLUSTER_NAME"Pour chaque pod, procédez comme suit :
Créez un KSA pour chaque pod :
kubectl create serviceaccount "KSA_NAME" \ --namespace "NAMESPACE"Remplacez les éléments suivants :
KSA_NAME: nom de votre KSA.NAMESPACE: espace de noms de vos pods.
Accordez à la clé de compte de service l'autorisation d'accéder au 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"Remplacez les éléments suivants :
PROJECT_NUMBER: votre numéro de projet.PROJECT_ID: ID de votre projet.
(Facultatif) Créer des dossiers gérés pour le bucket Cloud Storage
La création de dossiers vous permet d'isoler les autorisations pour les instantanés des pods qui ne se font pas mutuellement confiance, ce qui est utile dans les cas d'utilisation multitenants. Pour configurer des dossiers gérés, procédez comme suit :
Créez un rôle IAM personnalisé qui ne contient que les autorisations nécessaires pour les instantanés de pod :
gcloud iam roles create podSnapshotGcsReadWriter \ --project="PROJECT_ID" \ --permissions="storage.objects.get,storage.objects.create,storage.objects.delete,storage.folders.create"Attribuez le rôle
roles/storage.bucketViewerà tous les KSA dans l'espace de noms cible. Ce rôle permet aux ARM de lire les métadonnées des buckets, mais n'accorde pas d'autorisations de lecture ou d'écriture pour les objets du 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"Remplacez les éléments suivants :
PROJECT_NUMBER: votre numéro de projet.PROJECT_ID: ID de votre projet.
Pour chaque KSA qui doit stocker des instantanés de pod, procédez comme suit :
Créez un dossier géré pour le KSA :
gcloud storage managed-folders create "gs://BUCKET_NAME/FOLDER_PATH/"Remplacez
FOLDER_PATHpar le chemin d'accès au dossier géré, par exemplemy-app-snapshots.Attribuez au compte de service de clé le rôle personnalisé
podSnapshotGcsReadWritersur le dossier géré :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"Remplacez
KSA_NAMEpar le nom du KSA.
Configurer le stockage pour les instantanés
Pour spécifier où stocker les fichiers d'instantané, créez une ressource PodSnapshotStorageConfig.
L'exemple suivant configure GKE pour stocker les instantanés de pods dans le chemin d'accès
FOLDER_PATH/à l'intérieur du bucket Cloud Storage BUCKET_NAME. Enregistrez le manifeste suivant sous le nomexample-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"Remplacez les éléments suivants :
NAMESPACE: espace de noms de vos pods. Par défaut, il s'agit de la valeurdefault.BUCKET_NAME: nom du bucket Cloud Storage.FOLDER_PATH: chemin d'accès au dossier géré Cloud Storage.
Appliquez le fichier manifeste :
kubectl apply -f example-pod-snapshot-storage-config.yaml
Créer une règle d'instantané
Pour activer les snapshots pour un pod, créez une ressource PodSnapshotPolicy avec un sélecteur correspondant aux libellés du pod.
L'exemple suivant crée une règle qui s'applique aux pods portant le libellé
app: my-appet qui utilise la configuration de stockageexample-pod-snapshot-storage-config. Enregistrez le fichier manifeste suivant sous le nomexample-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: resumeAppliquez le fichier manifeste :
kubectl apply -f example-pod-snapshot-policy.yaml --namespace NAMESPACE
Optimiser la taille des instantanés
Lorsqu'un instantané de pod est déclenché, gVisor capture l'état complet de tous les conteneurs, y compris :
- État de l'application, comme la mémoire et les registres
- Modifications apportées au système de fichiers racine et à
tmpfs(y compris les volumesemptyDir) - État du noyau, tel que les descripteurs de fichiers ouverts, les threads et les sockets
La taille de l'instantané est déterminée par ces facteurs. Les instantanés plus volumineux mettent plus de temps à être enregistrés et restaurés. Pour optimiser les performances, avant de déclencher un instantané, vous devez nettoyer tout état ou fichier d'application qui ne sont pas nécessaires après la restauration du pod à partir de l'instantané.
L'optimisation de la taille des snapshots est particulièrement importante pour les charges de travail telles que les grands modèles de langage (LLM). Les serveurs LLM téléchargent souvent les pondérations du modèle dans un stockage local (rootfs ou tmpfs) avant de les charger dans le GPU. Lorsqu'un instantané est pris, l'état du GPU et les fichiers de pondération du modèle sont enregistrés. Dans ce scénario, si le modèle fait 100 Go, le snapshot obtenu fera environ 200 Go (100 Go de fichiers de modèle, plus 100 Go représentant l'état du GPU). Une fois les pondérations du modèle chargées dans le GPU, les fichiers du système de fichiers ne sont souvent plus nécessaires pour que l'application s'exécute. En supprimant ces fichiers de modèle avant de déclencher l'instantané, vous pouvez réduire de moitié la taille de l'instantané et restaurer l'application avec une latence considérablement réduite.
Déclencher un instantané
Vous pouvez déclencher un instantané à partir d'une charge de travail lorsque l'application est prête, ou vous pouvez déclencher manuellement un instantané à la demande pour un pod spécifique.
Déclencher un instantané à partir d'une charge de travail
Pour déclencher un instantané à partir du code de votre application, configurez votre application pour qu'elle envoie un signal lorsqu'elle est prête pour un instantané. Pour signaler que le service est prêt, écrivez 1 dans le fichier /proc/gvisor/checkpoint, par exemple echo 1 > /proc/gvisor/checkpoint.. L'opération d'écriture démarre le processus d'instantané de manière asynchrone et renvoie immédiatement. La lecture à partir du même descripteur de fichier bloquera le processus de lecture jusqu'à ce que l'instantané et la restauration soient terminés et que la charge de travail soit prête à reprendre.
L'utilisation exacte varie en fonction de votre application, mais l'exemple suivant montre un déclencheur d'instantané pour une application Python. Pour déclencher un instantané à partir de cet exemple de charge de travail, procédez comme suit :
Enregistrez le manifeste suivant sous le nom
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"Pour déployer l'application, procédez comme suit :
kubectl apply -f my-app.yaml
Déclencher manuellement un instantané
Pour déclencher manuellement un instantané à la demande pour un pod spécifique, créez une ressource PodSnapshotManualTrigger. Le déclenchement manuel d'un instantané est disponible dans les versions 1.34.1-gke.3556000 et ultérieures de GKE.
L'exemple suivant déclenche un instantané pour un pod nommé
my-pod. Enregistrez le manifeste suivant sous le nomexample-manual-trigger.yaml:apiVersion: podsnapshot.gke.io/v1alpha1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-podAppliquez le fichier manifeste :
kubectl apply -f example-manual-trigger.yaml --namespace NAMESPACE
Pour vérifier si l'instantané a bien été déclenché, consultez le champ status de la ressource PodSnapshotManualTrigger :
kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io example-manual-trigger -n NAMESPACE -o yaml
Le champ status indique si le déclenchement du snapshot a réussi ou échoué.
Valider des instantanés
Pour vérifier qu'un instantané a été pris, consultez l'historique des événements pour les événements 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
Remplacez POD_NAME par le nom de votre pod, par exemple my-app ou my-pod.
Le résultat se présente comme suit :
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
Gérer les instantanés
Lorsque vous créez un instantané de pod, une ressource CRD PodSnapshot est créée pour stocker l'état du pod à ce moment-là. Le champ status de cette ressource indique si l'opération d'instantané a réussi et si l'instantané est disponible pour les restaurations.
Pour afficher toutes les ressources PodSnapshot d'un espace de noms, exécutez la commande suivante :
kubectl get podsnapshots.gke.io --namespace NAMESPACE
Le résultat se présente comme suit :
NAME STATUS POLICY AGE
de334898-1e7a-4cdb-9f2e-7cc2181c29e4 AllSnapshotsAvailable example-policy 47h
Restaurer une charge de travail à partir d'un instantané
Pour restaurer votre charge de travail à partir du dernier instantané, vous pouvez supprimer le pod existant après la création d'un instantané, puis redéployer le pod. Vous pouvez également déployer un nouveau pod avec une spécification identique. GKE restaure automatiquement le pod à partir de l'instantané correspondant.
Les étapes suivantes montrent comment un pod est restauré à partir d'un instantané correspondant en supprimant et en redéployant le pod :
Supprimez le pod :
kubectl delete -f POD_NAME.yamlRemplacez
POD_NAMEpar le nom de votre pod, par exemplemy-app.Appliquez à nouveau le pod :
kubectl apply -f POD_NAME.yamlConsultez les journaux pour confirmer la restauration de l'instantané :
kubectl logs my-app --namespace NAMESPACELe résultat dépend de la façon dont vous avez configuré votre application. Dans l'exemple d'application, les journaux affichent
GKE Pod Snapshot: restorelorsqu'une opération de restauration se produit.
Restaurer à partir d'un instantané spécifique
Par défaut, GKE restaure les charges de travail à partir de la ressource PodSnapshot la plus récente correspondant au pod. Lorsqu'un instantané est pris, GKE génère automatiquement un nom unique (UUID) pour la ressource PodSnapshot, que vous pouvez afficher en exécutant kubectl get podsnapshots.gke.io --namespace NAMESPACE.
Pour restaurer une charge de travail à partir d'une ressource PodSnapshot ancienne ou spécifique, ajoutez l'annotation podsnapshot.gke.io/ps-name à la spécification du pod de votre charge de travail, en spécifiant le nom de la ressource PodSnapshot à utiliser pour la restauration de la charge de travail :
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:
...
Remplacez POD_SNAPSHOT_NAME par le nom de l'instantané à partir duquel vous souhaitez effectuer la restauration. Vous pouvez obtenir les noms des instantanés en exécutant la commande kubectl get podsnapshots.gke.io --namespace NAMESPACE.
Pour que GKE utilise l'instantané spécifié pour la restauration, l'état de la ressource PodSnapshot doit être Ready et exister dans le même espace de noms que le pod. Si PodSnapshot n'est pas Ready ou n'existe pas dans le même espace de noms que le pod, la charge de travail effectue un démarrage à froid au lieu d'être restaurée à partir d'un instantané.
Désactiver les instantanés
La suppression du CRD PodSnapshotPolicy empêche la création d'instantanés et la restauration des pods. Les pods en cours d'exécution ne sont pas affectés par la suppression des ressources. Toutefois, si vous supprimez la règle pendant qu'un pod est en cours d'enregistrement ou de restauration, il est possible qu'il passe à l'état "Échec".
Pour désactiver la création et la restauration de snapshots pour les nouveaux pods régis par une règle, supprimez PodSnapshotPolicy en exécutant la commande suivante :
kubectl delete podsnapshotpolicies.podsnapshot.gke.io SNAPSHOT_POLICY --namespace=NAMESPACE
Remplacez SNAPSHOT_POLICY par le nom de l'PodSnapshotPolicy que vous souhaitez supprimer, par exemple example-pod-snapshot-policy.
Vous pouvez également supprimer une ressource PodSnapshot spécifique afin que les pods ne soient plus restaurés à partir de cet instantané spécifique. La suppression de la ressource PodSnapshot supprime également les fichiers stockés dans Cloud Storage.
Pour empêcher l'utilisation d'un instantané spécifique pour les restaurations futures, supprimez l'objet PodSnapshot en exécutant la commande suivante :
kubectl delete podsnapshots.podsnapshot.gke.io POD_SNAPSHOT_NAME --namespace=NAMESPACE
Remplacez POD_SNAPSHOT_NAME par le nom de l'instantané que vous souhaitez supprimer, par exemple example-podsnapshot.
Étapes suivantes
- En savoir plus sur les concepts liés aux instantanés de pods
- Consultez les définitions de ressources personnalisées (CRD) des instantanés de pods.