Isolierung von Arbeitslasten mit GKE Sandbox härten


Auf dieser Seite wird beschrieben, wie Sie mit GKE Sandbox den Hostkernel auf Ihren Knoten schützen, wenn Container unbekannten oder nicht vertrauenswürdigen Code im Pod ausführen.

Verfügbarkeit von GKE Sandbox

GKE Sandbox kann in Autopilot-Clustern mit GKE-Version 1.27.4-gke.800 und höher verwendet werden. Fahren Sie mit Mit GKE Sandbox arbeiten fort, um mit dem Bereitstellen von Autopilot-Arbeitslasten in einer Sandbox zu beginnen.

Wenn Sie GKE Sandbox in neuen oder vorhandenen GKE Standardclustern verwenden möchten, müssen Sie die GKE Sandbox manuell im Cluster aktivieren.

GPU-Arbeitslasten werden in GKE Sandbox ab Version 1.29.2-gke.11080000 unterstützt.

Hinweise

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 gcloud components update ab.

GKE Sandbox in einem neuen Standardcluster aktivieren

Der Standardknotenpool, der bei der Erstellung eines neuen Clusters erstellt wird, kann GKE Sandbox nicht verwenden, wenn er der einzige Knotenpool im Cluster ist, da von GKE verwaltete Systemarbeitslasten getrennt von nicht vertrauenswürdigen Sandbox-Arbeitslasten ausgeführt werden müssen. Um GKE Sandbox während der Clustererstellung zu aktivieren, müssen Sie dem Cluster mindestens einen zusätzlichen Knotenpool hinzufügen.

Console

Rufen Sie zum Anzeigen Ihrer Cluster in der Google Cloud Console das Kubernetes Engine-Menü auf.

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

    Zur Seite „Google Kubernetes Engine“

  2. Klicken Sie auf Erstellen.

  3. Optional, aber empfohlen: Klicken Sie im Navigationsmenü unter Cluster auf Features und aktivieren Sie die folgenden Kästchen, damit gVisor Nachrichten werden protokolliert:

    • Cloud Logging
    • Cloud Monitoring
    • Verwalteter Dienst für Prometheus
  4. Klicken Sie auf Knotenpool hinzufügen .

  5. Erweitern Sie im Navigationsmenü unter Knotenpools den neuen Knotenpool und klicken Sie auf Knoten.

  6. Konfigurieren Sie den Knotenpool mit folgenden Einstellungen:

    1. Wählen Sie in der Drop-down-Liste Image-Typ die Option Container-Optimized OS mit "Containerd" (cos_containerd) aus. Dies ist der einzige unterstützte Image-Typ für GKE Sandbox.
    2. Wählen Sie unter Maschinenkonfiguration eine Reihe und einen Maschinentyp aus.
    3. Wenn Sie eine unterstützte GKE-Version ausführen, wählen Sie einen GPU-Typ aus. Dies muss einer der folgenden Werte sein:
      • nvidia-tesla-t4
      • nvidia-tesla-a100
      • nvidia-a100-80gb
      • nvidia-l4
      • nvidia-h100-80gb
    4. Wenn Sie GPUs in GKE Sandbox verwenden, wählen Sie die Treibervariante latest aus oder installieren Sie sie.
  7. Klicken Sie im Navigationsmenü unter dem Namen des Knotenpools, den Sie konfigurieren, auf Sicherheit und klicken Sie dann auf das Kästchen Sandbox mit gVisor aktivieren.

  8. Konfigurieren Sie den Cluster und die Knotenpools weiter nach Bedarf.

  9. Klicken Sie auf Erstellen.

gcloud

GKE Sandbox kann nicht für den Standardknotenpool aktiviert werden. Außerdem ist es nicht möglich, beim Erstellen eines neuen Clusters mit dem Befehl gcloud gleichzeitig zusätzliche Knotenpools zu erstellen. Gehen Sie zum Erstellen des Clusters stattdessen wie gewohnt vor. Wir empfehlen Ihnen, Logging und Monitoring zu aktivieren, damit gVisor-Meldungen protokolliert werden.

