Isoler les charges de travail à l'aide de GKE Sandbox

Vous pouvez protéger le noyau hôte de vos nœuds Google Kubernetes Engine (GKE) contre les conteneurs qui exécutent du code non approuvé ou inconnu à l'aide de GKE Sandbox. Ce document explique aux spécialistes de la sécurité comment activer GKE Sandbox, exécuter des pods dans des bacs à sable et vérifier l'isolation.

Vous devez déjà connaître GKE Sandbox.

Types de bacs à sable disponibles

GKE Sandbox est compatible avec les types de bacs à sable suivants, qui utilisent chacun une technologie spécifique pour séparer le code d'application du noyau hôte :

  • gvisor : réimplémentation de l'espace utilisateur de l'API du noyau Linux qui ne nécessite pas de privilèges élevés. Le noyau de l'espace utilisateur intercepte et traite la majorité des appels système pour le compte du noyau hôte, ce qui limite l'accès direct au noyau hôte.
  • microvm : VM légères imbriquées dans la VM hôte à l'aide de la virtualisation imbriquée. Chaque pod du nœud s'exécute dans sa propre VM imbriquée avec son propre noyau invité. Comme le code s'exécute dans une VM dédiée, ce type de bac à sable offre une isolation plus forte que les bacs à sable gVisor.

Pour en savoir plus sur le fonctionnement de chaque type de bac à sable et sur le moment où utiliser un type spécifique, consultez À propos de GKE Sandbox.

Limites

GKE Sandbox et certaines technologies de bac à sable présentent diverses limites, telles que la compatibilité avec les GPU et les TPU, ou la compatibilité avec certaines fonctionnalités Linux et Kubernetes. Pour en savoir plus, consultez la section Limites.

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

  • Activez l'API Google Kubernetes Engine.
  • Activer l'API Google Kubernetes Engine
  • Si vous souhaitez utiliser la Google Cloud CLI pour cette tâche, installez puis initialisez la gcloud CLI. Si vous avez déjà installé la gcloud CLI, obtenez la dernière version en exécutant la commande gcloud components update. Il est possible que les versions antérieures de la gcloud CLI ne permettent pas d'exécuter les commandes de ce document.

Choisir un type de bac à sable pour les nœuds créés automatiquement

Vous pouvez utiliser ComputeClasses avec le mode Autopilot ou la création automatique de pools de nœuds pour activer GKE Sandbox sur les nœuds créés par GKE. Dans les clusters Autopilot, gVisor est compatible par défaut. Vous pouvez donc éventuellement omettre la configuration du bac à sable de votre ComputeClass.

Pour configurer GKE Sandbox pour les nœuds créés automatiquement, procédez comme suit :

  1. Connectez-vous à un cluster Autopilot ou Standard existant :

    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=CONTROL_PLANE_LOCATION
    

    Remplacez les éléments suivants :

    • CLUSTER_NAME : nom du cluster
    • CONTROL_PLANE_LOCATION : région ou zone du plan de contrôle de votre cluster.
  2. Enregistrez l'un des fichiers manifestes ComputeClass suivants, en fonction de la technologie de bac à sable que vous souhaitez utiliser :

    • gVisor :

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: sandbox-gvisor-class
      spec:
        priorities:
        - machineFamily: n4
        - machineFamily: c4
        nodePoolConfig:
          sandbox:
            type: gvisor
        nodePoolAutoCreation:
          enabled: true
        whenUnsatisfiable: DoNotScaleUp
      
    • microVM :

      apiVersion: cloud.google.com/v1
      kind: ComputeClass
      metadata:
        name: sandbox-microvm-class
      spec:
        priorities:
        - machineFamily: n4
        - machineFamily: c4
        nodePoolConfig:
          sandbox:
            type: microvm
        priorityDefaults:
          enableNestedVirtualization: true
        nodePoolAutoCreation:
          enabled: true
        whenUnsatisfiable: DoNotScaleUp
      

      La ComputeClass pour les bacs à sable microVM permet la virtualisation imbriquée à l'aide du champ enableNestedVirtualization. Ce champ est obligatoire pour les bacs à sable microVM. Pour utiliser ce champ, votre cluster doit exécuter la version 1.37.0-gke.4713000 ou ultérieure.

    Ces exemples de fichiers manifestes utilisent le champ nodePoolAutoCreation pour activer la création automatique de pools de nœuds. Vous pouvez également spécifier la configuration du bac à sable dans une ComputeClass qui utilise le champ autopilot pour exécuter des pods en mode Autopilot. Si vous utilisez des clusters Autopilot, GKE ignore les champs nodePoolAutoCreation et autopilot.

  3. Créez la ComputeClass :

    kubectl apply -f PATH_TO_COMPUTE_CLASS_MANIFEST
    

    Remplacez PATH_TO_COMPUTE_CLASS_MANIFEST par le chemin d'accès au fichier manifeste ComputeClass.

