Arbeitslasten mit GKE Sandbox isolieren

Mit GKE Sandbox können Sie den Hostkernel Ihrer Google Kubernetes Engine-Knoten (GKE) vor Containern schützen, in denen nicht vertrauenswürdiger oder unbekannter Code ausgeführt wird. In diesem Dokument wird Sicherheitsexperten gezeigt, wie sie die GKE Sandbox aktivieren, Pods in Sandboxen ausführen und die Isolation prüfen können.

Sie sollten bereits mit GKE Sandbox vertraut sein.

Verfügbare Sandbox-Typen

GKE Sandbox unterstützt die folgenden Sandbox-Typen, die jeweils eine bestimmte Technologie verwenden, um Anwendungscode vom Hostkernel zu trennen:

  • gvisor: Eine Neuimplementierung der Linux-Kernel-API im Userspace, für die keine erhöhten Berechtigungen erforderlich sind. Der Userspace-Kernel fängt die meisten Systemaufrufe im Namen des Host-Kernels ab und verarbeitet sie. Dadurch wird der direkte Zugriff auf den Host-Kernel eingeschränkt.
  • microvm: Lightweight-VMs, die auf der Host-VM durch verschachtelte Virtualisierung verschachtelt werden. Jeder Pod auf dem Knoten wird in einer eigenen verschachtelten VM mit eigenem Gastkernel ausgeführt. Da der Code in einer dedizierten VM ausgeführt wird, bietet dieser Sandbox-Typ eine stärkere Isolation als gVisor-Sandboxes.

Weitere Informationen zur Funktionsweise der einzelnen Sandbox-Typen und dazu, wann ein bestimmter Typ verwendet werden sollte, finden Sie unter Informationen zu GKE Sandbox.

Beschränkungen

GKE Sandbox und bestimmte Sandbox-Technologien haben verschiedene Einschränkungen, z. B. die Unterstützung von GPUs und TPUs oder die Unterstützung bestimmter Linux- und Kubernetes-Features. Weitere Informationen finden Sie unter Einschränkungen.

Hinweis

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit dem Befehl gcloud components update ab. Ältere gcloud CLI-Versionen unterstützen möglicherweise nicht die Ausführung der Befehle in diesem Dokument.
  • Wenn Sie die Schritte im Abschnitt Sandbox-Typ für automatisch erstellte Knoten auswählen ausführen möchten, verwenden Sie einen vorhandenen Autopilot- oder Standardcluster. Wenn Sie MicroVM-Sandboxes verwenden möchten, müssen Ihre Knoten die GKE-Version 1.37.0-gke.4713000 oder höher ausführen.

Sandbox-Typ für automatisch erstellte Knoten auswählen

Sie können ComputeClasses mit dem Autopilot-Modus oder der automatischen Erstellung von Knotenpools verwenden, um GKE Sandbox auf Knoten zu aktivieren, die von GKE erstellt werden. In Autopilot-Clustern wird gVisor standardmäßig unterstützt. Sie können die Sandbox-Konfiguration also optional aus Ihrer ComputeClass weglassen.

So konfigurieren Sie GKE Sandbox für automatisch erstellte Knoten:

  1. Verbindung zu einem vorhandenen Autopilot- oder Standardcluster herstellen:

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    Ersetzen Sie Folgendes:

    • CLUSTER_NAME: Der Name Ihres Clusters.
    • CONTROL_PLANE_LOCATION: die Region oder Zone der Steuerungsebene Ihres Clusters.
  2. Speichern Sie eines der folgenden ComputeClass-Manifeste, je nachdem, welche Sandbox-Technologie Sie verwenden möchten:

    • gVisor:

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: sandbox-gvisor-class
      spec:
        priorities:
        - machineFamily: n4
        - machineFamily: c4
        nodePoolConfig:
          sandbox:
            type: gvisor
        nodePoolAutoCreation:
          enabled: true
        whenUnsatisfiable: DoNotScaleUp
      
    • microVM:

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: sandbox-microvm-class
      spec:
        priorities:
        - machineFamily: n4
        - machineFamily: c4
        nodePoolConfig:
          sandbox:
            type: microvm
        priorityDefaults:
          enableNestedVirtualization: true
        nodePoolAutoCreation:
          enabled: true
        whenUnsatisfiable: DoNotScaleUp
      

      Die ComputeClass für MicroVM-Sandboxes ermöglicht die verschachtelte Virtualisierung über das Feld enableNestedVirtualization. Dieses Feld ist für MicroVM-Sandboxes erforderlich. Damit Sie dieses Feld verwenden können, muss auf Ihrem Cluster die Version 1.37.0-gke.4713000 oder höher ausgeführt werden.

    In diesen Beispielmanifesten wird das Feld nodePoolAutoCreation verwendet, um das automatische Erstellen von Knotenpools zu aktivieren. Sie können die Sandbox-Konfiguration auch in einer ComputeClass angeben, die das Feld autopilot verwendet, um Pods im Autopilot-Modus auszuführen. Wenn Sie Autopilot-Cluster verwenden, ignoriert GKE sowohl die Felder nodePoolAutoCreation als auch autopilot.

  3. ComputeClass erstellen:

    kubectl apply -f PATH_TO_COMPUTE_CLASS_MANIFEST
    

    Ersetzen Sie PATH_TO_COMPUTE_CLASS_MANIFEST durch den Pfad zum ComputeClass-Manifest.