Verwenden Sie als Nächstes den Befehl gcloud container node-pools create und legen Sie das Flag -- sandbox auf type=gvisor fest. Der Knoten-Image-Typ muss cos_containerd für GKE Sandbox sein.

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=gvisor

Ersetzen Sie die folgenden Variablen:

  • NODE_POOL_NAME ist der Name des neuen Knotenpools.
  • CLUSTER_NAME: Der Name Ihres Clusters.
  • NODE_VERSION ist die Version, die für den Knotenpool verwendet werden soll.
  • MACHINE_TYPE: Der für die Knoten zu verwendende Maschinentyp.

Führen Sie zum Erstellen eines GPU-Knotenpools mit GKE Sandbox den folgenden Befehl aus:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=latest \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Ersetzen Sie Folgendes:

GKE Sandbox in einem vorhandenen Standardcluster aktivieren

Sie können GKE Sandbox in einem vorhandenen Standard-Cluster aktivieren. Dazu fügen Sie einen neuen Knotenpool hinzu und aktivieren das Feature für diesen Knotenpool.

Console

So erstellen Sie einen neuen Knotenpool mit aktiviertem GKE Sandbox:

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

    Zur Seite "Google Kubernetes Engine"

  2. Klicken Sie auf den Namen des Clusters, den Sie ändern möchten.

  3. Klicken Sie auf Knotenpool hinzufügen .

  4. Konfigurieren Sie die Seite Knotenpooldetails nach Bedarf.

  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. Dies ist der einzige unterstützte Image-Typ für GKE Sandbox.
    2. Wählen Sie unter Maschinenkonfiguration eine Reihe und einen Maschinentyp aus.
    3. Wenn Sie eine unterstützte GKE-Version ausführen, wählen Sie einen GPU-Typ aus. Dies muss einer der folgenden Werte sein:
      • nvidia-tesla-t4
      • nvidia-tesla-a100
      • nvidia-a100-80gb
      • nvidia-l4
      • nvidia-h100-80gb
    4. Wenn Sie GPUs in GKE Sandbox verwenden, wählen Sie die Treibervariante latest aus oder installieren Sie sie.
  6. Klicken Sie im Navigationsmenü auf Sicherheit und dann auf das Kästchen Sandbox mit gVisor aktivieren.

  7. Klicken Sie auf Erstellen.

gcloud

Verwenden Sie zum Erstellen eines neuen Knotenpools mit aktiviertem GKE Sandbox einen Befehl wie den folgenden:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --machine-type=MACHINE_TYPE \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Der Knoten-Image-Typ muss cos_containerd für GKE Sandbox sein.

Führen Sie zum Erstellen eines GPU-Knotenpools mit GKE Sandbox den folgenden Befehl aus:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=latest \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Ersetzen Sie Folgendes:

Optional: Monitoring und Logging aktivieren

Optional empfiehlt es sich, Cloud Logging und Cloud Monitoring auf dem Cluster zu aktivieren, damit gVisor-Meldungen protokolliert werden. Diese Dienste sind für neue Cluster standardmäßig aktiviert.

Sie können die Google Cloud Console verwenden, um diese Features auf einem vorhandenen Cluster zu aktivieren.

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

    Zur Seite "Google Kubernetes Engine"

  2. Klicken Sie auf den Namen des Clusters, den Sie ändern möchten.

  3. Klicken Sie unter Features im Feld Cloud Logging auf Cloud Logging bearbeiten.

  4. Klicken Sie das Kästchen Cloud Logging aktivieren an.

  5. Klicken Sie auf Änderungen speichern.

  6. Wiederholen Sie dieselben Schritte für die Felder Cloud Monitoring und Managed Service for Prometheus, um diese Features zu aktivieren.

GKE Sandbox in Autopilot und Standard verwenden

In Autopilot-Clustern und Standard-Clustern mit aktivierter GKE Sandbox fordern Sie eine Sandbox-Umgebung für einen Pod an. Geben Sie dazu die RuntimeClass gvisor in der Pod-Spezifikation an.

Für Autopilot-Cluster benötigen Sie die GKE-Version 1.27.4-gke.800 oder höher.

Anwendung in einer Sandbox ausführen

