Protezione dell'isolamento del carico di lavoro con GKE Sandbox

Mantieni tutto organizzato con le raccolte Salva e classifica i contenuti in base alle tue preferenze.

In questa pagina viene descritto come utilizzare GKE Sandbox per proteggere il kernel dell'host sui nodi quando i container nel pod eseguono codice sconosciuto o non attendibile o necessitano di un isolamento aggiuntivo dal nodo.

Abilitazione di GKE Sandbox

Puoi abilitare GKE Sandbox su un nuovo cluster o su un cluster esistente.

Prima di iniziare

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

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installa e poi inizializza l'interfaccia a riga di comando gcloud.
  • GKE Sandbox richiede GKE versione 1.13.5-gke.15 o successiva, per il piano di controllo e i nodi del cluster.
  • Assicurati che la versione dell'interfaccia a riga di comando di Google Cloud sia la 243.0.0 o successiva.

Su un nuovo cluster

Per abilitare GKE Sandbox, devi configurare un pool di nodi. Il pool di nodi predefinito (il primo pool di nodi nel cluster, creato al momento della creazione del cluster) non può utilizzare GKE Sandbox. Per abilitare Sandbox GKE durante la creazione del cluster, devi aggiungere un secondo pool di nodi quando crei il cluster.

Console

Per visualizzare i tuoi cluster, visita il menu di Google Kubernetes Engine nella console Google Cloud.

  1. Vai alla pagina Google Kubernetes Engine in Google Cloud Console.

    Vai a Google Kubernetes Engine

  2. Fai clic su Crea.

  3. Facoltativo ma consigliato: dal riquadro di navigazione, in Cluster, fai clic su Funzionalità e abilita Cloud Operations for GKE, in modo che i messaggi gVisor vengano registrati.

  4. Fai clic su Aggiungi pool di nodi.

  5. Nel riquadro di navigazione, in Pool di nodi, espandi il nuovo pool di nodi e fai clic su Nodi.

  6. Configura le impostazioni seguenti per il pool di nodi:

    1. Dall'elenco a discesa Tipo di immagine, seleziona Container-Optimized OS con Containerd (cos_containerd). Questo è l'unico tipo di immagine supportato per GKE Sandbox.
    2. In Configurazione macchina, seleziona una Serie e un Tipo di macchina.

  7. Nel riquadro di navigazione, sotto il nome del pool di nodi che stai configurando, fai clic su Sicurezza e seleziona la casella di controllo Abilita sandbox con gVisor.

  8. Continua a configurare il cluster e i pool di nodi come preferisci.

  9. Fai clic su Crea.

gcloud

La Sandbox GKE non può essere abilitata per il pool di nodi predefinito e non è possibile creare pool aggiuntivi di nodi contemporaneamente alla creazione di un nuovo cluster utilizzando il comando gcloud. Crea invece il tuo cluster come faresti normalmente. Sebbene sia facoltativo, ti consigliamo di attivare Cloud Operations for GKE in modo che vengano registrati i messaggi di gVisor.

Quindi, utilizza il comando gcloud container node-pools create e imposta il flag -- sandbox su type=gvisor. Il tipo di immagine del nodo deve essere cos_containerd per GKE Sandbox.

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

Sostituisci le seguenti variabili:

  • NODE_POOL_NAME: il nome del nuovo pool di nodi.
  • CLUSTER_NAME: il nome del tuo cluster.
  • NODE_VERSION: la versione da utilizzare per il pool di nodi.
  • MACHINE_TYPE: il tipo di macchina da utilizzare per i nodi. GKE Sandbox non supporta i tipi di macchine e2-micro, e2-small e e2-medium.

Prima di 1.18.4-gke.1300, viene creata un'istanza di runtimeClass di gvisor durante la creazione dei nodi. Prima di pianificare qualsiasi carico di lavoro sul nodo, controlla l'esistenza del runtimeClass di gvisor utilizzando il seguente comando:

kubectl get runtimeclasses

L'output è simile al seguente:

NAME     AGE
gvisor   19s

Se esegui una versione precedente alla 1.17.9-gke.1500 o a una versione 1.18 precedente alla 1.18.6-gke.600, devi anche attendere l'istanza di gvisor.config.common-webhooks.networking.gke.io. Per controllare, utilizza il comando seguente:

kubectl get mutatingwebhookconfiguration gvisor.config.common-webhooks.networking.gke.io

L'output è simile al seguente:

