Arbeitslasten in dedizierten Knotenpools isolieren


Auf dieser Seite erfahren Sie, wie Sie das Risiko von Angriffen zur Eskalation von Berechtigungen in Ihrem Cluster verringern können, indem Sie Google Kubernetes Engine (GKE) anweisen, Ihre Arbeitslasten auf einem separaten, dedizierten Knotenpool zu planen, der von privilegierten, von GKE verwalteten Arbeitslasten getrennt ist. Diese Seite gilt für Standardcluster ohne automatische Knotenbereitstellung. Informationen zum Trennen von Arbeitslasten in Autopilot-Clustern und in Standardclustern mit aktivierter automatischer Knotenbereitstellung finden Sie unter Arbeitslasttrennung in GKE konfigurieren.

Überblick

GKE-Cluster verwenden privilegierte GKE-verwaltete Arbeitslasten, um bestimmte Clusterfunktionen und -features wie das Erfassen von Messwerten zu aktivieren. Diese Arbeitslasten haben spezielle Berechtigungen, damit sie ordnungsgemäß im Cluster ausgeführt werden können.

Arbeitslasten, die Sie auf Ihren Knoten bereitstellen, können möglicherweise von einer bösartigen Entität kompromittiert werden. Die Ausführung dieser Arbeitslasten neben privilegierten, von GKE verwalteten Arbeitslasten bedeutet, dass ein Angreifer, der aus einem kompromittierten Container ausbricht, die Anmeldeinformationen der privilegierten Arbeitslast auf dem Knoten verwenden kann, um die Privilegien in Ihrem Cluster zu erweitern.

Container-Aufschlüsselungen verhindern

Ihre primäre Verteidigung sollte Ihre Anwendungen sein. GKE bietet mehrere Features, mit denen Sie Ihre Cluster und Pods härten können. In den meisten Fällen empfehlen wir dringend die Verwendung von GKE Sandbox, um Ihre Arbeitslasten zu isolieren. GKE Sandbox basiert auf dem Open Source-Projekt gVisor und implementiert die Linux Kernel API im Nutzerbereich. Jeder Pod wird auf einem dedizierten Kernel ausgeführt, der Anwendungen in einer Sandbox ausführt, um den Zugriff auf privilegierte Systemaufrufe im Host-Kernel zu verhindern. In GKE Sandbox ausgeführte Arbeitslasten werden automatisch auf separaten Knoten geplant, die von anderen Arbeitslasten isoliert sind.

Folgen Sie den Empfehlungen unter Sicherheit Ihres Clusters erhöhen.

Angriffe auf die Rechteausweitung vermeiden

Wenn Sie die GKE-Sandbox nicht verwenden können und zusätzlich zu anderen Härtungsmaßnahmen eine zusätzliche Isolationsebene wünschen, können Sie Knotenmarkierungen und Knotenaffinität verwenden, um Ihre Arbeitslasten auf einem dedizierten Knotenpool zu planen. Eine Knotenmarkierung weist GKE an, Arbeitslasten ohne entsprechende Toleranz (wie von GKE verwaltete Arbeitslasten) nicht auf diesen Knoten einzuplanen. Die Knotenaffinität für Ihre eigenen Arbeitslasten weist GKE an, Ihre Pods auf den dedizierten Knoten zu planen.

Einschränkungen der Knotenisolation

  • Angreifer können weiterhin DoS-Angriffe (Denial of Service) über den manipulierten Knoten initiieren.
  • Manipulierte Knoten können weiterhin viele Ressourcen lesen, einschließlich aller Pods und Namespaces im Cluster.
  • Manipulierte Knoten können auf Secrets und Anmeldedaten zugreifen, die von jedem auf diesem Knoten ausgeführten Pod verwendet werden.
  • Wenn Sie einen separaten Knotenpool verwenden, um Ihre Arbeitslasten zu isolieren, kann sich dies auf die Kosteneffizienz, das Autoscaling und die Ressourcennutzung auswirken.
  • Gefährdete Knoten können weiterhin Netzwerkrichtlinien für ausgehenden Traffic umgehen.
  • Einige von GKE verwaltete Arbeitslasten müssen auf jedem Knoten in Ihrem Cluster ausgeführt werden und so konfiguriert sein, dass sie alle Markierungen tolerieren.
  • Wenn Sie DaemonSets bereitstellen, die erhöhte Berechtigungen haben und jede Markierung tolerieren können, sind diese Pods möglicherweise ein Pfad für die Rechteausweitung von einem manipulierten Knoten.

Funktionsweise der Knotenisolation

So implementieren Sie die Knotenisolation für Ihre Arbeitslasten:

  1. Markieren Sie einen Knotenpool für Ihre Arbeitslasten und versehen Sie ihn mit einem Label.
  2. Aktualisieren Sie Ihre Arbeitslasten mit der entsprechenden Toleranz- und Knotenaffinitätsregel.

In dieser Anleitung wird davon ausgegangen, dass Sie mit einem Knotenpool in Ihrem Cluster beginnen. Die Verwendung der Knotenaffinität ist neben Knotenmarkierungen nicht obligatorisch, es wird jedoch empfohlen, da Sie von einer besseren Kontrolle über die Planung profitieren.

Vorbereitung

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.
  • Wählen Sie einen bestimmten Namen für die Knotenmarkierung und das Knotenlabel aus, das Sie für die dedizierten Knotenpools verwenden möchten. In diesem Beispiel verwenden wir workloadType=untrusted.

