GKE-Pod-Snapshots

GKE-Pod-Snapshots (Google Kubernetes Engine) können die Startlatenz von Arbeitslasten verbessern, indem sie Snapshots von ausgeführten Pods wiederherstellen. Ein Pod-Snapshot speichert den gesamten Pod-Status, einschließlich Speicher- und Dateisystemänderungen. Wenn Sie neue Replikate erstellen, werden sie aus dem Snapshot wiederhergestellt. So kann die Arbeitslast fortgesetzt werden, anstatt von einem neuen Status aus zu starten.

Dieses Dokument bietet eine konzeptionelle Übersicht über GKE-Pod-Snapshots. Informationen zum Aktivieren und Verwenden dieser Funktion finden Sie in den folgenden Dokumenten:

  1. Pod-Snapshots vorbereiten
  2. Pod-Snapshot auslösen
  3. Arbeitslast aus einem Pod-Snapshot wiederherstellen

Wann sollten Pod-Snapshots verwendet werden?

Verwenden Sie Pod-Snapshots für Arbeitslasten mit langen Initialisierungszeiten, z. B. für KI-Inferenzarbeitslasten, bei denen große Modelle in den CPU- oder GPU-Speicher geladen werden, oder für große Anwendungen, bei denen viele Bibliotheken und Abhängigkeiten geladen werden. Arbeitslasten mit bereits kurzen Startzeiten profitieren in der Regel nicht von Pod-Snapshots.

Funktionsweise von Pod-Snapshots

GKE-Pod-Snapshots speichern eine exakte Kopie des Prozessstatus eines Pods zu einem bestimmten Zeitpunkt. Wenn neue Replikate erstellt werden, wird der Pod nicht aus einem neuen Status initialisiert, sondern aus einem Snapshot wiederhergestellt. Die Ausführung wird an dem Punkt fortgesetzt, an dem der Snapshot erstellt wurde.

Wenn Sie Pod-Snapshots verwenden möchten, erstellen Sie benutzerdefinierte Kubernetes-Ressourcendefinitionen (CustomResourceDefinitions, CRDs), um das Snapshot-Verhalten deklarativ zu konfigurieren. Ein Agent, der auf jedem GKE-Knoten ausgeführt wird, verwaltet den Snapshot-Lebenszyklus. Basierend auf den von Ihnen definierten Richtlinien bestimmt der Agent, wann neue Snapshots erstellt und wann vorhandene Snapshots verwendet werden sollen, um neue Pods wiederherzustellen. Ein Controller, der auf der GKE-Steuerungsebene ausgeführt wird, bereinigt veraltete Snapshots und behebt Probleme. Cloud Storage speichert Ihre Pod-Snapshots.

Snapshot-Inhalte

In der folgenden Tabelle wird beschrieben, was in einem Pod-Snapshot enthalten ist und was nicht:

Kategorie In einem Snapshot enthalten Nicht in einem Snapshot enthalten
Anwendungsstatus Der gesamte Anwendungsstatus: alle offenen Dateideskriptoren, Threads, CPU-Register und der Arbeitsspeicher.
Dateisysteme Das Container-Rootdateisystem (rootfs), EmptyDir-Volumes und tmpfs-Mounts. Alles, was nicht in der vorherigen Spalte aufgeführt ist. Insbesondere werden nichtflüchtige Volumes nicht als Prüfpunkt gespeichert.
Netzwerk Loopback-Verbindungen, Listening-Sockets und Unix-Domain-Sockets. Externe Verbindungen werden nicht wiederhergestellt (sie werden bei der Wiederherstellung beendet). Von Nutzern hinzugefügte Regeln wie iptables oder nftables und Routen werden nicht wiederhergestellt.

CustomResourceDefinitions

Pod-Snapshots werden deklarativ mit den folgenden CRDs konfiguriert:

  • PodSnapshotStorageConfig: gibt den Speicherort für Snapshots an. Es werden nur Cloud Storage-Buckets unterstützt.
  • PodSnapshotPolicy: definiert anhand von Kubernetes-Label-Selectoren, welche Pods als Snapshot gespeichert werden sollen. Diese Ressource enthält die meisten Konfigurationsoptionen für die Funktion, einschließlich der Auslösung von Snapshots, des Snapshot-Umfangs und der Aufbewahrungsrichtlinien.
  • PodSnapshotManualTrigger: (optional) Wenn Sie keinen Arbeitslast-Trigger verwenden, definiert diese Ressource einen manuellen Trigger zum Erstellen eines Snapshots für einen bestimmten Pod.

Snapshot-Trigger