NAME                                              CREATED AT
gvisor.config.common-webhooks.networking.gke.io   2020-04-06T17:07:17Z

Su un cluster esistente

Puoi abilitare GKE Sandbox su un cluster esistente aggiungendo un nuovo pool di nodi e attivando la funzionalità per quel pool di nodi.

Console

Per creare un nuovo pool di nodi con GKE Sandbox abilitato:

  1. Vai alla pagina Google Kubernetes Engine in Google Cloud Console.

    Vai a Google Kubernetes Engine

  2. Fai clic sul nome del cluster da modificare.

  3. Fai clic su Aggiungi pool di nodi.

  4. Configura la pagina Dettagli del pool di nodi come preferisci.

  5. Nel riquadro di navigazione, fai clic su Nodi e configura le seguenti impostazioni:

    1. Dall'elenco a discesa Tipo di immagine, seleziona Container-Optimized OS con Containerd (cos_containerd). Questo è l'unico tipo di immagine supportato per GKE Sandbox.
    2. In Configurazione macchina, seleziona una Serie e un Tipo di macchina.

  6. Nel riquadro di navigazione, fai clic su Sicurezza e seleziona la casella di controllo Abilita sandbox con gVisor.

  7. Fai clic su Crea.

gcloud

Per creare un nuovo pool di nodi con GKE Sandbox abilitato, usa un comando come questo:

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

Il tipo di immagine del nodo deve essere cos_containerd per GKE Sandbox.

Prima di 1.18.4-gke.1300, viene creata un'istanza di runtimeClass di gvisor durante la creazione dei nodi. Prima di pianificare qualsiasi carico di lavoro sul nodo, controlla l'esistenza del runtimeClass di gvisor utilizzando il seguente comando:

kubectl get runtimeclasses
NAME     AGE
gvisor   19s

Se esegui una versione precedente alla 1.17.9-gke.1500 o a una versione 1.18 precedente alla 1.18.6-gke.600, devi anche attendere l'istanza di gvisor.config.common-webhooks.networking.gke.io. Per controllare, utilizza il comando seguente:

kubectl get mutatingwebhookconfiguration gvisor.config.common-webhooks.networking.gke.io
NAME                                              CREATED AT
gvisor.config.common-webhooks.networking.gke.io   2020-04-06T17:07:17Z

Facoltativo: abilita Cloud Operations for GKE

È facoltativo, ma è consigliabile abilitare Cloud Operations for GKE nel cluster, in modo che i messaggi gVisor vengano registrati. Cloud Operations for GKE è abilitato per impostazione predefinita per i nuovi cluster.

Puoi utilizzare Google Cloud Console per abilitare queste funzionalità su un cluster esistente.

  1. Vai alla pagina Google Kubernetes Engine in Google Cloud Console.

    Vai a Google Kubernetes Engine

  2. Fai clic sul nome del cluster da modificare.

  3. In Funzionalità, nel campo Cloud Operations for GKE, fai clic su Modifica Cloud Operations for GKE.

  4. Seleziona la casella di controllo Abilita Cloud Operations for GKE.

  5. Nell'elenco a discesa, seleziona Logging e monitoraggio del sistema e del carico di lavoro.

  6. Fai clic su Salva modifiche.

Lavorare con GKE Sandbox

Esecuzione di un'applicazione in una sandbox

Per forzare l'esecuzione di un deployment su un nodo con GKE Sandbox abilitato, imposta il relativo spec.template.spec.runtimeClassName su gvisor, come mostrato da questo manifest per un deployment:

# 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

Per creare il deployment, utilizza il comando kubectl create:

kubectl create -f httpd.yaml

Viene eseguito il deployment del pod su un nodo in un pool di nodi in cui è abilitata la sandbox di GKE. Per verificare il deployment, utilizza il comando seguente per trovare il nodo in cui viene eseguito il deployment del pod:

kubectl get pods

L'output è simile al seguente:

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

Dall'output, individua il nome del pod nell'output, quindi esegui il comando seguente per controllarne il valore per RuntimeClass:

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

L'output è:

gvisor

In alternativa, puoi elencare il runtimeClass di ogni pod e cercare quelli in cui è impostato su gvisor:

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

L'output è:

POD_NAME: gvisor

Questo metodo per verificare che il pod sia in esecuzione in una sandbox è affidabile perché non si basa sui dati al suo interno. Tutto ciò che viene segnalato all'interno della sandbox non è attendibile, perché potrebbe essere difettoso o dannoso.