Knotenpool für Arbeitslasten markieren und mit Labels versehen

Erstellen Sie einen neuen Knotenpool für Ihre Arbeitslasten und wenden Sie eine Knotenmarkierung und ein Knotenlabel an. Wenn Sie eine Markierung oder ein Label auf Knotenpoolebene anwenden, erhalten neue Knoten, beispielsweise solche, die durch Autoscaling erstellt werden, automatisch die angegebenen Markierungen und Labels.

Sie können vorhandenen Knotenpools auch Knotenmarkierungen und Knotenlabels hinzufügen. Wenn Sie den Effekt NoExecute verwenden, entfernt GKE alle Pods, die auf diesen Knoten ausgeführt werden und keine Toleranz für die neue Markierung haben.

Führen Sie den folgenden Befehl aus, um einem neuen Knotenpool eine Markierung und ein Label hinzuzufügen:

gcloud container node-pools create POOL_NAME \
    --cluster CLUSTER_NAME \
    --node-taints TAINT_KEY=TAINT_VALUE:TAINT_EFFECT \
    --node-labels LABEL_KEY=LABEL_VALUE

Dabei gilt:

  • POOL_NAME ist der Name des neuen Knotenpools für Ihre Arbeitslasten.
  • CLUSTER_NAME: Name Ihres GKE-Clusters.
  • TAINT_KEY=TAINT_VALUE: ein Schlüssel/Wert-Paar, das mit einem TAINT_EFFECT-Zeitplan verknüpft ist. Beispiel: workloadType=untrusted.
  • TAINT_EFFECT: einer der folgenden Effektwerte: NoSchedule, PreferNoSchedule oder NoExecute. NoExecute bietet eine bessere Bereinigungsgarantie als NoSchedule.
  • LABEL_KEY=LABEL_VALUE: Schlüssel/Wert-Paare für die Knotenlabels, die den Selektoren entsprechen, die Sie in Ihren Arbeitslastmanifesten angeben.

Toleranz und Knotenaffinitätsregel zu Arbeitslasten hinzufügen

Nachdem Sie den dedizierten Knotenpool markiert haben, können keine Arbeitslasten darin geplant werden, es sei denn, sie haben eine Toleranz, die der hinzugefügten Markierung entspricht. Fügen Sie der Spezifikation Ihrer Arbeitslasten die Toleranz hinzu, damit diese Pods im markierten Knotenpool geplant werden können.

Wenn Sie den dedizierten Knotenpool mit einem Label versehen haben, können Sie auch eine Knotenaffinitätsregel hinzufügen, um GKE anzuweisen, Ihre Arbeitslasten nur in diesem Knotenpool zu planen.

Im folgenden Beispiel wird eine Toleranz für die Markierung workloadType=untrusted:NoExecute und eine Knotenaffinitätsregel für das Knotenlabel workloadType=untrusted hinzugefügt.

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-app
  namespace: default
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      tolerations:
      - key: TAINT_KEY
        operator: Equal
        value: TAINT_VALUE
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: LABEL_KEY
                operator: In
                values:
                - "LABEL_VALUE"
      containers:
      - name: sleep
        image: ubuntu
        command: ["/bin/sleep", "inf"]

Ersetzen Sie Folgendes:

  • TAINT_KEY: Der Markierungsschlüssel, den Sie auf Ihren dedizierten Knotenpool angewendet haben.
  • TAINT_VALUE: Markierungswert, den Sie auf Ihren dedizierten Knotenpool angewendet haben.
  • LABEL_KEY ist der Knotenlabelschlüssel, den Sie auf Ihren dedizierten Knotenpool angewendet haben.
  • LABEL_VALUE: der Wert des Knotenlabels, den Sie auf Ihren dedizierten Knotenpool angewendet haben.

Wenn Sie Ihre Bereitstellung mit kubectl apply aktualisieren, erstellt GKE die betroffenen Pods neu. Die Knotenaffinitätsregel erzwingt die Pods für den von Ihnen erstellten dedizierten Knotenpool. Die Toleranz erlaubt es, nur diese Pods auf den Knoten zu platzieren.

Prüfen, ob die Trennung funktioniert

Führen Sie den folgenden Befehl aus und prüfen Sie, ob sich Ihre Arbeitslasten im dedizierten Knotenpool befinden, um zu prüfen, ob die Planung ordnungsgemäß funktioniert:

kubectl get pods -o=wide

Empfehlungen und Best Practices

Nachdem Sie die Knotenisolation eingerichtet haben, sollten Sie Folgendes tun:

  • Beschränken Sie bestimmte Knotenpools auf von GKE verwaltete Arbeitslasten. Fügen Sie dazu die Markierung components.gke.io/gke-managed-components hinzu. Durch Hinzufügen dieser Markierung wird verhindert, dass Ihre eigenen Pods auf diesen Knoten geplant werden, um die Isolation zu verbessern.
  • Verhindern Sie beim Erstellen neuer Knotenpools, dass die meisten von GKE verwalteten Arbeitslasten auf diesen Knoten ausgeführt werden. Fügen Sie dazu diesen Knotenpools eine eigene Markierung hinzu.
  • Prüfen Sie bei der Bereitstellung neuer Arbeitslasten in Ihrem Cluster, z. B. bei der Installation von Drittanbietertools, die Berechtigungen, die die Pods benötigen. Vermeiden Sie nach Möglichkeit die Bereitstellung von Arbeitslasten, die erhöhte Berechtigungen für gemeinsam genutzte Knoten verwenden.

Nächste Schritte