Isolar cargas de trabalho usando o GKE Sandbox

É possível proteger o kernel do host dos nós do Google Kubernetes Engine (GKE) contra contêineres que executam código desconhecido ou não confiável usando o GKE Sandbox. Este documento mostra aos especialistas em segurança como ativar o GKE Sandbox, executar pods em sandboxes e verificar o isolamento.

É preciso conhecer o GKE Sandbox.

Tipos de sandbox disponíveis

O GKE Sandbox é compatível com os seguintes tipos de sandbox, cada um usando uma tecnologia específica para separar o código do aplicativo do kernel do host:

  • gvisor: uma reimplementação do espaço do usuário da API do kernel do Linux que não precisa de privilégios elevados. O kernel do espaço do usuário intercepta e atende à maioria das chamadas do sistema em nome do kernel do host, o que limita o acesso direto a ele.
  • microvm: VMs leves aninhadas na VM host usando a virtualização aninhada. Cada pod no nó é executado na própria VM aninhada com o próprio kernel convidado. Como o código é executado em uma VM dedicada, esse tipo de sandbox oferece um isolamento mais forte do que as sandboxes do gVisor.

Para mais informações sobre como cada tipo de sandbox funciona e quando usar um tipo específico, consulte Sobre o GKE Sandbox.

Limitações

O GKE Sandbox e tecnologias específicas de sandbox têm várias limitações, como suporte a GPU e TPU ou a recursos específicos do Linux e do Kubernetes. Para mais informações, consulte Limitações.

Antes de começar

Antes de começar, verifique se você realizou as tarefas a seguir:

  • Ative a API Google Kubernetes Engine.
  • Ativar a API Google Kubernetes Engine
  • Para usar a Google Cloud CLI nesta tarefa, instale e inicialize a CLI gcloud. Se você instalou a CLI gcloud anteriormente, instale a versão mais recente executando o comando gcloud components update. Talvez as versões anteriores da CLI gcloud não sejam compatíveis com a execução dos comandos neste documento.

Escolher um tipo de sandbox para nós criados automaticamente

É possível usar ComputeClasses com o modo Autopilot ou a criação automática de pool de nós para ativar o GKE Sandbox em nós criados pelo GKE. Nos clusters do Autopilot, o gVisor é compatível por padrão. Portanto, é possível omitir a configuração do sandbox da ComputeClass.

Para configurar o GKE Sandbox para nós criados automaticamente, siga estas etapas:

  1. Conecte-se a um cluster do Autopilot ou Standard:

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

    Substitua:

    • CLUSTER_NAME: o nome do cluster.
    • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster.
  2. Salve um dos seguintes manifestos do ComputeClass, dependendo da tecnologia de sandbox que você quer:

    • 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
      

      A ComputeClass para sandboxes de microVMs ativa a virtualização aninhada usando o campo enableNestedVirtualization. Esse campo é obrigatório para sandboxes de microVMs. Para usar esse campo, o cluster precisa executar a versão 1.37.0-gke.4713000 ou mais recente.

    Esses exemplos de manifestos usam o campo nodePoolAutoCreation para ativar a criação automática de pools de nós. Também é possível especificar a configuração da sandbox em uma ComputeClass que usa o campo autopilot para executar pods no modo Autopilot. Se você usa clusters do Autopilot, o GKE ignora os campos nodePoolAutoCreation e autopilot.

  3. Crie a ComputeClass:

    kubectl apply -f PATH_TO_COMPUTE_CLASS_MANIFEST
    

    Substitua PATH_TO_COMPUTE_CLASS_MANIFEST pelo caminho para o manifesto da ComputeClass.

Para selecionar essa ComputeClass e solicitar um ambiente de sandbox, consulte Solicitar um ambiente de sandbox para um pod.

Escolher um tipo de sandbox ao criar pools de nós

É possível ativar manualmente o GKE Sandbox ao criar um novo pool de nós em um cluster Standard. As limitações a seguir se aplicam quando você ativa manualmente o GKE Sandbox:

  • Para ativar o GKE Sandbox durante a criação do cluster Standard, é preciso configurar pelo menos um pool de nós extra. O pool de nós extra é necessário porque o GKE precisa de pelo menos um pool de nós no cluster que não use o GKE Sandbox para executar cargas de trabalho do sistema gerenciadas pelo GKE. Se você usar a CLI gcloud para criar o cluster, primeiro crie o cluster e depois um pool de nós que use o GKE Sandbox.
  • Para selecionar o tipo de sandbox de microVM, use a CLI gcloud ou a API GKE. O consoleGoogle Cloud não permite selecionar o tipo de sandbox de microVM.

Ativar o tipo de sandbox do gVisor

