Isola i carichi di lavoro in pool di nodi dedicati

Questa pagina mostra come ridurre il rischio di attacchi di escalation dei privilegi nel tuo cluster configurando GKE su AWS per pianificare i carichi di lavoro su un pool di nodi dedicato e separato, lontano dai carichi di lavoro gestiti con privilegi.

Panoramica

GKE su cluster AWS utilizzano carichi di lavoro con privilegi che gestiamo per abilitare funzionalità e caratteristiche specifiche di cluster, come la raccolta di metriche. A questi carichi di lavoro vengono concesse autorizzazioni speciali per essere eseguite correttamente nel cluster.

I carichi di lavoro di cui esegui il deployment nei tuoi nodi potrebbero essere compromessi da un'entità dannosa. L'esecuzione di questi carichi di lavoro insieme a carichi di lavoro di sistema con privilegi significa che un utente malintenzionato che esce da un container compromesso può utilizzare le credenziali del carico di lavoro con privilegi sul nodo per riassegnare i privilegi nel cluster.

Prevenzione dei gruppi di lavoro

La tua difesa principale dovrebbe essere le tue applicazioni. GKE su AWS offre varie funzionalità che consentono di proteggere i cluster e i pod. Nella maggior parte dei casi, consigliamo vivamente di utilizzare Policy Controller e le funzionalità di sicurezza del kernel per proteggere i carichi di lavoro. Per ulteriori consigli sulla sicurezza, consulta la Panoramica sulla sicurezza.

Evitare attacchi di escalation dei privilegi

Se vuoi un ulteriore livello di isolamento oltre ad altre misure di protezione, puoi utilizzare le incompatibilità dei nodi e l'affinità dei nodi per pianificare i tuoi carichi di lavoro su un pool di nodi dedicato.

Un'incompatibilità dei nodi indica a GKE su AWS di evitare la pianificazione dei carichi di lavoro senza una tolleranza corrispondente (come GKE su carichi di lavoro gestiti da AWS) su quei nodi. L'affinità dei nodi sui tuoi carichi di lavoro indica a GKE su AWS di pianificare i pod sui nodi dedicati.

Limitazioni dell'isolamento dei nodi

  • Gli aggressori possono comunque avviare attacchi DoS (Denial of Service) dal nodo compromesso.
  • I nodi compromessi possono ancora leggere molte risorse, inclusi tutti i pod e gli spazi dei nomi nel cluster.
  • I nodi compromessi possono accedere ai secret e alle credenziali utilizzate da ogni pod in esecuzione su quel nodo.
  • L'utilizzo di un pool di nodi separato per isolare i carichi di lavoro può influire sull'efficienza dei costi, sulla scalabilità automatica e sull'utilizzo delle risorse.
  • I nodi compromessi possono comunque bypassare i criteri di rete in uscita.
  • Alcuni carichi di lavoro GKE su carichi di lavoro gestiti da AWS devono essere eseguiti su ogni nodo del cluster e sono configurati in modo da tollerare tutte le incompatibilità.
  • Se esegui il deployment di DaemonSet che hanno autorizzazioni elevate e possono tollerare qualsiasi incompatibilità, questi pod potrebbero essere un percorso per l'escalation dei privilegi da un nodo compromesso.

Come funziona l'isolamento dei nodi

Per implementare l'isolamento dei nodi per i carichi di lavoro:

  1. Controlla ed etichetta un pool di nodi per i tuoi carichi di lavoro.
  2. Aggiorna i carichi di lavoro con la tolleranza e la regola di affinità dei nodi corrispondenti.

Questa guida presuppone di iniziare con un pool di nodi nel tuo cluster. L'utilizzo dell'affinità dei nodi oltre alle incompatibilità dei nodi non è obbligatorio, ma lo consigliamo perché puoi beneficiare di un maggiore controllo sulla pianificazione.

Prima di iniziare

Per seguire i passaggi descritti in questa pagina, devi prima completare le seguenti operazioni:

Controlla ed etichetta un pool di nodi per i carichi di lavoro