Informationen zum Auswählen dieser ComputeClass und zum Anfordern einer Sandbox-Umgebung finden Sie unter Sandbox-Umgebung für einen Pod anfordern.

Sandbox-Typ beim Erstellen von Knotenpools auswählen

Sie können GKE Sandbox manuell aktivieren, wenn Sie einen neuen Knotenpool in einem Standardcluster erstellen. Die folgenden Einschränkungen gelten, wenn Sie GKE Sandbox manuell aktivieren:

  • Wenn Sie GKE Sandbox während der Erstellung eines Standardclusters aktivieren möchten, müssen Sie mindestens einen zusätzlichen Knotenpool konfigurieren. Der zusätzliche Knotenpool ist erforderlich, da GKE mindestens einen Knotenpool im Cluster benötigt, in dem keine GKE Sandbox verwendet wird, um von GKE verwaltete Systemarbeitslasten auszuführen. Wenn Sie die gcloud CLI zum Erstellen des Clusters verwenden, müssen Sie den Cluster erstellen und dann einen Knotenpool erstellen, der GKE Sandbox verwendet.
  • Wenn Sie den MicroVM-Sandbox-Typ auswählen möchten, müssen Sie die gcloud CLI oder die GKE API verwenden. In derGoogle Cloud Console kann der Sandbox-Typ „microVM“ nicht ausgewählt werden.

gVisor-Sandbox-Typ aktivieren

Wenn Sie gVisor-Sandboxes beim Erstellen eines neuen Knotenpools manuell aktivieren möchten, wählen Sie eine der folgenden Optionen aus:

Console

  1. Rufen Sie in der Google Cloud Console die Seite Kubernetes-Cluster auf.

    Zur Seite "Kubernetes-Cluster"

  2. Klicken Sie auf den Namen des Clusters, den Sie ändern möchten. Die Seite Clusterdetails wird geöffnet.

  3. Klicken Sie auf den Tab Knoten.

  4. Klicken Sie im Bereich Knotenpools auf Nutzerverwalteten Knotenpool hinzufügen. Die Seite Knotenpool hinzufügen wird geöffnet.

  5. Klicken Sie im Navigationsmenü auf Knoten und konfigurieren Sie die folgenden Einstellungen:

    1. Wählen Sie in der Drop-down-Liste Image-Typ die Option Container-Optimized OS mit Containerd (cos_containerd) aus.
    2. Wählen Sie im Abschnitt Maschinenkonfiguration eine Maschinenserie und einen Maschinentyp für die Knoten aus.
    3. Optional: Wählen Sie einen unterstützten GPU-Typ oder einen unterstützten TPU-Typ aus.
  6. Klicken Sie im Navigationsmenü auf Sicherheit. Die Seite Knotensicherheit wird geöffnet.

  7. Klicken Sie auf das Kästchen Sandbox mit gVisor aktivieren.

  8. Klicken Sie auf Erstellen, um den Knotenpool zu erstellen.

gcloud

Führen Sie den folgenden Befehl aus, um einen Knotenpool zu erstellen, der gVisor für Sandboxes verwendet:

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --sandbox=type=gvisor

Ersetzen Sie Folgendes:

  • NODE_POOL_NAME: ein Name für den Knotenpool.
  • CLUSTER_NAME: Der Name Ihres Clusters.
  • CONTROL_PLANE_LOCATION: die Region oder Zone der Steuerungsebene Ihres Clusters.