Sie können einen Pod-Snapshot auf folgende Arten auslösen:

  • Arbeitslast-Trigger: Die Anwendung im Pod signalisiert dem GKE-Agent, dass sie für einen Snapshot bereit ist. Diese Art von Trigger wird einmal in einem Arbeitslastzyklus ausgeführt, z. B. wenn die Arbeitslast bereit ist. Dieser Ansatz eignet sich am besten, um die Startlatenz von horizontal skalierten Arbeitslasten zu verbessern.
  • Manueller Trigger: Sie können einen Snapshot bei Bedarf für einen bestimmten Pod auslösen indem Sie eine benutzerdefinierte PodSnapshotManualTrigger-Ressource erstellen. Diese Art von Trigger kann beliebig oft ausgeführt werden. Dieser Ansatz eignet sich am besten für Situationen, in denen Sie Ihre Anwendung nicht so ändern können, dass sie die Bereitschaft signalisiert.

Snapshot-Abgleich und -Kompatibilität

Damit ein Snapshot mit einer wiederhergestellten Arbeitslast kompatibel ist, führt GKE einen Kompatibilitätsabgleich zwischen dem ursprünglichen Pod mit Prüfpunkt und dem Ziel-Pod durch.

Die Kompatibilität wird durch die folgenden Regeln bestimmt:

  • Auswahlreihenfolge: Standardmäßig stellt GKE Arbeitslasten aus der neuesten PodSnapshot-Ressource wieder her, die dem Namespace und der Konfiguration des Pods entspricht.
  • Abgleichskriterien: Die Kompatibilitätsprüfung variiert je nach Snapshot Umfang, der in Ihrer PodSnapshotPolicy konfiguriert ist (whole-pod oder rootfs-only).

Abgleich mit whole-pod-Umfang (Standard)

Bei Richtlinien mit dem Standardumfang whole-pod prüft GKE Folgendes:

  1. Hash der destillierten Spezifikation: GKE generiert einen eindeutigen Hash basierend auf den wichtigsten Laufzeitfeldern in der Spezifikation des Pods. Damit eine Wiederherstellung erfolgreich ist, muss der Ziel-Pod aus seiner destillierten Spezifikation einen identischen Hash generieren. Diese Prüfung stellt sicher, dass die Pods mit Prüfpunkt und die wiederhergestellten Pods in ihren Laufzeitkonfigurationen identisch sind.

    Die folgenden Felder aus dem Pod-Objekt sind Teil der destillierten Spezifikation und beeinflussen den eindeutigen Hash:

    • metadata:
      • annotations: nur Annotationen, die für die gVisor-Laufzeit relevant sind (z. B. Annotationen, die mit dem Präfix dev.gvisor.* beginnen).
      • labels: batch.kubernetes.io/job-completion-index
    • spec:
      • volumes: name, volumeSource, hostPath, persistentVolumeClaim, configMap
      • containers:
        • name
        • image
        • command
        • args
        • workingDir
        • ports: name, containerPort, protocol
        • volumeMounts: name, readOnly, recursiveReadOnly, mountPath, subPath, mountPropagation, subPathExpr
        • volumeDevices: name
        • lifecycle: postStart, preStop
        • terminationMessagePath
        • terminationMessagePolicy
        • securityContext (und alle Unterfelder)
        • stdin
        • stdinOnce
        • tty
      • initContainers: dieselben Unterfelder wie containers.
      • dnsPolicy
      • automountServiceAccountToken
      • hostNetwork
      • hostPID
      • hostIPC
      • shareProcessNamespace
      • securityContext
      • dnsConfig
      • runtimeClassName
      • os
      • hostUsers
  2. Hardwarekompatibilität: Der Ziel-Pod muss auf einem Knoten mit derselben Maschinenserie und CPU-Architektur wie der ursprüngliche Pod mit Prüfpunkt ausgeführt werden (z. B. N2 zu N2 oder G2 zu G2).

  3. Versionskompatibilität: Die gVisor-Kernel-Version und die GPU-Treiberversion müssen mit der Version übereinstimmen, die im ursprünglichen Snapshot erfasst wurde.

Abgleich mit rootfs-only-Umfang

Wenn Sie Ihre Richtlinie mit dem Umfang rootfs-only konfigurieren (verfügbar in GKE-Version 1.35.3-gke.1031000 und höher), sind die Abgleichsanforderungen weniger streng:

  • GKE berechnet oder vergleicht den Hash der destillierten Pod-Spezifikation nicht. Durch diesen weniger strengen Abgleich können Sie einen Snapshot in einem Ziel-Pod wiederherstellen, der sich in Bezug auf Ressourcen, Umgebungen oder andere Konfigurationsfelder vom ursprünglichen Pod mit Prüfpunkt unterscheidet. Voraussetzung ist, dass das zugrunde liegende Container-Image und die Knotenversionen kompatibel sind.
  • Da der Prozessspeicher nicht wiederhergestellt wird, können Sie Snapshots, die auf einer Maschinenserie erstellt wurden, in einer anderen Maschinenserie wiederherstellen (einschließlich E2-Maschinentypen).

