GKE Sandbox

Nesta página, você vê como o GKE Sandbox protege o kernel do host nos nós quando contêineres no pod executam códigos desconhecidos ou não confiáveis. Por exemplo, clusters multilocatários, como provedores de Software as a Service (SaaS), geralmente executam código desconhecido enviado por usuários.

O GKE Sandbox usa o gVisor, um projeto de código aberto. Neste tópico, o gVisor é amplamente abordado, mas você encontra mais detalhes na documentação oficial dele (em inglês).

Visão geral

O GKE Sandbox fornece uma camada extra de segurança para evitar que um código não confiável afete o kernel do host nos nós do cluster. Antes de ver como o GKE Sandbox funciona, você precisa entender a natureza dos possíveis riscos que ele reduz.

Um ambiente de execução de contêiner, como docker ou containerd, fornece certo grau de isolamento entre os processos do contêiner e o kernel em execução no nó. No entanto, esse ambiente costuma ser executado como um usuário privilegiado no nó e tem acesso à maioria das chamadas do sistema no kernel do host.

Possíveis ameaças

Os clusters de multilocatários e os que têm contêineres que executam cargas de trabalho não confiáveis estão mais expostos a vulnerabilidades de segurança do que os outros. Os exemplos incluem fornecedores de SaaS, provedores de hospedagem na Web ou outras organizações que permitem que os usuários deles façam upload e executem código. Com uma falha no ambiente de execução de contêiner ou no kernel do host, um processo executado em um contêiner pode "escapar" dele e afetar o kernel do nó. Isso possivelmente pode interromper o nó.

Também há a possibilidade de um locatário mal-intencionado receber acesso e extrair dados de outro locatário na memória ou no disco, explorando esse tipo de falha.

Por fim, uma carga de trabalho não confiável pode acessar outros metadados de cluster ou serviços do Google Cloud.

Como o GKE Sandbox mitiga essas ameaças

O gVisor é uma reimplementação do espaço do usuário da API do kernel do Linux que não precisa de privilégios avançados. Com um ambiente de execução de contêiner, como containerd, o kernel do espaço do usuário reimplementa a maioria das chamadas do sistema e as veicula em nome do kernel do host. O acesso direto ao kernel do host é limitado. Consulte o Guia de arquitetura do gVisor (em inglês) para informações detalhadas sobre como ele funciona. Do ponto de vista do contêiner, o gVisor é quase imperceptível e não requer alterações no aplicativo em contêiner.

Quando você ativa o GKE Sandbox em um pool de nós, um sandbox é criado para cada pod sendo executado em um nó nesse pool. Além disso, os nós que executam pods em sandbox são impedidos de acessar outros metadados de cluster ou serviços do Google Cloud.

Cada sandbox usa seu próprio kernel do espaço do usuário. Com isso em mente, é possível tomar decisões sobre como agrupar os contêineres em pods com base no nível de isolamento necessário e nas características dos aplicativos.

O GKE Sandbox é ideal para os tipos de aplicativos a seguir. Consulte a seção Limitações para mais informações que ajudam você a decidir quais aplicativos colocar no sandbox.

  • Aplicativos não confiáveis ou de terceiros que usam ambientes de execução, como Rust, Java, Python, PHP, Node.js ou Golang.
  • Proxies, caches ou front-ends do servidor da Web.
  • Aplicativos que processam mídia ou dados externos com CPUs.
  • Cargas de trabalho de machine learning que usam CPUs.
  • Aplicativos que consomem muita memória ou CPU.

Outras recomendações de segurança

Ao usar o GKE Sandbox, você também precisa seguir estas recomendações:

  • É altamente recomendado especificar limites de recursos (em inglês) em todos os contêineres em execução em um sandbox. Isso evita o risco de um aplicativo defeituoso ou malicioso privar o nó de recursos e afetar negativamente outros aplicativos ou processos do sistema em execução no nó.

Limitações

O GKE Sandbox funciona bem com muitos aplicativos, mas não todos. Veja nesta seção mais informações sobre as limitações atuais do GKE Sandbox.

Configuração do pool de nós

  • Não é possível ativar o GKE Sandbox no pool de nós padrão.
  • Ao usar o GKE Sandbox, seu cluster precisa ter pelo menos dois pools de nós. É sempre necessário ter pelo menos um pool de nós em que o GKE Sandbox esteja desativado. Esse pool precisa conter pelo menos um nó, mesmo que todas as cargas de trabalho estejam no sandbox.

Acesso aos metadados do cluster

  • Os nós que executam pods em sandbox são impedidos de acessar os metadados do cluster no nível do sistema operacional no nó.
  • É possível executar pods regulares em um nó com o GKE Sandbox ativado. No entanto, por padrão, esses pods regulares não podem acessar os metadados de cluster ou serviços do Google Cloud. Use a Identidade da carga de trabalho para conceder aos pods acesso aos serviços do Google Cloud.

Hyper-Threading desativado