Pour sélectionner cette ComputeClass et demander un environnement de bac à sable, consultez Demander un environnement de bac à sable pour un pod.

Choisir un type de bac à sable lorsque vous créez des pools de nœuds

Vous pouvez activer manuellement GKE Sandbox lorsque vous créez un pool de nœuds dans un cluster Standard. Les limites suivantes s'appliquent lorsque vous activez manuellement GKE Sandbox :

  • Pour activer GKE Sandbox lors de la création d'un cluster Standard, vous devez configurer au moins un pool de nœuds supplémentaire. Le pool de nœuds supplémentaire est requis, car GKE a besoin d'au moins un pool de nœuds dans le cluster qui n'utilise pas GKE Sandbox pour exécuter les charges de travail système gérées par GKE. Si vous utilisez la gcloud CLI pour créer votre cluster, vous devez d'abord créer le cluster, puis un pool de nœuds qui utilise GKE Sandbox.
  • Pour sélectionner le type de bac à sable microVM, vous devez utiliser la gcloud CLI ou l'API GKE. La consoleGoogle Cloud ne permet pas de sélectionner le type de bac à sable microVM.

Activer le type de bac à sable gVisor

Pour activer manuellement les bacs à sable gVisor lorsque vous créez un pool de nœuds, sélectionnez l'une des options suivantes :

Console

  1. Dans la console Google Cloud , accédez à la page Clusters Kubernetes.

    Accéder à la page "Clusters Kubernetes"

  2. Cliquez sur le nom du cluster que vous souhaitez modifier. La page Détails du cluster s'ouvre.

  3. Cliquez sur l'onglet Nœuds.

  4. Dans la section Pools de nœuds, cliquez sur Ajouter un pool de nœuds géré par l'utilisateur. La page Ajouter un pool de nœuds s'ouvre.

  5. Dans le menu de navigation, cliquez sur Nœuds et configurez les paramètres suivants :

    1. Dans la liste déroulante Type d'image, sélectionnez Container-Optimized OS avec Containerd (cos_containerd).
    2. Dans la section Configuration de la machine, sélectionnez une série de machines et un type de machine pour les nœuds.
    3. Facultatif : sélectionnez un type de GPU compatible ou un type de TPU compatible.
  6. Dans le menu de navigation, cliquez sur Sécurité. La page Sécurité des nœuds s'ouvre.

  7. Cochez la case Activer le bac à sable avec gVisor.

  8. Pour créer le pool de nœuds, cliquez sur Créer.

gcloud

Pour créer un pool de nœuds utilisant gVisor pour les bacs à sable, exécutez la commande suivante :

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --sandbox=type=gvisor

Remplacez les éléments suivants :

  • NODE_POOL_NAME : nom du pool de nœuds.
  • CLUSTER_NAME : nom du cluster
  • CONTROL_PLANE_LOCATION : région ou zone du plan de contrôle de votre cluster.

Vous pouvez également activer les bacs à sable gVisor lorsque vous créez des pools de nœuds qui utilisent un type de GPU compatible ou un type de TPU compatible. Pour en savoir plus, consultez les documents suivants :

Activer le type de bac à sable microVM

Vous pouvez activer le type de bac à sable microVM lorsque vous créez un pool de nœuds à l'aide de gcloud CLI ou de l'API GKE. La console Google Cloud n'est pas compatible avec l'activation du type de bac à sable microVM. Pour créer un pool de nœuds qui utilise des bacs à sable microVM, exécutez la commande suivante :

gcloud container node-pools create NODE_POOL_NAME \
    --cluster=CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --sandbox=type=microvm \
    --enable-nested-virtualization \
    --machine-type=MACHINE_TYPE

Remplacez les éléments suivants :

  • NODE_POOL_NAME : nom du pool de nœuds.
  • CLUSTER_NAME : nom du cluster
  • CONTROL_PLANE_LOCATION : région ou zone du plan de contrôle de votre cluster.
  • MACHINE_TYPE : type de machine pour les nœuds. Cette valeur doit correspondre à un type de machine compatible avec la virtualisation imbriquée. Pour en savoir plus, consultez la ligne Virtualisation imbriquée dans le tableau comparatif des séries de machines.

Activer la surveillance et la journalisation

Pour collecter et afficher les journaux et les métriques de vos bacs à sable, assurez-vous que votre cluster active les services d'observabilité suivants :

Ces services sont activés par défaut dans tous les nouveaux clusters GKE.

Demander un environnement de bac à sable pour un pod

