Protezione dell'isolamento del carico di lavoro con GKE Sandbox


Questa pagina descrive come utilizzare GKE Sandbox per proteggere il kernel host sui tuoi nodi quando i container nel pod eseguono codice sconosciuto o non attendibile o richiedono un isolamento aggiuntivo dal nodo.

Disponibilità di GKE Sandbox

GKE Sandbox è pronta per l'uso nei cluster Autopilot che eseguono GKE 1.27.4-gke.800 e versioni successive. Per iniziare a eseguire il deployment di carichi di lavoro Autopilot in una sandbox, vai a Utilizzare GKE Sandbox.

Per utilizzare GKE Sandbox in cluster GKE Standard nuovi o esistenti, devi attivare manualmente GKE Sandbox sul cluster.

I carichi di lavoro GPU sono disponibili in anteprima in GKE Sandbox nella versione 1.29.2-gke.11080000 e successive.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:

  • Attiva l'API Google Kubernetes Engine.
  • Attiva l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installa e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, ottieni la versione più recente eseguendo gcloud components update.

Abilita GKE Sandbox su un nuovo cluster standard

Il pool di nodi predefinito, creato quando crei un nuovo cluster, non può utilizzare GKE Sandbox se è l'unico pool di nodi nel cluster, perché i workload di sistema gestiti da GKE devono essere eseguiti separatamente dai workload in sandbox non attendibili. Per abilitare GKE Sandbox durante la creazione del cluster, devi aggiungere almeno un altro pool di nodi al cluster.

Console

Per visualizzare i cluster, vai al menu Google Kubernetes Engine nella console Google Cloud.

  1. Vai alla pagina Google Kubernetes Engine nella console Google Cloud.

    Vai a Google Kubernetes Engine

  2. Fai clic su Crea.

  3. Facoltativo, ma consigliato: nel menu di navigazione, fai clic su Funzionalità in Cluster e seleziona le seguenti caselle di controllo in modo che i messaggi di gVisor vengano registrati:

    • Cloud Logging
    • Cloud Monitoring
    • Managed Service per Prometheus
  4. Fai clic su Aggiungi pool di nodi.

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

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

    1. Nell'elenco a discesa Tipo di immagine, seleziona OS ottimizzato per i contenitori 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.
    3. Se utilizzi una versione GKE supportata, puoi anche selezionare un tipo di GPU. Deve essere uno dei seguenti tipi:

      • nvidia-tesla-t4
      • nvidia-tesla-a100
      • nvidia-a100-80gb
      • nvidia-l4
      • nvidia-h100-80gb

      Le GPU in GKE Sandbox sono disponibili in anteprima.

    4. Se utilizzi GPU su GKE Sandbox (anteprima), seleziona o installa la variante del driver latest.

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

  8. Continua a configurare il cluster e i node pool in base alle esigenze.

  9. Fai clic su Crea.

gcloud

GKE Sandbox non può essere attivato per il pool di nodi predefinito e non è possibile creare altri node pool contemporaneamente alla creazione di un nuovo cluster utilizzando il comando gcloud. Crea invece il cluster come faresti normalmente. Sebbene facoltativo, ti consigliamo di abilitare il logging e il monitoraggio in modo che i messaggi di gVisor vengano registrati.

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.

Per creare un pool di nodi GPU con GKE Sandbox, esegui il seguente comando:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=latest \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Sostituisci quanto segue:

Abilita GKE Sandbox su un cluster standard esistente

Puoi attivare GKE Sandbox su un cluster standard 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 abilitata:

  1. Vai alla pagina Google Kubernetes Engine nella console Google Cloud.

    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 selezionato.

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

    1. Nell'elenco a discesa Tipo di immagine, seleziona OS ottimizzato per i contenitori 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.
    3. Se utilizzi una versione GKE supportata, puoi anche selezionare un tipo di GPU. Deve essere uno dei seguenti tipi:

      • nvidia-tesla-t4
      • nvidia-tesla-a100
      • nvidia-a100-80gb
      • nvidia-l4
      • nvidia-h100-80gb

      Le GPU in GKE Sandbox sono disponibili in anteprima.

    4. Se utilizzi GPU su GKE Sandbox (anteprima), seleziona o installa la variante del driver latest.

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

  7. Fai clic su Crea.

gcloud

Per creare un nuovo pool di nodi con GKE Sandbox abilitato, utilizza un comando come il seguente:

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.

Per creare un pool di nodi GPU con GKE Sandbox, esegui il seguente comando:

gcloud container node-pools create NODE_POOL_NAME \
  --cluster=CLUSTER_NAME \
  --node-version=NODE_VERSION \
  --machine-type=MACHINE_TYPE \
  --accelerator=type=GPU_TYPE,gpu-driver-version=latest \
  --image-type=cos_containerd \
  --sandbox type=gvisor

Sostituisci quanto segue:

(Facoltativo) Abilita il monitoraggio e il logging

È facoltativo, ma consigliato, attivare Cloud Logging e Cloud Monitoring sul cluster in modo che i messaggi gVisor vengano registrati. Questi servizi sono attivati per impostazione predefinita per i nuovi cluster.

Puoi utilizzare la console Google Cloud per attivare queste funzionalità su un cluster esistente.

  1. Vai alla pagina Google Kubernetes Engine nella console Google Cloud.

    Vai a Google Kubernetes Engine

  2. Fai clic sul nome del cluster da modificare.

  3. In Funzionalità, nel campo Cloud Logging, fai clic su Modifica Cloud Logging.

  4. Seleziona la casella di controllo Attiva Cloud Logging.

  5. Fai clic su Salva modifiche.

  6. Ripeti gli stessi passaggi per i campi Cloud Monitoring e Managed Service per Prometheus per attivare queste funzionalità.