Os nós gVisor têm o Hyper-Threading desativado por padrão para reduzir as vulnerabilidades da amostragem de dados de microarquitetura (MDS, na sigla em inglês) anunciadas pela Intel. Para ativar o Hyper-Threading em um pool de nós:

  1. Crie um novo pool de nós no cluster com o rótulo cloud.google.com/gke-smt-disabled=false:

        gcloud container node-pools create smt-enabled --cluster=[CLUSTER_NAME] \
          --node-labels=cloud.google.com/gke-smt-disabled=false \
          --image-type=cos_containerd \
          --sandbox type=gvisor
        
  2. Implante o DaemonSet no pool de nós. O DaemonSet será executado somente em nós com o rótulo cloud.google.com/gke-smt-disabled=false. Com ele, você ativa o Hyper-Threading e reinicializa o nó.

        kubectl create -f \
          https://raw.githubusercontent.com/GoogleCloudPlatform/\
          k8s-node-tools/master/disable-smt/gke/enable-smt.yaml
        
  3. Após a reinicialização do nó, verifique se os pods do DaemonSet estão em execução.

        kubectl get pods --selector=name=enable-smt -n kube-system
        
  4. Você receberá uma resposta semelhante a:

        NAME               READY     STATUS    RESTARTS   AGE
        enable-smt-2xnnc   1/1       Running   0          6m
        
  5. Verifique se SMT has been enabled aparece nos registros dos pods.

        kubectl logs enable-smt-2xnnc enable-smt -n kube-system
        

Recursos

Por padrão, o contêiner é impedido de abrir soquetes básicos para reduzir o potencial de ataques mal-intencionados. Algumas ferramentas relacionadas à rede, como ping e tcpdump, criam soquetes básicos como parte da funcionalidade principal delas. Para ativar esses soquetes, adicione explicitamente o recurso NET_RAW ao contexto de segurança do contêiner:

spec:
      containers:
      - name: my-container
        securityContext:
          capabilities:
            add: ["NET_RAW"]
    

Dependências externas

Códigos não confiáveis em execução no sandbox podem conseguir acessar serviços externos, como servidores de banco de dados, APIs, outros contêineres e drivers CSI (em inglês). Esses serviços são executados fora do limite do sandbox e precisam ser protegidos separadamente. Um invasor pode tentar explorar as vulnerabilidades nesses serviços para escapar do sandbox. Você precisa considerar o risco e o impacto causados pelo acesso do código executado no sandbox e tomar as medidas necessárias para protegê-los.

Isso inclui implementações do sistema de arquivos de volumes de contêiner, como drivers CSI e ext4. Os drivers CSI são executados fora do isolamento do sandbox e podem ter acesso privilegiado ao host e aos serviços. Uma violação desses drivers afeta o kernel do host e compromete o nó inteiro. É recomendável que você execute o driver CSI em um contêiner com a menor quantidade de permissões necessárias, para reduzir a exposição em caso de exploração. O driver CSI do Persistent Disk do Compute Engine é compatível para ser usado com o GKE Sandbox.

Recursos incompatíveis

No momento, não é possível usar o GKE Sandbox com os recursos do Kubernetes a seguir:

  • Aceleradores como GPUs ou TPUs.
  • Istio.
  • Monitoramento de estatísticas no nível do pod ou contêiner.
  • Armazenamento do Hostpath (em inglês).
  • Os limites de CPU e memória são aplicados somente a pods garantidos e com burst. Isso é feito apenas quando esses limites são especificados em todos os contêineres em execução no pod.
  • Pods que usam PodSecurityPolicies (em inglês) e especificam namespaces de host, como hostNetwork, hostPID, hostIPC.
  • Pods usando as configurações do PodSecurityPolicy, como modo privilegiado (em inglês).
  • VolumeDevices (em inglês).
  • Portforward (em inglês).
  • Módulos de segurança do kernel do Linux, como Seccomp, Apparmor ou Selinux Sysctl, NoNewPrivileges, MountPropagation bidirecional, FSGroup ou ProcMount (páginas em inglês).

Características da carga de trabalho

Impor uma camada extra de indireção para acessar o kernel do nó tem vantagens e desvantagens de desempenho. O GKE Sandbox fornece os melhores benefícios nos clusters grandes de multilocatários em que o isolamento é importante. Siga as diretrizes a seguir ao testar suas cargas de trabalho com o GKE Sandbox.

Chamadas do sistema

As cargas de trabalho que geram um volume elevado de chamadas de sistema com baixa sobrecarga, como uma quantidade grande de operações pequenas de E/S, podem exigir mais recursos do sistema durante a execução em um sandbox. Por isso, talvez seja necessário usar nós mais avançados ou adicionar mais nós ao cluster.

Acesso direto ao hardware ou à virtualização

Se a carga de trabalho precisar de qualquer um dos itens a seguir, o GKE Sandbox talvez não seja adequado porque ele impede o acesso direto ao kernel do host no nó:

  • Acesso direto ao hardware do nó
  • Recursos de virtualização no nível do kernel
  • Contêineres privilegiados

A seguir