Damit ein Deployment auf einem Knoten mit aktivierter GKE Sandbox ausgeführt wird, legen Sie für spec.template.spec.runtimeClassName den Wert gvisor fest, wie im folgenden Beispiel gezeigt:

# httpd.yaml
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: gvisor
      containers:
      - name: httpd
        image: httpd

Erstellen Sie das Deployment:

kubectl apply -f httpd.yaml

Der Pod wird auf einem Knoten mit aktivierter GKE Sandbox bereitgestellt. Suchen Sie zum Prüfen der Bereitstellung den Knoten, auf dem der Pod bereitgestellt wird:

kubectl get pods

Die Ausgabe sieht in etwa so aus:

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

Suchen Sie in der Ausgabe den Namen des Pods und prüfen Sie dann den Wert für RuntimeClass:

kubectl get pods POD_NAME -o jsonpath='{.spec.runtimeClassName}'

Die Ausgabe lautet gvisor.

Alternativ können Sie die RuntimeClass eines jeden Pods auflisten und nach den Pods suchen, die auf gvisor festgelegt sind:

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

Die Ausgabe sieht so aus:

POD_NAME: gvisor

Diese Methode zur Prüfung des Pods auf Ausführung in einer Sandbox ist vertrauenswürdig, da sie sich nicht auf Daten aus der Sandbox selbst stützt. Alle aus der Sandbox gemeldeten Daten sind nicht vertrauenswürdig, da sie fehlerhaft sein oder aus böswilligen Aktivitäten stammen können.

Pod mit GPUs in GKE Sandbox ausführen

Zum Ausführen einer GPU-Arbeitslast in GKE Sandbox fügen Sie Ihrem Manifest wie in den folgenden Beispielen das Feld runtimeClassName: gvisor hinzu:

  • Beispielmanifest für GPU-Pods im Standardmodus:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      containers:
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
          nvidia.com/gpu: 1
    
  • Beispielmanifest für GPU-Pods im Autopilot-Modus:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      nodeSelector:
        cloud.google.com/compute-class: "Accelerator"
        cloud.google.com/gke-accelerator: nvidia-tesla-t4
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
            nvidia.com/gpu: 1
    

Sie können alle GPU-Pods im Autopilot- oder Standard-Modus ausführen, die die Anforderungen für Version und GPU-Typ in GKE Sandbox erfüllen, indem Sie dem Manifest das Feld runtimeClassName: gvisor hinzufügen. Eine Anleitung zum Ausführen von GPU-Pods in GKE finden Sie in den folgenden Ressourcen:

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.

Wie Pods, die in einer Sandbox ausgeführt werden, werden auch reguläre Pods daran gehindert, auf andere Google Cloud-Dienste oder Clustermetadaten zuzugreifen. Dieser Schutz ist Teil der Knotenkonfiguration. Wenn die regulären Pods oder Pods, die in einer Sandbox ausgeführt werden, Zugriff auf Google 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:

labels:
  sandbox.gke.io/runtime: gvisor
taints:
- effect: NoSchedule
  key: sandbox.gke.io/runtime
  value: gvisor

Neben Einstellungen für die Knotenaffinität und -toleranz im Pod-Manifest wendet GKE Sandbox die folgende Knotenaffinität und -toleranz auf alle Pods an, für die RuntimeClass auf gvisor festgelegt ist:

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: sandbox.gke.io/runtime
          operator: In
          values:
          - gvisor
tolerations:
  - effect: NoSchedule
    key: sandbox.gke.io/runtime
    operator: Equal
    value: gvisor

Wenn Sie einen regulären Pod auf einem Knoten mit aktivierter GKE Sandbox planen möchten, wenden Sie die beschrieben Knotenaffinität und -toleranz manuell in Ihrem Pod-Manifest an.

  • Wenn Ihr Pod auf Knoten mit aktivierter GKE Sandbox ausgeführt werden kann, fügen Sie die Toleranz hinzu.
  • Wenn Ihr Pod auf Knoten mit aktivierter GKE Sandbox ausgeführt werden muss, fügen Sie sowohl die Knotenaffinität als auch die Toleranz hinzu.