Para ativar manualmente os sandboxes do gVisor ao criar um pool de nós, selecione uma das seguintes opções:

Console

  1. No console do Google Cloud , acesse a página de clusters do Kubernetes.

    Acessar os clusters do Kubernetes

  2. Clique no nome do cluster que você quer modificar. A página Detalhes do cluster é aberta.

  3. Clique na guia Nós.

  4. Na seção Pools de nós, clique em Adicionar pool de nós gerenciado pelo usuário. A página Adicionar um pool de nós é aberta.

  5. No menu de navegação, clique em Nós e defina as seguintes configurações:

    1. Na lista suspensa Tipo de imagem, selecione Container-Optimized OS com Containerd (cos_containerd).
    2. Na seção Configuração da máquina, selecione uma série e um tipo de máquina para os nós.
    3. Opcional: selecione um tipo de GPU compatível ou um tipo de TPU compatível.
  6. No menu de navegação, clique em Segurança. A página Segurança do nó é aberta.

  7. Marque a caixa de seleção Ativar sandbox com gVisor.

  8. Para criar o pool de nós, clique em Criar.

gcloud

Para criar um pool de nós que use o gVisor para sandboxes, execute o seguinte comando:

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

Substitua:

  • NODE_POOL_NAME: um nome para o pool de nós.
  • CLUSTER_NAME: o nome do cluster.
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster.

Também é possível ativar sandboxes do gVisor ao criar pools de nós que usam um tipo de GPU compatível ou um tipo de TPU compatível. Para mais informações, consulte os seguintes documentos:

Ativar o tipo de sandbox de microVM

É possível ativar o tipo de sandbox de microVM ao criar um pool de nós usando a CLI gcloud ou a API GKE. O console do Google Cloud não permite ativar o tipo de sandbox de microVM. Para criar um pool de nós que use sandboxes de microVM, execute o seguinte comando:

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

Substitua:

  • NODE_POOL_NAME: um nome para o pool de nós.
  • CLUSTER_NAME: o nome do cluster.
  • CONTROL_PLANE_LOCATION: a região ou zona do plano de controle do cluster.
  • MACHINE_TYPE: o tipo de máquina dos nós. Esse valor precisa ser um tipo de máquina que ofereça suporte à virtualização aninhada. Para mais informações, consulte a linha Virtualização aninhada na tabela de comparação de séries de máquinas.

Ativar monitoramento e geração de registros

Para coletar e conferir registros e métricas das suas sandbox, verifique se o cluster ativa os seguintes serviços de observabilidade:

Esses serviços são ativados por padrão em todos os novos clusters do GKE.

Solicitar um ambiente de sandbox para um pod

Para executar um pod específico em uma sandbox, especifique a RuntimeClass gvisor ou microvm na especificação do pod. O GKE programa o pod em nós que usam o tipo de sandbox especificado. Para selecionar um tipo de sandbox em uma especificação de pod, siga estas etapas:

  1. Salve um dos seguintes exemplos de manifestos de implantação, dependendo de como você ativa o GKE Sandbox: usando ComputeClasses ou pools de nós criados manualmente:

    • 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
      

      Substitua:

      • COMPUTECLASS_NAME: o nome da ComputeClass que você criou, conforme descrito em Escolher um tipo de sandbox para nós criados automaticamente.

      • SANDBOX_TYPE: o tipo de sandbox a ser usado para os pods. Os valores a seguir são compatíveis:

        • gvisor
        • microvm

        O tipo de sandbox especificado precisa corresponder ao tipo que a ComputeClass selecionada ativa.

    • Pools de nós criados manualmente:

      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
      

      Substitua SANDBOX_TYPE pelo tipo de sandbox. Os valores a seguir são compatíveis:

      • gvisor
      • microvm

      O tipo de sandbox especificado precisa corresponder ao tipo de sandbox de um pool de nós existente no cluster.

  2. Crie a implantação:

    kubectl apply -f PATH_TO_DEPLOYMENT_MANIFEST
    

    Substitua PATH_TO_DEPLOYMENT_MANIFEST pelo caminho para o manifesto de implantação.

  3. Verifique se os pods foram criados:

    kubectl get pods
    

    O resultado será o seguinte:

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

Você também pode solicitar sandboxes ao executar pods em um tipo de GPU compatível ou um tipo de TPU compatível usando o campo runtimeClassName. Para mais informações, consulte os seguintes documentos:

Executar um pod normal junto com pods no sandbox

As etapas nesta seção se aplicam às cargas de trabalho do modo Standard. Não é preciso executar pods regulares com os pods do sandbox no modo do Autopilot, porque o modelo de preços do Autopilot elimina a necessidade de otimizar manualmente o número de pods programados nos nós.