Utilizzare GKE Sandbox in Autopilot e Standard

Nei cluster Autopilot e nei cluster standard con GKE Sandbox abilitato, puoi richiedere un ambiente in sandbox per un pod specificando gvisor RuntimeClass nella specifica del pod.

Per i cluster Autopilot, assicurati di eseguire GKE versione 1.27.4-gke.800 o successive.

Esecuzione di un'applicazione in un ambiente sandbox

Per eseguire un deployment su un nodo con GKE Sandbox abilitato, imposta spec.template.spec.runtimeClassName su gvisor, come mostrato nell'esempio seguente:

# 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

Crea il deployment:

kubectl apply -f httpd.yaml

Il pod viene dispiegato su un nodo con GKE Sandbox abilitata. Per verificare il deployment, individua il nodo in cui è stato 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

Nell'output, trova il nome del pod e controlla il valore di RuntimeClass:

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

L'output è gvisor.

In alternativa, puoi elencare la classe di runtime di ogni pod e cercare i pod in cui è impostata su gvisor:

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

L'output è il seguente:

POD_NAME: gvisor

Questo metodo di verifica che il pod sia in esecuzione in una sandbox è attendibile perché non si basa su dati all'interno della sandbox stessa. Qualsiasi elemento segnalato dall'interno della sandbox non è attendibile, in quanto potrebbe essere difettoso o dannoso.

Eseguire un pod con GPU su GKE Sandbox

Per eseguire un carico di lavoro GPU su GKE Sandbox, aggiungi il campo runtimeClassName: gvisor al manifest come negli esempi seguenti:

  • Manifest di esempio per i pod GPU in modalità standard:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      containers:
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
          nvidia.com/gpu: 1
    
  • Manifest di esempio per i pod GPU in modalità Autopilot:

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-gpu-pod
    spec:
      runtimeClassName: gvisor
      nodeSelector:
        cloud.google.com/gke-gpu-driver-version: "latest"
        cloud.google.com/gke-accelerator: nvidia-tesla-t4
      containers:
      - name: my-gpu-container
        image: nvidia/samples:vectoradd-cuda10.2
        resources:
          limits:
            nvidia.com/gpu: 1
    

Puoi eseguire qualsiasi pod GPU in modalità Autopilot o Standard chesoddisfa i requisiti di versione e tipo di GPU su GKE Sandbox aggiungendo il runtimeClassName: gvisor campo al manifest. Per istruzioni su come eseguire i pod GPU in GKE, consulta le seguenti risorse:

Eseguire un pod normale insieme a pod in sandbox

I passaggi descritti in questa sezione si applicano ai carichi di lavoro in modalità standard. Non è necessario eseguire pod regolari insieme a pod sandbox in modalità Autopilot, perché il modello di prezzi di Autopilot elimina la necessità di ottimizzare manualmente il numero di pod pianificati sui nodi.

Dopo aver attivato GKE Sandbox su un pool di nodi, puoi eseguire applicazioni attendibili su questi nodi senza utilizzare una sandbox utilizzando le incompatibilità e le tolleranze dei nodi. Questi pod sono chiamati "pod regolari" per distinguerli dai pod con sandbox.

Ai pod normali, come ai pod in sandbox, è impedito di accedere ad altri servizi Google Cloud o ai metadati del cluster. Questa prevenzione fa parte della configurazione del nodo. Se i pod normali o in sandbox richiedono l'accesso ai servizi Google Cloud, utilizza la federazione delle identità per i carichi di lavoro per GKE.

GKE Sandbox aggiunge la seguente etichetta e incompatibilità ai nodi che possono eseguire i pod in sandbox:

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

Oltre a eventuali impostazioni di affinità e tolleranza dei nodi nel manifest del pod, GKE Sandbox applica la seguente affinità e tolleranza dei nodi 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à e la tolleranza del nodo descritta in precedenza 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à del nodo sia la tolleranza.

Ad esempio, il seguente manifest modifica il manifest utilizzato in Eseguire un'applicazione in una sandbox in modo che venga eseguito come un pod normale su un nodo con pod in sandbox, rimuovendo il runtimeClass e aggiungendo sia l'attributo taint che la tolleranza descritti in precedenza.

# 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 della sua classe di runtime è gvisor. Il deployment httpd-no-sandbox non ha un valore per runtimeClass, quindi non viene eseguito in una sandbox.

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

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

Il nome del pool di nodi è incorporato nel valore di nodeName. Verifica che il pod sia in esecuzione su un nodo di un pool di nodi con GKE Sandbox abilitato.

Verificare la protezione dei metadati

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

  1. Crea un deployment in sandbox dal seguente manifest utilizzando kubectl apply -f. Utilizza l'immagine fedora, che include il comando curl. Il pod esegue il comando /bin/sleep per assicurarsi che il deployment venga eseguito per 10000 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 collegarti al pod in modo interattivo.

    kubectl exec -it POD_NAME /bin/sh
    

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

  3. Nella 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 il tempo di attesa perché i pacchetti vengono ignorati.

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

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

  6. Ottieni il nome del nuovo pod, connettiti utilizzando kubectl exec ed esegui di nuovo il comando curl. Questa volta vengono restituiti risultati. L'output di questo esempio è 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 di GKE Sandbox

Non puoi disattivare GKE Sandbox nei cluster GKE Autopilot o nei pool di nodi GKE Standard. Se non vuoi più utilizzare GKE Sandbox, elimina il node pool.

Passaggi successivi