Das folgende Manifest ändert beispielsweise das unter Anwendung in einer Sandbox ausführen verwendete Manifest so, dass die Ausführung als regulärer Pod auf einem Knoten mit Pods erfolgt, die in einer Sandbox ausgeführt werden. Dafür wird die RuntimeClass entfernt und die beschriebene Markierung und Toleranz werden hinzugefügt:

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

Prüfen Sie zuerst, ob das Deployment in einer Sandbox ausgeführt wird:

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

Die Ausgabe sieht etwa so aus:

httpd-db5899bc9-dk7lk: gvisor
httpd-no-sandbox-5bf87996c6-cfmmd:

Das zuvor erstellte httpd-Deployment wird in einer Sandbox ausgeführt, da seine RuntimeClass gvisor ist. Das httpd-no-sandbox-Deployment hat dagegen keinen Wert für RuntimeClass und wird somit nicht in einer Sandbox ausgeführt.

Prüfen Sie als Nächstes, ob das Deployment ohne Sandbox auf einem Knoten mit GKE Sandbox ausgeführt wird. Führen Sie dazu folgenden Befehl aus:

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

Der Name des Knotenpools ist in den Wert von nodeName eingebettet. Prüfen Sie, ob der Pod auf einem Knoten in einem Knotenpool mit aktivierter GKE Sandbox ausgeführt wird.

Metadatenschutz prüfen

Durch Ausführen eines Tests können Sie validieren, dass Metadaten vor Knoten geschützt sind, die Pods in einer Sandbox ausführen können:

  1. Erstellen Sie mithilfe von kubectl apply -f über das folgende Manifest ein Deployment, das in einer Sandbox ausgeführt wird. Dabei wird das fedora-Image verwendet, das den curl-Befehl enthält. Der Pod führt den Befehl /bin/sleep aus, damit das Deployment 10.000 Sekunden lang ausgeführt wird:

    # sandbox-metadata-test.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: fedora
      labels:
        app: fedora
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: fedora
      template:
        metadata:
          labels:
            app: fedora
        spec:
          runtimeClassName: gvisor
          containers:
          - name: fedora
            image: fedora
            command: ["/bin/sleep","10000"]
    
  2. Rufen Sie den Namen des Pods mithilfe von kubectl get pods ab und verwenden Sie dann kubectl exec, um eine interaktive Verbindung zum Pod herzustellen:

    kubectl exec -it POD_NAME /bin/sh
    

    Sie sind in einer /bin/sh-Sitzung mit einem Container verbunden, der im Pod ausgeführt wird.

  3. Versuchen Sie in der interaktiven Sitzung, auf eine URL zuzugreifen, die Clustermetadaten zurückgibt:

    curl -s "http://169.254.169.254/computeMetadata/v1/instance/attributes/kube-env" -H "Metadata-Flavor: Google"
    

    Der Befehl bleibt hängen und führt letztendlich zu einer Zeitüberschreitung, da die Pakete ohne Rückmeldung verworfen werden.

  4. Drücken Sie Strg + C, um den curl-Befehl zu beenden, und geben Sie exit ein, um die Verbindung zum Pod zu trennen.

  5. Entfernen Sie die Zeile RuntimeClass aus dem YAML-Manifest und stellen Sie den Pod mit kubectl apply -f FILENAME noch einmal bereit. Der in einer Sandbox ausgeführte Pod wird beendet und auf einem Knoten ohne GKE Sandbox neu erstellt.

  6. Rufen Sie den Namen des neuen Pods ab, stellen Sie mithilfe von kubectl exec eine Verbindung zu ihm her und führen Sie den curl-Befehl noch einmal aus. Diesmal werden Ergebnisse zurückgegeben. Diese Beispielausgabe ist gekürzt:

    ALLOCATE_NODE_CIDRS: "true"
    API_SERVER_TEST_LOG_LEVEL: --v=3
    AUTOSCALER_ENV_VARS: kube_reserved=cpu=60m,memory=960Mi,ephemeral-storage=41Gi;...
    ...
    

    Geben Sie exit ein, um die Verbindung zum Pod zu trennen.

  7. Entfernen Sie das Deployment:

    kubectl delete deployment fedora
    

GKE Sandbox deaktivieren

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

Nächste Schritte