Sie können gVisor-Sandboxes auch aktivieren, wenn Sie Knotenpools erstellen, die einen unterstützten GPU-Typ oder einen unterstützten TPU-Typ verwenden. Weitere Informationen finden Sie in den folgenden Dokumenten:

MicroVM-Sandbox-Typ aktivieren

Sie können den MicroVM-Sandbox-Typ aktivieren, wenn Sie einen Knotenpool mit der gcloud CLI oder der GKE API erstellen. In der Google Cloud Console wird das Aktivieren des MicroVM-Sandbox-Typs nicht unterstützt. Führen Sie den folgenden Befehl aus, um einen Knotenpool zu erstellen, der MicroVM-Sandboxes verwendet:

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --sandbox=type=microvm \
    --enable-nested-virtualization \
    --machine-type=MACHINE_TYPE

Ersetzen Sie Folgendes:

  • NODE_POOL_NAME: ein Name für den Knotenpool.
  • CLUSTER_NAME: Der Name Ihres Clusters.
  • CONTROL_PLANE_LOCATION: die Region oder Zone der Steuerungsebene Ihres Clusters.
  • MACHINE_TYPE: Der Maschinentyp für die Knoten. Dieser Wert muss ein Maschinentyp sein, der verschachtelte Virtualisierung unterstützt. Weitere Informationen finden Sie in der Zeile Verschachtelte Virtualisierung in der Vergleichstabelle der Maschinenserien.

Monitoring und Logging aktivieren

Damit Logs und Messwerte aus Ihren Sandboxes erfasst und angezeigt werden können, müssen die folgenden Beobachtbarkeitsdienste in Ihrem Cluster aktiviert sein:

Diese Dienste sind in allen neuen GKE-Clustern standardmäßig aktiviert.

Sandbox-Umgebung für einen Pod anfordern

Wenn Sie einen bestimmten Pod in einer Sandbox ausführen möchten, können Sie die RuntimeClass gvisor oder microvm in der Pod-Spezifikation angeben. GKE plant den Pod auf Knoten, die den angegebenen Sandbox-Typ verwenden. So wählen Sie einen Sandbox-Typ in einer Pod-Spezifikation aus:

  1. Speichern Sie eines der folgenden Beispielmanifeste für Deployments, je nachdem, ob Sie GKE Sandbox mit ComputeClasses oder manuell erstellten Knotenpools aktivieren:

    • ComputeClasses:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sandbox-pod
        labels:
          environment: sandbox
      spec:
        replicas: 2
        selector:
          matchLabels:
            environment: sandbox
        template:
          metadata:
            labels:
              environment: sandbox
          spec:
            nodeSelector:
              cloud.google.com/compute-class: COMPUTECLASS_NAME
            runtimeClassName: SANDBOX_TYPE
            
            containers:
            - name: nginx
              image: nginx
      

      Ersetzen Sie Folgendes:

      • COMPUTECLASS_NAME: Der Name der ComputeClass, die Sie erstellt haben, wie unter Sandbox-Typ für automatisch erstellte Knoten auswählen beschrieben.

      • SANDBOX_TYPE: der Sandbox-Typ, der für die Pods verwendet werden soll. Folgende Werte werden unterstützt:

        • gvisor
        • microvm

        Der angegebene Sandbox-Typ muss mit dem Sandbox-Typ übereinstimmen, der von der ausgewählten ComputeClass aktiviert wird.

    • Manuell erstellte Knotenpools:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: httpd
        labels:
          app: httpd
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: httpd
        template:
          metadata:
            labels:
              app: httpd
          spec:
            runtimeClassName: SANDBOX_TYPE
            containers:
            - name: httpd
              image: httpd
      

      Ersetzen Sie SANDBOX_TYPE durch den Sandbox-Typ. Folgende Werte werden unterstützt:

      • gvisor
      • microvm

      Der von Ihnen angegebene Sandbox-Typ muss mit dem Sandbox-Typ eines vorhandenen Knotenpools im Cluster übereinstimmen.

  2. Erstellen Sie das Deployment:

    kubectl apply -f PATH_TO_DEPLOYMENT_MANIFEST
    

    Ersetzen Sie PATH_TO_DEPLOYMENT_MANIFEST durch den Pfad zum Bereitstellungsmanifest.

  3. Prüfen Sie, ob die Pods erstellt wurden:

    kubectl get pods
    

    Die Ausgabe sieht etwa so aus:

    NAME                    READY   STATUS    RESTARTS   AGE
    httpd-db5899bc9-dk7lk   1/1     Running   0          24s
    