Pour exécuter un pod spécifique dans un bac à sable, vous pouvez spécifier la RuntimeClass gvisor ou microvm dans la spécification du pod. GKE planifie le pod sur les nœuds qui utilisent le type de bac à sable spécifié. Pour sélectionner un type de bac à sable dans une spécification de pod :

  1. Enregistrez l'un des exemples de fichiers manifestes de déploiement suivants, selon que vous activez GKE Sandbox à l'aide de ComputeClasses ou de pools de nœuds créés manuellement :

    • ComputeClasses :

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: sandbox-pod
        labels:
          environment: sandbox
      spec:
        replicas: 2
        selector:
          matchLabels:
            environment: sandbox
        template:
          metadata:
            labels:
              environment: sandbox
          spec:
            nodeSelector:
              cloud.google.com/compute-class: COMPUTECLASS_NAME
            runtimeClassName: SANDBOX_TYPE
            
            containers:
            - name: nginx
              image: nginx
      

      Remplacez les éléments suivants :

      • COMPUTECLASS_NAME : nom de la ComputeClass que vous avez créée, comme décrit dans Choisir un type de bac à sable pour les nœuds créés automatiquement.

      • SANDBOX_TYPE : type de bac à sable à utiliser pour les pods. Les valeurs suivantes sont acceptées :

        • gvisor
        • microvm

        Le type de bac à sable que vous spécifiez doit correspondre à celui que la classe ComputeClass sélectionnée permet.

    • Pools de nœuds créés manuellement :

      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: SANDBOX_TYPE
            containers:
            - name: httpd
              image: httpd
      

      Remplacez SANDBOX_TYPE par le type de bac à sable. Les valeurs suivantes sont acceptées :

      • gvisor
      • microvm

      Le type de bac à sable que vous spécifiez doit correspondre à celui d'un pool de nœuds existant dans le cluster.

  2. Créez le déploiement :

    kubectl apply -f PATH_TO_DEPLOYMENT_MANIFEST
    

    Remplacez PATH_TO_DEPLOYMENT_MANIFEST par le chemin d'accès au fichier manifeste Deployment.

  3. Vérifiez que les pods ont été créés :

    kubectl get pods
    

    Le résultat ressemble à ce qui suit :

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

Vous pouvez également demander des bacs à sable lorsque vous exécutez des pods sur un type de GPU compatible ou un type de TPU compatible à l'aide du champ runtimeClassName. Pour en savoir plus, consultez les documents suivants :

Exécuter un pod standard avec des pods en bac à sable

Les étapes de cette section s'appliquent aux charges de travail en mode Standard. Vous n'avez pas besoin d'exécuter des pods Standard avec des pods de bac à sable en mode Autopilot, car le modèle de tarification Autopilot élimine le besoin d'optimiser manuellement le nombre de pods programmés sur les nœuds.

Après avoir activé GKE Sandbox sur un pool de nœuds, vous pouvez exécuter des applications approuvées sur ces nœuds sans utiliser de bac à sable, à l'aide des paramètres de rejet et de tolérance de nœud. Ces pods sont appelés "pods standards" pour les distinguer des pods en bac à sable.

Comme les pods en bac à sable, les pods standards ne peuvent pas accéder aux autres servicesGoogle Cloud ni aux métadonnées du cluster. Cette protection fait partie de la configuration du nœud. Si vos pods standards ou en bac à sable nécessitent un accès aux servicesGoogle Cloud , utilisez la fédération d'identité de charge de travail pour GKE.

GKE Sandbox ajoute les étiquettes et les rejets suivants aux nœuds qui peuvent exécuter des pods en bac à sable :

  • L'étiquette de nœud sandbox.gke.io/runtime: SANDBOX_TYPE.
  • Rejet de nœud sandbox.gke.io/runtime=SANDBOX_TYPE:NoSchedule. Seuls les pods disposant d'une tolérance correspondante peuvent être planifiés sur le nœud.

Si vous utilisez le champ RuntimeClass pour exécuter un pod dans un bac à sable, GKE applique automatiquement une affinité de nœud et une tolérance au pod. Pour exécuter un pod standard sur un nœud qui utilise GKE Sandbox, vous devez appliquer manuellement les sélecteurs suivants à la spécification du pod :

  • Pour permettre à votre pod de s'exécuter sur des nœuds qui utilisent GKE Sandbox si nécessaire, ajoutez uniquement la tolérance pour le rejet de nœud.
  • Pour exécuter votre pod uniquement sur des nœuds qui utilisent GKE Sandbox, ajoutez un sélecteur de nœud et la tolérance pour le rejet de nœud.