Abgleich mit Gruppierungsregeln

Wenn in der Richtlinie das Feld snapshotGroupingRules verwendet wird, um Snapshots nach bestimmten Label-Werten zu gruppieren (z. B. nach Mandant oder Umgebung), müssen die wiederhergestellten Pods genau dieselben Label-Schlüssel und -Werte haben. Der Pod-Snapshot-Controller wählt nur einen Snapshot aus der entsprechenden Gruppe aus. Weitere Informationen zum Einrichten von Gruppierungs-Labels finden Sie unter Zusätzliche Pod-Snapshot Richtlinien konfigurieren.

Bereitschaft zur Wiederherstellung und Hintergrundladen

Wenn ein Pod aus einem Snapshot wiederhergestellt wird, wird zuerst der gVisor-Kernel wiederhergestellt. Das dauert in der Regel einige Sekunden. Um die Startlatenz zu minimieren, wird die Anwendung sofort nach der Wiederherstellung des Kernels fortgesetzt. Sie wartet nicht, bis der Anwendungsspeicher vollständig geladen ist. Der Anwendungsspeicher wird mithilfe eines Hintergrund-Streamingmechanismus wiederhergestellt.

Wenn die Anwendung versucht, auf einen Teil des Speichers zuzugreifen, der noch nicht geladen wurde, tritt ein Seitenfehler auf. gVisor fängt diesen Fehler ab, pausiert den Anwendungsthread und ruft sofort die erforderliche Speicherseite aus dem Speicher ab. Dieser Abruf bei Bedarf hat Vorrang vor dem Hintergrundstream.

Aufgrund dieses Hintergrundladens kann der Speicherzugriff in den ersten Sekunden nach der Wiederherstellung eine geringe Latenz aufweisen, wenn die Anwendung Speicher benötigt, der noch nicht gestreamt wurde. Diese Latenz verschwindet, wenn der Speicherstatus vollständig synchronisiert ist.

Dieses Verhalten beim Hintergrundladen gilt auch für den GPU-Status. Beispielsweise kann ein Pod mit einem großen Sprachmodell (Large Language Model, LLM) den Status Running haben und auf Netzwerkprüfungen reagieren, obwohl der GPU-Speicher noch gefüllt wird. Das Modell ist erst dann vollständig für die Inferenz verfügbar, wenn der GPU-Status vollständig wiederhergestellt wurde. Berücksichtigen Sie diese Verzögerung bei der Messung der Wiederherstellungsgeschwindigkeit und erfassen Sie, wann der Modellserver gestartet wurde. Sie können den Start des Modell servers anhand von Messwerten wie der Zeit bis zum ersten Token (Time-to-First-Token, TTFT) oder Pod-Bereitschaftstests prüfen.

GPU-Status

Pod-Snapshots unterstützen die Erfassung des GPU-Status. Wenn Sie einen Snapshot für einen Pod auslösen, der GPUs verwendet, speichert das NVIDIA-Tool cuda-checkpoint den GPU-Status im Prozessspeicher. Das bedeutet, dass alle auf der GPU gespeicherten Daten, z. B. Modellgewichte, im Snapshot enthalten sind. Der Pod wird dann pausiert und als Snapshot gespeichert. Bei der Wiederherstellung wird der Vorgang umgekehrt.

Da der GPU-Status in den Prozessarbeitsspeicher geschrieben wird, steigt die Pod-Arbeitsspeichernutzung während der Snapshot- und Wiederherstellungsvorgänge. Berücksichtigen Sie diesen zusätzlichen Speicherbedarf, wenn Sie Speicherlimits für Ihre Pods festlegen.

Hinweise zu wiederhergestellten Pods

Aus Sicht der Kubernetes API wird ein neuer Pod erstellt. Wenn der Pod gestartet wird und ein entsprechender Snapshot für den Pod vorhanden ist, wird der Pod aus diesem Snapshot wiederhergestellt, einschließlich des ursprünglichen Speicher- und Prozessstatus. Einige Aspekte des Pod-Status müssen sich jedoch ändern, damit er als neue, eindeutige Instanz funktioniert.