Crea un nuovo pool di nodi per i tuoi carichi di lavoro e applica un'incompatibilità dei nodi e un'etichetta dei nodi. Quando applichi un'incompatibilità o un'etichetta a livello di pool di nodi, tutti i nuovi nodi, come quelli creati con la scalabilità automatica, riceveranno automaticamente le incompatibilità e le etichette specificate.

Puoi anche aggiungere incompatibilità dei nodi ed etichette dei nodi ai pool di nodi esistenti. Se utilizzi l'effetto NoExecute, GKE su AWS rimuove tutti i pod in esecuzione su quei nodi che non tollerano la nuova incompatibilità.

Per aggiungere un'incompatibilità e un'etichetta a un nuovo pool di nodi, esegui questo comando:

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

Sostituisci quanto segue:

  • POOL_NAME: il nome del nuovo pool di nodi per i carichi di lavoro.
  • CLUSTER_NAME: il nome del tuo GKE su cluster AWS.
  • TAINT_KEY=TAINT_VALUE: una coppia chiave-valore associata a una TAINT_EFFECT di pianificazione. Ad esempio, workloadType=untrusted.
  • TAINT_EFFECT: uno dei seguenti valori effetto: NoSchedule, PreferNoSchedule o NoExecute. NoExecute offre una garanzia di rimozione migliore rispetto a NoSchedule.
  • LABEL_KEY=LABEL_VALUE: coppie chiave-valore per le etichette dei nodi, che corrispondono ai selettori specificati nei manifest del carico di lavoro.

Aggiungi una tolleranza e una regola di affinità dei nodi ai tuoi carichi di lavoro

Dopo l'incompatibilità con il pool di nodi dedicato, nessun carico di lavoro può eseguire la pianificazione su di esso a meno che non abbia una tolleranza corrispondente all'incompatibilità aggiunta. Aggiungi la tolleranza alla specifica per i carichi di lavoro per consentire la programmazione dei pod sul pool di nodi incompatibile.

Se hai etichettato il pool di nodi dedicato, puoi anche aggiungere una regola di affinità dei nodi per indicare a GKE su AWS di pianificare i carichi di lavoro solo su quel pool di nodi.

L'esempio seguente aggiunge una tolleranza per l'incompatibilità workloadType=untrusted:NoExecute e una regola di affinità nodo per l'etichetta del nodo workloadType=untrusted.

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"]

Sostituisci quanto segue:

  • TAINT_KEY: la chiave di incompatibilità che hai applicato al pool di nodi dedicato.
  • TAINT_VALUE: il valore di incompatibilità applicato al pool di nodi dedicato.
  • LABEL_KEY: la chiave di etichetta del nodo che hai applicato al pool di nodi dedicato.
  • LABEL_VALUE: il valore dell'etichetta del nodo che hai applicato al pool di nodi dedicato.

Quando aggiorni il deployment con kubectl apply, GKE su AWS ricrea i pod interessati. La regola di affinità dei nodi forza i pod a collegarsi al pool di nodi dedicato che hai creato. La tolleranza consente di posizionare solo i pod sui nodi.

Verificare che la separazione funzioni

Per verificare che la pianificazione funzioni correttamente, esegui il comando seguente e controlla se i tuoi carichi di lavoro si trovano nel pool di nodi dedicato:

kubectl get pods -o=wide

Consigli e best practice

Dopo aver configurato l'isolamento dei nodi, ti consigliamo di procedere come segue:

  • Limita pool di nodi specifici a GKE sui carichi di lavoro gestiti da AWS solo aggiungendo l'incompatibilità components.gke.io/gke-managed-components. L'aggiunta di questa incompatibilità impedisce ai tuoi pod di pianificare su quei nodi, migliorando l'isolamento.
  • Quando crei nuovi pool di nodi, puoi impedire che la maggior parte di GKE su carichi di lavoro gestiti da AWS venga eseguito su quei nodi aggiungendo la tua incompatibilità a questi pool di nodi.
  • Ogni volta che esegui il deployment di nuovi carichi di lavoro nel tuo cluster, ad esempio durante l'installazione di strumenti di terze parti, controlla le autorizzazioni richieste dai pod. Ove possibile, evita di eseguire il deployment di carichi di lavoro che usano autorizzazioni elevate per i nodi condivisi.

Passaggi successivi