Procedure consigliate per la sicurezza e gli aggiornamenti del cluster nel servizio Azure Kubernetes

Quando si gestiscono i cluster nel servizio Azure Kubernetes, la sicurezza dei carichi di lavoro e dei dati è una considerazione fondamentale. Quando si eseguono cluster multi-tenant usando l'isolamento logico, è soprattutto necessario proteggere l'accesso alle risorse e ai carichi di lavoro. Ridurre al minimo il rischio di attacco applicando gli ultimi aggiornamenti della sicurezza del sistema operativo Kubernetes e del nodo.

Questo articolo illustra in particolare come proteggere il cluster del servizio Azure Kubernetes (AKS). Scopri come:

  • Usare Microsoft Entra ID e il controllo degli accessi in base al ruolo di Kubernetes per proteggere l'accesso al server API.
  • Proteggere l'accesso del contenitore alle risorse dei nodi.
  • Aggiornare un cluster del servizio Azure Kubernetes alla versione più recente di Kubernetes.
  • Mantenere i nodi aggiornati e applicare automaticamente le patch di protezione.

È anche possibile leggere le procedure consigliate per la gestione delle immagini del contenitore e la sicurezza dei pod.

Abilitare la protezione dalle minacce

Materiale sussidiario sulle procedure consigliate

È possibile abilitare Defender per contenitori per proteggere i contenitori. Defender per contenitori può valutare le configurazioni del cluster e fornire raccomandazioni sulla sicurezza, eseguire analisi delle vulnerabilità e fornire protezione e avvisi in tempo reale per nodi e cluster Kubernetes.

Proteggere l'accesso al server dell'API e ai nodi del cluster

Materiale sussidiario sulle procedure consigliate

Uno dei modi più importanti per proteggere il cluster consiste nel proteggere l'accesso al server API Kubernetes. Per controllare l'accesso al server API, integrare il controllo degli accessi in base al ruolo di Kubernetes con Microsoft Entra ID. Con questi controlli è possibile proteggere il servizio Azure Kubernetes allo stesso modo in cui si protegge l'accesso alle sottoscrizioni di Azure.

Il server dell'API Kubernetes fornisce un singolo punto di connessione per le richieste di esecuzione di azioni all'interno di un cluster. Per proteggere e controllare l'accesso al server API, limitare l'accesso e fornire i livelli di autorizzazione più bassi possibili. anche se questo approccio non è univoco per Kubernetes, è particolarmente importante quando è stato isolato logicamente il cluster del servizio Azure Kubernetes per l'uso multi-tenant.

Microsoft Entra ID offre una soluzione di gestione delle identità pronta per l'organizzazione che si integra con i cluster del servizio Azure Kubernetes. Poiché Kubernetes non fornisce una soluzione di gestione delle identità, potrebbe essere difficile limitare in modo granulare l'accesso al server API. Con i cluster integrati di Microsoft Entra nel servizio Azure Kubernetes, si usano gli account utente e di gruppo esistenti per autenticare gli utenti nel server API.

Microsoft Entra integration for AKS clusters

Usando il controllo degli accessi in base al ruolo di Kubernetes e Microsoft Entra ID-integration, è possibile proteggere il server API e fornire le autorizzazioni minime necessarie per un set di risorse con ambito, ad esempio un singolo spazio dei nomi. È possibile concedere diversi utenti o gruppi di Microsoft Entra a ruoli Kubernetes diversi. Con autorizzazioni granulari, è possibile limitare l'accesso al server API e fornire un audit trail chiaro delle azioni eseguite.

La procedura consigliata consiste nell'usare dei gruppi per fornire l'accesso a file e cartelle anziché alle singole identità. Ad esempio, usare un'appartenenza al gruppoMicrosoft Entra ID per associare gli utenti ai ruoli Kubernetes anziché ai singoli utenti. Man mano che l'appartenenza al gruppo di un utente cambia, le autorizzazioni di accesso nel cluster del servizio Azure Kubernetes cambiano di conseguenza.

Nel frattempo, si supponga di associare l'utente singolo direttamente a un ruolo e alle modifiche della funzione del processo. Mentre le appartenenze ai gruppi di Microsoft Entra si aggiornano, le relative autorizzazioni per il cluster del servizio Azure Kubernetes non vengono aggiornate. In questo scenario, l'utente finisce con più autorizzazioni di quelle necessarie.