Les étapes suivantes vous expliquent comment exécuter un pod standard sur un nœud qui utilise GKE Sandbox :

  1. Enregistrez le fichier manifeste de déploiement suivant sous le nom httpd-regular.yaml :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: httpd-regular
      labels:
        app: httpd-regular
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: httpd-regular
      template:
        metadata:
          labels:
            app: httpd-regular
        spec:
          containers:
          - name: httpd-regular
            image: httpd
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: sandbox.gke.io/runtime
                    operator: In
                    values:
                    - SANDBOX_TYPE
          tolerations:
            - effect: NoSchedule
              key: sandbox.gke.io/runtime
              operator: Equal
              value: SANDBOX_TYPE
    

    Remplacez SANDBOX_TYPE par le type de bac à sable, par exemple gvisor ou microvm.

  2. Créez le déploiement :

    kubectl apply -f httpd-regular.yaml
    

    Si le pod n'est pas programmable, vérifiez que l'affinité de nœud et la tolérance sont correctement définies dans le fichier manifeste du pod.

  3. Vérifiez que le pod ne se trouve pas dans un bac à sable :

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

    Le résultat ressemble à ce qui suit :

    httpd-db5899bc9-dk7lk: SANDBOX_TYPE
    httpd-regular-5bf87996c6-cfmmd:
    

    Le pod httpd-regular n'a pas de valeur RuntimeClass, ce qui signifie qu'il n'est pas dans un bac à sable.

  4. Vérifiez que le pod standard s'exécute sur un nœud qui utilise GKE Sandbox :

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

    Le résultat ressemble à ce qui suit :

    httpd-db5899bc9-dk7lk: gke-cluster-2-pool-1-75c8fc63-h373
    httpd-regular-5bf87996c6-cfmmd: gke-cluster-2-pool-1-75c8fc63-h373
    

    Le pod en bac à sable et le pod standard se trouvent sur le même nœud, ce qui indique que le pod standard s'exécute sur un nœud qui utilise GKE Sandbox.

Vérifier la configuration du bac à sable

Les sections suivantes vous expliquent comment vérifier qu'un pod s'exécute dans un bac à sable et que le pod en bac à sable est isolé du noyau hôte. Ces sections supposent que vous avez créé l'exemple de déploiement dans Demander un environnement de bac à sable pour un pod.

Vérifier qu'un pod s'exécute dans un bac à sable

Pour vérifier si vos pods utilisent un bac à sable, obtenez la classe RuntimeClass des pods. Cette méthode est plus fiable que l'exécution d'une commande à l'intérieur du pod, car vous ne verrez pas les données du bac à sable lui-même. Tout ce qui provient du bac à sable est considéré comme à risque, car il peut contenir des éléments défaillants ou malveillants.

  • Obtenez la valeur RuntimeClass de chaque pod en cours d'exécution :

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

    Le résultat ressemble à ce qui suit :

    httpd-db5899bc9-dk7lk: gvisor
    httpd-db5899bc9-ab3cd: gvisor
    

    Si le résultat indique gvisor ou microvm, le pod s'exécute dans un bac à sable.

Vérifier l'isolation des pods mis en bac à sable par rapport à l'hôte

Pour vérifier si un pod en bac à sable est isolé du nœud hôte, vérifiez les appareils virtuels disponibles et la version du noyau à laquelle le pod peut accéder.

  1. Pour les bacs à sable gVisor et microVM, vérifiez si la version du noyau à laquelle le pod peut accéder est différente de la version du noyau du nœud hôte :

    1. Obtenez la version du noyau à laquelle le pod peut accéder :

      kubectl exec POD_NAME -- uname -r
      

      Remplacez POD_NAME par le nom du pod.

      Le résultat ressemble à ce qui suit :

      4.19.0-gvisor
      
    2. Obtenez la version du noyau sur le nœud hôte :

      kubectl get node NODE_NAME \
          -o jsonpath='{.status.nodeInfo.kernelVersion}'
      

      Remplacez NODE_NAME par le nom du nœud qui exécute le pod.

      Le résultat ressemble à ce qui suit :

      6.12.94+
      

    La version de noyau du nœud hôte est différente de celle à laquelle le pod en bac à sable peut accéder, car le pod ne voit que le noyau de l'espace utilisateur pour gVisor ou le noyau invité pour les microVM.

  2. Pour les bacs à sable de microVM, vous pouvez également vérifier si les appareils auxquels le pod peut accéder sont virtualisés par Cloud Hypervisor :

    kubectl exec POD_NAME -- cat /sys/class/dmi/id/product_name
    

    Si le résultat est cloud-hypervisor, le pod se trouve dans un bac à sable de microVM.

Désactiver GKE Sandbox

Vous ne pouvez pas désactiver GKE Sandbox dans des clusters GKE Autopilot ou dans des pools de nœuds GKE Standard. Si vous souhaitez cesser d'utiliser GKE Sandbox, supprimez le pool de nœuds.

Étapes suivantes