Esecuzione di un pod normale insieme a pod con sandbox

Dopo aver abilitato la sandbox di GKE su un pool di nodi, puoi eseguire applicazioni attendibili su tali nodi senza utilizzare una sandbox utilizzando incompatibilità e tolleranze dei nodi. Questi pod sono denominati "pod regolari" per distinguerli dai pod con sandbox.

Ai pod normali, proprio come ai pod con sandbox, viene impedito l'accesso ad altri servizi Google Cloud o ai metadati del cluster. Questa prevenzione fa parte della configurazione del nodo. Se i tuoi pod normali o con sandbox richiedono l'accesso ai servizi Google Cloud, utilizza Workload Identity.

La sandbox di GKE aggiunge la seguente etichetta e l'incompatibilità ai nodi che possono eseguire pod con sandbox:

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

Oltre alle impostazioni di affinità e tolleranza relative ai nodi nel manifest del pod, GKE Sandbox applica la seguente affinità e tolleranza a tutti i pod con RuntimeClass impostato su gvisor:

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

Per pianificare un pod normale su un nodo con GKE Sandbox abilitato, applica manualmente l'affinità nodo e la tolleranza sopra nel manifest del pod.

  • Se il pod può essere eseguito su nodi con GKE Sandbox abilitato, aggiungi la tolleranza.
  • Se il pod deve essere eseguito su nodi con GKE Sandbox abilitato, aggiungi sia l'affinità nodo che la tolleranza.

Ad esempio, il seguente manifest modifica il manifest utilizzato in Esecuzione di un'applicazione in una sandbox in modo che venga eseguito come un pod normale su un nodo con pod con sandbox, rimuovendo il runtime runtime e aggiungendo sia l'incompatibilità che la tolleranza sopra.

# 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

Innanzitutto, verifica che il deployment non sia in esecuzione in una sandbox:

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

L'output è simile al seguente:

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

Il deployment httpd creato in precedenza è in esecuzione in una sandbox, perché il valore di runtime è pari a gvisor. Il deployment httpd-no-sandbox non ha alcun valore per runtimeClass, quindi non è in esecuzione in una sandbox.

Successivamente, verifica che il deployment senza sandbox sia in esecuzione su un nodo con GKE Sandbox eseguendo il comando seguente:

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

Il nome del pool di nodi è incorporato nel valore nodeName. Verifica che il pod sia in esecuzione su un nodo in un pool di nodi in cui è abilitata la sandbox di GKE.

Verificare la protezione dei metadati

Per convalidare l'affermazione che i metadati sono protetti dai nodi che possono eseguire pod con sandbox, puoi eseguire un test:

  1. Crea un deployment con sandbox dal file manifest seguente, utilizzando kubectl apply -f. Utilizza l'immagine fedora, che include il comando curl. Il pod esegue il comando /bin/sleep per garantire che il deployment venga eseguito per 10.000 secondi.

    # 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. Ottieni il nome del pod utilizzando kubectl get pods, quindi utilizza kubectl exec per connetterti in modo interattivo al pod.

    kubectl exec -it POD_NAME /bin/sh
    

    Sei collegato a un container in esecuzione nel pod in una sessione /bin/sh.

  3. Durante la sessione interattiva, prova ad accedere a un URL che restituisce i metadati del cluster:

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

    Il comando si blocca e alla fine scade perché i pacchetti sono stati ignorati automaticamente.

  4. Premi Ctrl+C per terminare il comando curl e digita exit per disconnetterti dal pod.

  5. Rimuovi la riga RuntimeClass dal manifest YAML ed esegui nuovamente il deployment del pod utilizzando kubectl apply -f FILENAME. Il pod con sandbox viene terminato e ricreato su un nodo senza la sandbox di GKE.

  6. Ottieni il nuovo nome del pod, connettilo utilizzando kubectl exec ed esegui di nuovo il comando curl. Questa volta, vengono restituiti i risultati. Questo output di esempio viene troncato.

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

    Digita exit per disconnetterti dal pod.

  7. Rimuovi il deployment:

    kubectl delete deployment fedora
    

Disabilitazione della sandbox di GKE

Al momento non è possibile aggiornare un pool di nodi per disabilitare GKE Sandbox. Per disabilitare GKE Sandbox su un pool di nodi esistente, puoi eseguire una delle seguenti opzioni:

Passaggi successivi