Per altre informazioni sull'integrazione di Microsoft Entra, sul controllo degli accessi in base al ruolo di Kubernetes e sul controllo degli accessi in base al ruolo di Azure, vedere Procedure consigliate per l'autenticazione e l'autorizzazione nel servizio Azure Kubernetes.

Limitare l'accesso all'API metadati dell'istanza

Materiale sussidiario sulle procedure consigliate

Aggiungere un criterio di rete in tutti gli spazi dei nomi utente per bloccare l'uscita dei pod all'endpoint dei metadati.

Nota

Per implementare i criteri di rete, includere l'attributo --network-policy azure durante la creazione del cluster del servizio Azure Kubernetes. Usare il comando seguente per creare il cluster: az aks create -g myResourceGroup -n myManagedCluster --enable-managed-identity --network-plugin azure --network-policy azure

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-instance-metadata
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 10.10.0.0/0#example
        except:
        - 169.254.169.254/32

Proteggere l'accesso del contenitore alle risorse

Materiale sussidiario sulle procedure consigliate

Limitare l'accesso alle azioni che i contenitori possono eseguire. Concedere il minor numero possibile di autorizzazioni ed evitare l'uso dell'accesso radice o dell'escalation dei privilegi.

Allo stesso modo in cui è necessario concedere agli utenti o ai gruppi i privilegi minimi necessari, è anche necessario limitare i contenitori solo alle azioni e ai processi necessari. Per ridurre al minimo il rischio di attacco, evitare di configurare applicazioni e contenitori che richiedono privilegi di escalation o accesso radice.

Ad esempio, impostare allowPrivilegeEscalation: false nel manifesto del pod. Questi contesti di sicurezza pod predefiniti di Kubernetes consentono di definire autorizzazioni aggiuntive, ad esempio l'utente o il gruppo con cui eseguire, o le funzionalità di Linux da esporre. Per altre procedure consigliate, vedere Proteggere l'accesso dei pod alle risorse.

Per un controllo ancora più granulare delle azioni dei contenitori, è anche possibile usare funzionalità di sicurezza predefinite di Linux, come AppArmor e seccomp.

  1. Definire le funzionalità di sicurezza di Linux a livello di nodo.
  2. Implementare le funzionalità tramite un manifesto del pod.

Le funzionalità di sicurezza Linux predefinite sono disponibili solo nei nodi e nei pod Linux.

Nota

Attualmente, gli ambienti Kubernetes non sono completamente sicuri per l'utilizzo multi-tenant ostile. Funzionalità di sicurezza aggiuntive, ad esempio Microsoft Defender per contenitoriAppArmor, seccomp,ammissione di sicurezza dei pod o controllo degli accessi in base al ruolo di Kubernetes per i nodi, bloccano in modo efficiente gli exploit.

Per una vera sicurezza quando si eseguono carichi di lavoro multi-tenant ostili, considerare attendibile solo un hypervisor. Il dominio di sicurezza per Kubernetes diventa l'intero cluster, non un singolo nodo.

Per questi tipi di carichi di lavoro multi-tenant ostili è consigliabile usare cluster fisicamente isolati.

AppArmor

Per limitare le azioni del contenitore, è possibile usare il modulo di sicurezza del kernel AppArmor Linux. Il modulo è disponibile come parte del sistema operativo del nodo del servizio Azure Kubernetes sottostante ed è abilitato per impostazione predefinita. È possibile creare profili AppArmor che limitano le azioni di lettura, scrittura o esecuzione o funzioni di sistema come il montaggio di file system. I profili AppArmor predefiniti limitano l'accesso a vari percorsi /proc e /sys e consentono di isolare logicamente i contenitori dal nodo sottostante. AppArmor funziona non solo per i pod Kubernetes ma per qualsiasi applicazione in esecuzione su Linux.

AppArmor profiles in use in an AKS cluster to limit container actions

