GKE Sandbox

Nesta página, você verá 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 como serviço (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 é abordado mais amplamente, mas é possível saber mais detalhes na documentação oficial do gVisor (em inglês).

Para informações detalhadas sobre como ativar o GKE Sandbox, consulte Configurar o GKE Sandbox.

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 discutir como o GKE Sandbox funciona, é bom entender a natureza dos riscos potenciais que ele ajuda a mitigar.

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

Ameaças em potencial

Clusters de multilocação e clusters 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 outros clusters. Os exemplos incluem provedores de SaaS, provedores de hospedagem na Web ou outras organizações que permitem que os usuários deles façam upload e executem códigos. Com uma falha no ambiente de execução do contêiner ou no kernel do host, é possível que um processo executado em um contêiner "escape" do contêiner e afete o kernel do nó, possivelmente derrubando o nó.

Também existe a possibilidade de um locatário mal-intencionado ter 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 elevados. Em conjunto com um ambiente de execução do contêiner, como containerd, o kernel do espaço do usuário reimplementa a maioria das chamadas do sistema e as atende 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 isso funciona. Do ponto de vista do contêiner, o gVisor é quase transparente 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 executado em um nó nesse pool. Além disso, os nós que executam pods na 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 seus contêineres nos pods, com base no nível de isolamento necessário e nas características dos aplicativos.

O GKE Sandbox é ideal para os seguintes tipos de aplicativos. Consulte a parte de limitações para mais informações. Elas ajudarão você a decidir quais aplicativos serão colocados 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 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, aconselhamos que você também siga estas recomendações:

  • É altamente recomendado especificar os 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. Você verá 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 suas cargas de trabalho estejam no sandbox.
  • O pool de nós não pode usar os tipos de máquina e2-micro, e2-small e e2-medium.

Acesso aos metadados do cluster

  • Os nós que executam os Pods no 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 do gVisor têm o Hyper-Threading desativado por padrão em todas as arquiteturas para reduzir as vulnerabilidades de canais secundários que aproveitam o estado principal compartilhado entre os hyper-threads. Por exemplo, vulnerabilidade de amostragem de dados de micro-arquitetônica (MDS, na sigla em inglês). Para ativar o Hyper-Threading para um pool de nós:

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

    gcloud container node-pools create smt-enabled --cluster=cluster-name \
        --machine-type=machine-type \
        --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. Ele ativará o Hyper-Threading e reinicializará 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 brutos para reduzir o potencial de ataques mal-intencionados. Algumas ferramentas relacionadas à rede, como ping e tcpdump, criam soquetes brutos como parte da funcionalidade principal delas. Para ativar soquetes brutos, 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 seguintes recursos do Kubernetes:

  • 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 para pods garantidos e com burst e somente quando esses limites são especificados para todos os contêineres em execução no pod.
  • Pods usando PodSecurityPolicies (em inglês) que 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).
  • Traffic Director

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 oferece benefícios mais evidentes em clusters de multilocatários grandes em que o isolamento é importante. Pense nas seguintes diretrizes ao testar suas cargas de trabalho com o GKE Sandbox.

Chamadas do sistema

Cargas de trabalho que geram um grande volume de chamadas de sistema com baixa sobrecarga, como um grande número 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 poderosos 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 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