Beachten Sie die folgenden Statusänderungen nach einer Wiederherstellung:

  • Netzwerkschnittstellen: Der wiederhergestellte Pod erhält eine neue IP-Adresse. Alle Schnittstellen und Routen werden neu konfiguriert. Aktive Netzwerkverbindungen, die zum Zeitpunkt der Snapshot-Erstellung bestanden, werden bei der Wiederherstellung geschlossen. Listening-Sockets, Loopback-Verbindungen und Unix-Domain-Socket-Verbindungen funktionieren weiterhin.
  • Hostname: Der wiederhergestellte Pod erhält eine neue Identität und einen neuen Hostnamen.
  • Echtzeit: Die Echtzeit wird auf die aktuelle Zeit gesetzt.
  • Anwendungsstatus: Der Anwendungsstatus muss für jeden Pod eindeutig sein, z. B. Experiment-IDs oder Zufallszahl-Seeds, und muss nach einer Wiederherstellung neu initialisiert werden.
  • Secrets: Verschlüsselungsschlüssel und Zertifikate, die vor der Snapshot-Erstellung erstellt wurden, müssen neu erstellt werden.
  • Umgebungsvariablen: Sie können Umgebungsvariablen zwischen einem Snapshot und einer Wiederherstellung ändern. Da Umgebungsvariablen jedoch im Anwendungsspeicher gespeichert werden, kann GKE Sandbox sie nicht zuverlässig finden und ersetzen. Wenn Ihre Arbeitslast nach einer Wiederherstellung auf neuen Umgebungsvariablen basiert, müssen diese manuell vom Pod aktualisiert werden. Die neuen Umgebungsvariablen sind in der Datei /proc/gvisor/spec_environ verfügbar. Das Dateiformat ist dasselbe wie /proc/<pid>/environ.

Mehrmandantenfähigkeit und Identität

Für Pod-Snapshots sind manuelle IAM-Bindungen für das Kubernetes-Dienstkonto (Kubernetes ServiceAccount, KSA) jedes Pods erforderlich, um auf Cloud Storage zuzugreifen. Es kann einige Zeit dauern, bis die manuellen IAM-Bindungen weitergegeben werden. Das kann ein Problem sein, wenn Sie sofort nach der Erstellung eines Pods Snapshots erstellen müssen.

Um Verzögerungen zu vermeiden und die Verwaltung mehrerer Mandanten zu vereinfachen, können Sie optional ein GKE-Knoten-Dienstkonto verwenden, um bei Bedarf kurzlebige Tokens zu erstellen, anstatt IAM manuell an KSAs zu binden. Wenn Sie Pod-Snapshots mit diesem Ansatz konfigurieren möchten, verwenden Sie das Feld tokenSource im PodSnapshotStorageConfig-Objekt mit einem der folgenden Werte:

  • podKSA (Standard): Manuelle IAM-Bindung des KSA des Pods an den Cloud Storage-Bucket.
  • federatedP4SA: Verwenden Sie ein pfadspezifisches Token, das vom Knoten-Dienstkonto erstellt wurde.

Beschränkungen und Anforderungen

Für GKE-Pod-Snapshots gelten die folgenden Einschränkungen:

  • Pods müssen in GKE Sandbox ausgeführt werden, da Pod-Snapshots von der gVisor-Containerlaufzeit abhängen, die von GKE Sandbox bereitgestellt wird.
  • Pod-Snapshots unterstützen keine E2-Maschinentypen, wenn der Standardumfang whole-pod verwendet wird. Dateisystem-Snapshots (rootfs-only) unterstützen E2-Maschinentypen.
  • Für die GPU-Unterstützung für Pod-Snapshots gelten die folgenden Anforderungen und Einschränkungen:
    • Pods mit einer einzelnen GPU werden sowohl auf Knoten mit einer einzelnen GPU als auch auf Knoten mit mehreren GPUs unterstützt.
    • Pods mit mehreren GPUs werden nur auf L4-GPUs (g2-standard-*-Maschinentypen) unterstützt.
    • Die GPU-Freigabe mit Multi-Instance GPU (MIG) wird nicht unterstützt.
    • In GKE-Versionen 1.35.0-gke.1738000 und früher muss ein Pod, der auf einem Knoten mit mehreren GPUs ausgeführt wird, alle auf diesem Knoten verfügbaren GPUs verwenden. In Versionen 1.35.0-gke.1738000 und höher können Pods eine Teilmenge der GPUs auf einem Knoten verwenden.
    • Pod-Snapshots unterstützen die folgenden Maschinentypen:
      • g2-standard-4 (1 x L4)
      • g2-standard-8 (1 x L4)
      • g2-standard-12 (1 x L4)
      • g2-standard-16 (1 x L4)
      • g2-standard-32 (1 x L4)
      • g2-standard-48 (4 x L4)
      • g2-standard-96 (8 x L4)
      • a2-highgpu-1g (1 x A100-40GB)
      • a2-ultragpu-1g (1 x A100-80GB)
      • a3-highgpu-1g (1 x H100-80GB)
  • Der Sidecar-Container des Cloud Storage FUSE CSI-Treibers wird mit Pod-Snapshots nicht unterstützt.
  • Pod-Snapshots unterstützen keine TPU-Maschinentypen.

Nächste Schritte