Sie können auch Sandboxes anfordern, wenn Sie Pods auf einem unterstützten GPU-Typ oder einem unterstützten TPU-Typ ausführen. Verwenden Sie dazu das Feld runtimeClassName. Weitere Informationen finden Sie in den folgenden Dokumenten:

Regulären Pod zusammen mit Pods ausführen, die in einer Sandbox ausgeführt werden

Die Schritte in diesem Abschnitt gelten für Arbeitslasten im Standardmodus. Sie müssen keine regulären Pods zusammen mit den Sandbox-Pods im Autopilot-Modus ausführen, da das Autopilot-Preismodell die manuelle Optimierung der Anzahl der auf den Knoten geplanten Pods überflüssig macht.

Nachdem Sie GKE Sandbox in einem Knotenpool aktiviert haben, können Sie vertrauenswürdige Anwendungen auf diesen Knoten ohne Verwendung einer Sandbox mithilfe von Knotenmarkierungen und -toleranzen ausführen. Diese Pods werden als "reguläre Pods" bezeichnet, um sie von Pods zu unterscheiden, die in einer Sandbox ausgeführt werden.

Reguläre Pods haben wie Sandbox-Pods keinen Zugriff auf andereGoogle Cloud -Dienste oder Clustermetadaten. Dieser Schutz ist Teil der Knotenkonfiguration. Wenn die regulären Pods oder Pods, die in einer Sandbox ausgeführt werden, Zugriff aufGoogle Cloud -Dienste benötigen, verwenden Sie die Workload Identity-Föderation für GKE.

GKE Sandbox fügt Knoten, die in einer Sandbox ausgeführte Pods ausführen können, das folgende Label und die folgende Markierung hinzu:

  • Das Knotenlabel sandbox.gke.io/runtime: SANDBOX_TYPE.
  • Die sandbox.gke.io/runtime=SANDBOX_TYPE:NoSchedule-Knotenmarkierung. Nur Pods mit einer übereinstimmenden Toleranz können auf dem Knoten geplant werden.

Wenn Sie das Feld RuntimeClass verwenden, um einen Pod in einer Sandbox auszuführen, wendet GKE automatisch eine Knotenaffinität und eine Toleranz auf den Pod an. Wenn Sie einen regulären Pod auf einem Knoten ausführen möchten, der GKE Sandbox verwendet, müssen Sie die folgenden Selektoren manuell auf die Pod-Spezifikation anwenden:

  • Wenn Sie möchten, dass Ihr Pod bei Bedarf auf Knoten ausgeführt wird, die GKE Sandbox verwenden, fügen Sie nur die Toleranz für die Knotenmarkierung hinzu.
  • Wenn Sie Ihren Pod nur auf Knoten ausführen möchten, die GKE Sandbox verwenden, fügen Sie einen Knotenselektor und die Toleranz für die Knotenmarkierung hinzu.

In den folgenden Schritten wird gezeigt, wie Sie einen regulären Pod auf einem Knoten ausführen, der GKE Sandbox verwendet:

  1. Speichern Sie das folgende Deployment-Manifest als httpd-regular.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpd-regular
      labels:
        app: httpd-regular
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpd-regular
      template:
        metadata:
          labels:
            app: httpd-regular
        spec:
          containers:
          - name: httpd-regular
            image: httpd
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: sandbox.gke.io/runtime
                    operator: In
                    values:
                    - SANDBOX_TYPE
          tolerations:
            - effect: NoSchedule
              key: sandbox.gke.io/runtime
              operator: Equal
              value: SANDBOX_TYPE
    

    Ersetzen Sie SANDBOX_TYPE durch den Sandbox-Typ, z. B. gvisor oder microvm.

  2. Erstellen Sie das Deployment:

    kubectl apply -f httpd-regular.yaml
    

    Wenn der Pod nicht planbar ist, prüfen Sie, ob die Knotenaffinität und die Toleranz im Pod-Manifest richtig festgelegt sind.

  3. Prüfen Sie, ob sich der Pod in einer Sandbox befindet:

    kubectl get pods -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'
    

    Die Ausgabe sieht etwa so aus:

    httpd-db5899bc9-dk7lk: SANDBOX_TYPE
    httpd-regular-5bf87996c6-cfmmd:
    

    Der httpd-regular-Pod hat keinen RuntimeClass-Wert, was bedeutet, dass sich der Pod nicht in einer Sandbox befindet.

  4. Prüfen Sie, ob der reguläre Pod auf einem Knoten ausgeführt wird, der GKE Sandbox verwendet:

    kubectl get pod -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.nodeName}\n{end}'
    

    Die Ausgabe sieht etwa so aus:

    httpd-db5899bc9-dk7lk: gke-cluster-2-pool-1-75c8fc63-h373
    httpd-regular-5bf87996c6-cfmmd: gke-cluster-2-pool-1-75c8fc63-h373
    

    Sowohl der Pod, der in einer Sandbox ausgeführt wird, als auch der reguläre Pod befinden sich auf demselben Knoten. Das bedeutet, dass der reguläre Pod auf einem Knoten ausgeführt wird, der GKE Sandbox verwendet.

