Isola i carichi di lavoro in pool di nodi dedicati


Questa pagina mostra come ridurre il rischio di attacchi di escalation dei privilegi nel cluster chiedendo a Google Kubernetes Engine (GKE) di pianificare i carichi di lavoro in un pool di nodi dedicato e separato dai carichi di lavoro gestiti da GKE con privilegi. Questa pagina riguarda gli standard di cluster senza provisioning automatico dei nodi. Per separare i carichi di lavoro nei cluster Autopilot e nei cluster standard con il provisioning automatico dei nodi abilitato, consulta Configurare la separazione dei carichi di lavoro in GKE.

Panoramica

I cluster GKE utilizzano carichi di lavoro privilegiati gestiti da GKE per attivare funzionalità e funzionalità specifiche del cluster, come la raccolta delle metriche. A questi carichi di lavoro vengono concesse autorizzazioni speciali per essere eseguiti correttamente in un cluster Kubernetes.

I carichi di lavoro di cui esegui il deployment sui nodi potrebbero essere potenzialmente compromessi da un'entità malintenzionata. Esecuzione di questi carichi di lavoro insieme per carichi di lavoro con privilegi gestiti da GKE un aggressore che esce da un container compromesso può utilizzare le credenziali del carico di lavoro con privilegi sul nodo per aumentare i privilegi in un cluster Kubernetes.

Prevenire i gruppi di lavoro dei container

La tua difesa principale dovrebbe essere costituita dalle tue applicazioni. GKE ha per la protezione di cluster e pod. Nella maggior parte dei casi, consigliamo vivamente di utilizzare GKE Sandbox per isolare i carichi di lavoro. GKE Sandbox si basa sul progetto open source gVisor e implementa l'API del kernel Linux nello spazio utente. Ogni pod viene eseguito su un kernel dedicato che esegue il sandboxing delle applicazioni per impedire l'accesso alle chiamate di sistema privilegiate nel kernel host. I carichi di lavoro in esecuzione in GKE Sandbox vengono automaticamente pianificati su nodi separati, isolati da altri carichi di lavoro.

Segui anche i consigli riportati in Rafforzamento della sicurezza del cluster.

Evitare gli attacchi con escalation dei privilegi

Se non puoi usare GKE Sandbox e vuoi aggiungere un ulteriore livello sull'isolamento in aggiunta ad altre misure di protezione avanzata, puoi utilizzare incompatibilità dei nodi e affinità nodo per pianificare i carichi di lavoro su un pool di nodi dedicato. Un'incompatibilità del nodo indica a GKE di evitare di pianificare carichi di lavoro senza una tolleranza corrispondente (ad esempio i carichi di lavoro gestiti da GKE) su quei nodi. L'affinità dei nodi sui tuoi carichi di lavoro indica a GKE di pianificare i pod sui nodi dedicati.

Limitazioni dell'isolamento dei nodi

  • Gli utenti malintenzionati possono comunque avviare attacchi DoS (Denial-of-Service) dal compromesso.
  • I nodi compromessi possono comunque leggere molte risorse, inclusi tutti i pod e gli spazi dei nomi nel cluster.
  • I nodi compromessi possono accedere ai secret e alle credenziali utilizzati 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 aggirare i criteri di rete in uscita.
  • Alcuni carichi di lavoro gestiti da GKE devono essere eseguiti su ogni nodo del cluster e sono configurati per tollerare tutti gli elementi dannosi.
  • Se esegui il deployment di DaemonSet con autorizzazioni elevate e che possono tollerare qualsiasi attacco di manomissione, 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 tuoi carichi di lavoro, devi:

  1. Incompatibilità ed etichettare un pool di nodi per i tuoi carichi di lavoro.
  2. Aggiorna i carichi di lavoro con la tolleranza e l'affinità dei nodi corrispondenti personalizzata.

Questa guida presuppone che tu inizi con un pool di nodi nel tuo cluster. Utilizzo del nodo di affinità e le incompatibilità dei nodi non è obbligatorio, ma lo consigliamo perché trarrai vantaggio da un maggiore controllo sulla pianificazione.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Attiva l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, install e poi inizializzare con gcloud CLI. Se hai già installato gcloud CLI, ottieni la versione più recente eseguendo gcloud components update.
  • Scegli un nome specifico per l'incompatibilità del nodo e l'etichetta del nodo che vuoi da usare per i pool di nodi dedicati. Per questo esempio utilizziamo workloadType=untrusted.

Contaminare ed etichettare un pool di nodi per i tuoi carichi di lavoro

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

Puoi anche aggiungere incompatibilità dei nodi ed etichette dei nodi a pool di nodi esistenti. Se utilizzi l'effetto NoExecute, GKE esegue l'espulsione di tutti i pod in esecuzione su quei nodi che non hanno una tolleranza per il nuovo taint.

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

gcloud container 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 per i carichi di lavoro.
  • CLUSTER_NAME: il nome del tuo cluster GKE in un cluster Kubernetes.
  • TAINT_KEY=TAINT_VALUE: una coppia chiave-valore associata con una programmazione TAINT_EFFECT. Ad esempio: workloadType=untrusted.
  • TAINT_EFFECT: uno dei seguenti valori valori effetto: NoSchedule, PreferNoSchedule o NoExecute. NoExecute offre una garanzia di espulsione migliore rispetto a NoSchedule.
  • LABEL_KEY=LABEL_VALUE: per le etichette dei nodi, che corrispondono ai selettori che specificato nei manifest dei carichi di lavoro.

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

Dopo aver incompatibile il pool di nodi dedicato, nessun carico di lavoro può pianificare il pool a meno che hanno una tolleranza corrispondente all'incompatibilità che hai aggiunto. Aggiungi la tolleranza alla specifica per i tuoi carichi di lavoro per consentire la pianificazione di questi pod nel tuo pool di nodi con incompatibilità.

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

Nell'esempio seguente viene aggiunta una tolleranza per l'attributo Incompatibilità di workloadType=untrusted:NoExecute e una regola di affinità nodo per 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 contaminazione che hai applicato al pool di nodi dedicato.
  • TAINT_VALUE: il valore dell'alterazione applicato al pool di nodi dedicato.
  • LABEL_KEY: la chiave dell'etichetta del nodo applicata al pool di nodi dedicato.
  • LABEL_VALUE: il valore dell'etichetta del nodo che hai applicato il tuo pool di nodi dedicato.

Quando aggiorni il tuo deployment con kubectl apply, GKE ricrea i pod interessati. La regola di affinità dei nodi forza i pod nel pool di nodi dedicato che hai creato. La tolleranza consente di collocare sui nodi solo questi pod.

Verificare il funzionamento della separazione

Per verificare che la pianificazione funzioni correttamente, esegui il seguente comando 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 ai carichi di lavoro gestiti da GKE solo aggiungendo l'incompatibilità components.gke.io/gke-managed-components. Aggiunta di questo elemento l'incompatibilità impedisce la pianificazione dei tuoi pod su quei nodi, migliorando e l'isolamento dei dati.
  • Quando crei nuovi pool di nodi, impedisci la maggior parte dei servizi gestiti da GKE per l'esecuzione di carichi di lavoro su quei nodi, aggiungendo la tua incompatibilità piscine.
  • Ogni volta che esegui il deployment di nuovi carichi di lavoro nel cluster, ad esempio durante l'installazione strumenti di terze parti, controllano le autorizzazioni richieste dai pod. Quando possibile, evita di eseguire il deployment di carichi di lavoro che usano autorizzazioni elevate nodi.

Passaggi successivi