Depois de ativar o GKE Sandbox em um pool de nós, é possível executar aplicativos confiáveis nesses nós sem usar um sandbox, com tolerâncias e taints de nó. Esses pods são chamados de “pods normais” para diferenciá-los dos pods em sandbox.

Os pods regulares, assim como os pods em sandbox, são impedidos de acessar outros serviçosGoogle Cloud ou metadados do cluster. Essa prevenção faz parte da configuração do nó. Se os pods regulares ou no sandbox exigirem acesso aos serviços doGoogle Cloud , use a Federação de Identidade da Carga de Trabalho para GKE.

O GKE Sandbox adiciona o seguinte rótulo e taint aos nós que podem executar pods no sandbox:

  • O rótulo do nó sandbox.gke.io/runtime: SANDBOX_TYPE.
  • O taint de nó sandbox.gke.io/runtime=SANDBOX_TYPE:NoSchedule. Somente pods com uma tolerância correspondente podem ser programados no nó.

Se você usar o campo RuntimeClass para executar um pod em um sandbox, o GKE vai aplicar automaticamente uma afinidade de nó e uma tolerância ao pod. Para executar um pod normal em um nó que usa o GKE Sandbox, aplique manualmente os seguintes seletores à especificação do pod:

  • Para permitir que o pod seja executado em nós que usam o GKE Sandbox quando necessário, adicione apenas a tolerância para o taint do nó.
  • Para executar o pod apenas em nós que usam o GKE Sandbox, adicione um seletor de nós e a tolerância para o taint de nós.

As etapas a seguir mostram como executar um pod regular em um nó que usa o GKE Sandbox:

  1. Salve o seguinte manifesto de implantação como 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
    

    Substitua SANDBOX_TYPE pelo tipo de sandbox, como gvisor ou microvm.

  2. Crie a implantação:

    kubectl apply -f httpd-regular.yaml
    

    Se o pod não puder ser programado, verifique se a afinidade de nó e a tolerância estão definidas corretamente no manifesto do pod.

  3. Verifique se o pod não está em um sandbox:

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

    O resultado será o seguinte:

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

    O pod httpd-regular não tem um valor de RuntimeClass, o que significa que ele não está em uma sandbox.

  4. Verifique se o pod regular está sendo executado em um nó que usa o GKE Sandbox:

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

    O resultado será o seguinte:

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

    O pod no sandbox e o pod normal estão no mesmo nó, o que indica que o pod normal está sendo executado em um nó que usa o GKE Sandbox.

Verificar a configuração do sandbox

As seções a seguir mostram como verificar se um pod está sendo executado em uma sandbox e se o pod em sandbox está isolado do kernel do host. Estas seções pressupõem que você criou o exemplo de implantação em Solicitar um ambiente de sandbox para um pod.

Verificar se um pod está sendo executado em um sandbox

Para verificar se os pods usam uma sandbox, extraia a RuntimeClass deles. Esse método é mais confiável do que executar um comando dentro do pod, porque você não verá dados de dentro do próprio sandbox. Qualquer item do sandbox que seja reportado não é confiável, porque pode estar com erros ou ser malicioso.

  • Confira a RuntimeClass de cada pod em execução:

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

    O resultado será o seguinte:

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

    Se a saída mostrar gvisor ou microvm, o pod estará sendo executado em um sandbox.

Verificar o isolamento de pods em sandbox do host

Para verificar se um pod no modo sandbox está isolado do nó host, confira os dispositivos virtuais disponíveis e a versão do kernel que o pod pode acessar.

  1. Para sandboxes gVisor e microVM, verifique se a versão do kernel que o pod pode acessar é diferente da versão do kernel do nó do host:

    1. Confira a versão do kernel que o pod pode acessar:

      kubectl exec POD_NAME -- uname -r
      

      Substitua POD_NAME pelo nome do pod.

      O resultado será o seguinte:

      4.19.0-gvisor
      
    2. Encontre a versão do kernel no nó host:

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

      Substitua NODE_NAME pelo nome do nó que executa o pod.

      O resultado será o seguinte:

      6.12.94+
      

    A versão do kernel do nó host é diferente da versão do kernel que o pod em sandbox pode acessar, porque o pod vê apenas o kernel do espaço do usuário para o gVisor ou o kernel convidado para microVMs.

  2. Para sandboxes de microVM, também é possível verificar se os dispositivos que o pod pode acessar são virtualizados pelo Cloud Hypervisor:

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

    Se a saída for cloud-hypervisor, o pod está em um sandbox de microVM.

Desativar o GKE Sandbox

Não é possível desativar o GKE Sandbox em clusters Autopilot do GKE ou em pools de nós GKE Standard. Se você quiser parar de usar o GKE Sandbox, exclua o pool de nós.

A seguir