Sandbox-Konfiguration prüfen

In den folgenden Abschnitten erfahren Sie, wie Sie überprüfen, ob ein Pod in einer Sandbox ausgeführt wird und ob der Sandbox-Pod vom Hostkernel isoliert ist. In diesen Abschnitten wird davon ausgegangen, dass Sie das Beispiel-Deployment in Sandbox-Umgebung für einen Pod anfordern erstellt haben.

Prüfen, ob ein Pod in einer Sandbox ausgeführt wird

Wenn Sie prüfen möchten, ob Ihre Pods eine Sandbox verwenden, rufen Sie die RuntimeClass der Pods ab. Diese Methode ist vertrauenswürdiger als das Ausführen eines Befehls im Pod, da Sie keine Daten aus der Sandbox selbst sehen. Alle aus der Sandbox gemeldeten Daten sind nicht vertrauenswürdig, da sie fehlerhaft sein oder aus böswilligen Aktivitäten stammen können.

  • Rufen Sie die RuntimeClass jedes ausgeführten Pods ab:

    kubectl get pods -l=app=httpd -o jsonpath=$'{range .items[*]}{.metadata.name}: {.spec.runtimeClassName}\n{end}'
    

    Die Ausgabe sieht etwa so aus:

    httpd-db5899bc9-dk7lk: gvisor
    httpd-db5899bc9-ab3cd: gvisor
    

    Wenn in der Ausgabe gvisor oder microvm angezeigt wird, wird der Pod in einer Sandbox ausgeführt.

Isolation von Sandbox-Pods vom Host prüfen

Sie können prüfen, ob ein Sandbox-Pod vom Hostknoten isoliert ist, indem Sie die verfügbaren virtuellen Geräte und die Version des Kernels prüfen, auf die der Pod zugreifen kann.

  1. Prüfen Sie für gVisor- und MicroVM-Sandboxes, ob sich die Kernel-Version, auf die der Pod zugreifen kann, von der Kernel-Version des Hostknotens unterscheidet:

    1. Rufen Sie die Version des Kernels ab, auf den der Pod zugreifen kann:

      kubectl exec POD_NAME -- uname -r
      

      Ersetzen Sie POD_NAME durch den Namen des Pods.

      Die Ausgabe sieht etwa so aus:

      4.19.0-gvisor
      
    2. Rufen Sie die Version des Kernels auf dem Hostknoten ab:

      kubectl get node NODE_NAME \
          -o jsonpath='{.status.nodeInfo.kernelVersion}'
      

      Ersetzen Sie NODE_NAME durch den Namen des Knotens, auf dem der Pod ausgeführt wird.

      Die Ausgabe sieht etwa so aus:

      6.12.94+
      

    Die Kernel-Version des Hostknotens unterscheidet sich von der Kernel-Version, auf die der Sandbox-Pod zugreifen kann, da der Pod nur den Userspace-Kernel für gVisor oder den Gast-Kernel für Micro-VMs sieht.

  2. Bei MicroVM-Sandboxes können Sie auch prüfen, ob die Geräte, auf die der Pod zugreifen kann, von Cloud Hypervisor virtualisiert werden:

    kubectl exec POD_NAME -- cat /sys/class/dmi/id/product_name
    

    Wenn die Ausgabe cloud-hypervisor ist, befindet sich der Pod in einer MicroVM-Sandbox.

GKE Sandbox deaktivieren

Sie können GKE Sandbox nicht in GKE Autopilot-Clustern oder GKE Standard-Knotenpools deaktivieren. Wenn Sie GKE Sandbox nicht mehr verwenden möchten, löschen Sie den Knotenpool.

Nächste Schritte