Per una dimostrazione di AppArmor in azione, l'esempio seguente crea un profilo che impedisce la scrittura nei file.

  1. Connettersi tramite SSH a un nodo del servizio Azure Kubernetes.

  2. Creare un file denominato deny-write.profile.

  3. Copiare e incollare il contenuto seguente:

    #include <tunables/global>
    profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
      #include <abstractions/base>
    
      file,
      # Deny all file writes.
      deny /** w,
    }
    

Per aggiungere profili AppArmor occorre usare il comando apparmor_parser.

  1. Aggiungere il profilo ad AppArmor.

  2. Specificare il nome del profilo creato nel passaggio precedente:

    sudo apparmor_parser deny-write.profile
    

    Se il profilo viene analizzato correttamente e applicato ad AppArmor, non verrà visualizzato alcun output e verrà restituito al prompt dei comandi.

  3. Dal computer locale creare un manifesto del pod denominato aks-apparmor.yaml. Questo manifesto:

    • Definisce un'annotazione per container.apparmor.security.beta.kubernetes.
    • Fa riferimento al profilo di deny-write creato nei passaggi precedenti.
    apiVersion: v1
    kind: Pod
    metadata:
      name: hello-apparmor
      annotations:
        container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write
    spec:
      containers:
      - name: hello
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
    
  4. Con il pod distribuito, eseguire il comando seguente e verificare che il pod hello-apparmor mostri uno stato di In esecuzione:

    kubectl get pods
    
    NAME             READY   STATUS    RESTARTS   AGE
    aks-ssh          1/1     Running   0          4m2s
    hello-apparmor   0/1     Running   0          50s
    

Per altre informazioni su AppArmor, vedere AppArmor nella documentazione di Kubernetes.

seccomp

Mentre AppArmor funziona con qualsiasi applicazione Linux, seccomp (secure computing, elaborazione sicura) funziona a livello di processo. Anche seccomp è un modulo di protezione del kernel di Linux ed è supportato in modo nativo dal runtime Docker usato dai nodi del servizio Azure Kubernetes. Con seccomp, è possibile limitare le chiamate al processo del contenitore. Allineare alla procedura consigliata di concedere al contenitore l'autorizzazione minima solo per l'esecuzione da:

  • Definizione con filtra le azioni da consentire o negare.
  • Annotazione all'interno di un manifesto YAML del pod da associare al filtro seccomp.

Per una dimostrazione di seccomp in azione, creare un filtro che impedisce di cambiare le autorizzazioni su un file.

  1. Connettersi tramite SSH a un nodo del servizio Azure Kubernetes.

  2. Creare un filtro seccomp denominato /var/lib/kubelet/seccomp/prevent-chmod.

  3. Copiare e incollare il contenuto seguente:

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "name": "chmod",
          "action": "SCMP_ACT_ERRNO"
        },
        {
          "name": "fchmodat",
          "action": "SCMP_ACT_ERRNO"
        },
        {
          "name": "chmodat",
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    

    Nella versione 1.19 e successive è necessario configurare quanto segue:

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "names": ["chmod","fchmodat","chmodat"],
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    
  4. Dal computer locale creare un manifesto pod denominato aks-seccomp.yaml e incollare il contenuto seguente. Questo manifesto:

    • Definisce un'annotazione per seccomp.security.alpha.kubernetes.io.
    • Fa riferimento al filtro di prevent-chmod creato nel passaggio precedente.
    apiVersion: v1
    kind: Pod
    metadata:
      name: chmod-prevented
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod
    spec:
      containers:
      - name: chmod
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command:
          - "chmod"
        args:
         - "777"
         - /etc/hostname
      restartPolicy: Never
    

    Nella versione 1.19 e successive è necessario configurare quanto segue:

    apiVersion: v1
    kind: Pod
    metadata:
      name: chmod-prevented
    spec:
      securityContext:
        seccompProfile:
          type: Localhost
          localhostProfile: prevent-chmod
      containers:
      - name: chmod
        image: mcr.microsoft.com/dotnet/runtime-deps:6.0
        command:
          - "chmod"
        args:
         - "777"
         - /etc/hostname
      restartPolicy: Never
    
  5. Distribuire il pod di esempio usando il comando kubectl apply:

    kubectl apply -f ./aks-seccomp.yaml
    
  6. Visualizzare lo stato del pod usando il comando kubectl get pods.

    • Il pod segnala un errore.
    • Come illustrato nell'output di esempio seguente, il filtro seccomp impedisce l'esecuzione del comando chmod:
    kubectl get pods
    
    NAME                      READY     STATUS    RESTARTS   AGE
    chmod-prevented           0/1       Error     0          7s
    

Per altre informazioni sui filtri disponibili, vedere Seccomp security profiles for Docker (Profili di sicurezza di seccomp per Docker).

Eseguire regolarmente l'aggiornamento alla versione più recente di Kubernetes

Materiale sussidiario sulle procedure consigliate

Per rimanere aggiornati sulle nuove funzionalità e sulle correzioni di bug, aggiornare regolarmente la versione di Kubernetes nel cluster del servizio Azure Kubernetes.

Kubernetes rilascia nuove funzionalità con maggiore frequenza rispetto alle piattaforme di infrastruttura più tradizionali. Gli aggiornamenti di Kubernetes includono:

  • Nuove funzionalità
  • Correzioni di bug o sicurezza

Le nuove funzionalità in genere passano attraverso lo stato alfa e beta prima che diventino stabili. Una volta stabili, sono disponibili a livello generale e consigliati per l'uso in produzione. Il nuovo ciclo di rilascio delle funzionalità di Kubernetes consente di aggiornare Kubernetes senza incontrare regolarmente modifiche di rilievo o modificare le distribuzioni e i modelli.

Il servizio Azure Kubernetes supporta tre versioni secondarie di Kubernetes. Dopo aver introdotto una nuova versione di patch secondaria, le versioni secondarie meno recenti e le versioni patch supportate vengono ritirate. Gli aggiornamenti secondari di Kubernetes vengono eseguiti periodicamente. Per rimanere all'interno del supporto, assicurarsi di disporre di un processo di governance per verificare la presenza di aggiornamenti necessari. Per altre informazioni, vedere Versioni Kubernetes supportate nel servizio Azure Kubernetes.

Per verificare le versioni disponibili per il cluster in uso, usare il comando az aks get-upgrades come illustrato nell'esempio seguente:

az aks get-upgrades --resource-group myResourceGroup --name myAKSCluster --output table

È quindi possibile aggiornare il cluster AKS tramite il comando az aks upgrade. Il processo di aggiornamento è sicuro:

  • Blocca e svuota un nodo alla volta.
  • Pianifica i pod nei nodi rimanenti.
  • Distribuisce un nuovo nodo che esegue le versioni più recenti del sistema operativo e Kubernetes.

Importante

Testare le nuove versioni secondarie in un ambiente di test di sviluppo e verificare che il carico di lavoro rimanga integro con la nuova versione di Kubernetes.

Kubernetes può deprecare le API (ad esempio nella versione 1.16) su cui si basano i carichi di lavoro. Quando si apportano nuove versioni nell'ambiente di produzione, è consigliabile usare più pool di nodi in versioni separate e aggiornare singoli pool uno alla volta per eseguire progressivamente l'aggiornamento in un cluster. Se si eseguono più cluster, aggiornare un cluster alla volta per monitorare progressivamente l'impatto o le modifiche.

az aks upgrade --resource-group myResourceGroup --name myAKSCluster --kubernetes-version KUBERNETES_VERSION

Per altre informazioni sugli aggiornamenti nel servizio Azure Container, vedere Versioni Kubernetes supportate nel servizio Azure Kubernetes e Aggiornare un cluster del servizio Azure Kubernetes.

Elaborare gli aggiornamenti dei nodi Linux

Ogni sera, i nodi Linux nel servizio Azure Kubernetes ottengono patch di sicurezza tramite il canale di aggiornamento della distribuzione. Questo comportamento viene configurato automaticamente quando i nodi vengono distribuiti in un cluster del servizio Azure Kubernetes. Per ridurre al minimo le interruzioni del servizio e l'impatto sui carichi di lavoro in esecuzione, i nodi non vengono riavviati automaticamente se una patch di protezione o un aggiornamento del kernel lo richiede. Per altre informazioni su come gestire i riavvii dei nodi, vedere Applicare aggiornamenti di sicurezza e del kernel ai nodi nel servizio Azure Kubernetes.

Aggiornamenti delle immagini del nodo

Gli aggiornamenti automatici applicano aggiornamenti al sistema operativo del nodo Linux, ma l'immagine usata per creare nodi per il cluster rimane invariata. Se viene aggiunto un nuovo nodo Linux al cluster, l'immagine originale viene usata per creare il nodo. Questo nuovo nodo riceverà tutti gli aggiornamenti della sicurezza e del kernel disponibili durante il controllo automatico ogni notte, ma rimarrà senza patch fino al completamento di tutti i controlli e i riavvii. È possibile usare l'aggiornamento dell'immagine del nodo per verificare la presenza e aggiornare le immagini del nodo usate dal cluster. Per altre informazioni sull'aggiornamento delle immagini del nodo, vedere Aggiornamento dell'immagine del nodo del servizio Azure Kubernetes.

Elaborare gli aggiornamenti dei nodi di Windows Server

Per i nodi di Windows Server, eseguire regolarmente un'operazione di aggiornamento dell'immagine del nodo per completare e svuotare in modo sicuro i pod e distribuire nodi aggiornati.