Multilocação de cluster

Nesta página, você verá uma explicação sobre a multilocação de cluster no Google Kubernetes Engine (GKE). Esse conceito inclui tanto clusters compartilhados por usuários diferentes em uma única organização quanto clusters compartilhados por instâncias por cliente de um aplicativo de Software as a Service (SaaS). A multilocação de cluster é uma alternativa ao gerenciamento de muitos clusters com um único locatário.

Você também encontrará nesta página um resumo dos recursos do Kubernetes e do GKE que podem ser usados para gerenciar clusters multilocatários.

O que é multilocação?

Um cluster multilocatário é compartilhado por vários usuários e/ou cargas de trabalho, chamados de “locatários”. Os operadores desse tipo de cluster precisam isolar os locatários uns dos outros para minimizar o dano que um locatário comprometido ou mal-intencionado pode causar ao cluster e aos outros locatários. Além disso, é necessário alocar os recursos do cluster de maneira justa entre os locatários.

Ao planejar uma arquitetura multilocatária, pense nas camadas de isolamento de recursos no Kubernetes: cluster, namespace, nó, pod e contêiner. Pense também nas implicações na segurança que resultarão do compartilhamento de tipos diferentes de recursos entre os locatários. Por exemplo, programar pods de locatários diferentes no mesmo nó pode reduzir o número de máquinas necessárias no cluster. Por outro lado, talvez seja necessário impedir que determinadas cargas de trabalho sejam colocalizadas. Por exemplo, é possível proibir que códigos não confiáveis provenientes de fora da organização sejam executados no mesmo nó dos contêineres que processam informações confidenciais.

O Kubernetes não garante um isolamento perfeitamente seguro entre os locatários, mas oferece recursos que podem ser suficientes para casos de uso específicos. É possível separar cada locatário e respectivos recursos do Kubernetes nos próprios namespaces deles. Depois, use as políticas para impor o isolamento entre locatários. Geralmente, essas políticas têm o escopo definido por namespace e podem ser usadas para restringir o acesso a APIs, limitar o uso de recursos e determinar o que os contêineres podem fazer.

Os locatários de um cluster desse tipo compartilham:

A operação de um cluster multilocatário apresenta várias vantagens em comparação com a operação de vários clusters com um único locatário:

  • Redução nos esforços de gerenciamento.
  • Redução na fragmentação de recursos.
  • Eliminação da necessidade de esperar pela criação de um cluster para cada locatário novo.

Casos de uso de multilocação

Nesta seção, você descobrirá como configurar um cluster para vários casos de uso de multilocação.

Multilocação empresarial

Em um ambiente empresarial, os locatários de um cluster são equipes distintas dentro da organização. Normalmente, cada locatário tem um namespace correspondente. Modelos alternativos de multilocação com um locatário por cluster ou por projeto doCloud de Confiance são mais difíceis de gerenciar. O tráfego de rede dentro de um namespace é irrestrito. É preciso permitir explicitamente o tráfego de rede entre namespaces. Essas políticas podem ser aplicadas usando a política de rede do Kubernetes.

Os usuários do cluster são divididos em três papéis diferentes, dependendo do privilégio de cada um:

Administrador do cluster
Esse papel cabe aos administradores do cluster inteiro, que gerenciam todos os locatários. Os administradores do cluster podem criar, ler, atualizar e excluir qualquer objeto de política. Eles podem criar namespaces e atribuí-los a administradores de namespace.
Administrador de namespace
Esse papel é atribuído aos administradores de locatários únicos e específicos. Um administrador de namespace pode gerenciar os usuários incluídos em seu próprio namespace.
Desenvolvedor
Os membros com esse papel podem criar, ler, atualizar e excluir objetos em namespace e não relacionados a política, como pods, jobs, e entradas. Os desenvolvedores têm esses privilégios apenas nos namespaces a que eles têm acesso.

Para informações sobre como configurar vários clusters multilocatários para uma organização empresarial, consulte Práticas recomendadas para multilocação empresarial.

Multilocação de provedor de SaaS

Os locatários de um cluster de provedor de SaaS são as instâncias por cliente do aplicativo e o plano de controle do SaaS. Para aproveitar as políticas com escopo por namespace, é necessário que as instâncias do aplicativo sejam organizadas nos próprios namespaces delas, assim como os componentes do plano de controle do SaaS. Os usuários finais não podem interagir diretamente com o plano de controle do Kubernetes. Em vez disso, eles usam a interface do SaaS que, por sua vez, interage com o plano de controle do Kubernetes.

Por exemplo, uma plataforma de blog pode ser executada em um cluster multilocatário. Nesse caso, os locatários são as instâncias de blog de cada cliente e o próprio plano de controle da plataforma. O plano de controle da plataforma e cada blog hospedado são executados em namespaces separados. Os clientes criam e excluem blogs e atualizam as versões do software por meio da interface da plataforma, sem visibilidade de como o cluster opera.

Aplicação de políticas de multilocação

O GKE e o Kubernetes fornecem vários recursos que podem ser usados para gerenciar clusters multilocatários. Leia nas seções a seguir uma visão geral desses recursos.

Controle de acesso

O GKE tem dois sistemas de controle de acesso: o gerenciamento de identidade e acesso (IAM) e o controle de acesso baseado em papéis (RBAC, na sigla em inglês). O IAM é o sistema controle de acesso do Cloud de Confiancepara gerenciar a autenticação e a autorização de recursos do Cloud de Confiance. Use o IAM para conceder aos usuários acesso a recursos do GKE e do Kubernetes. O RBAC vem incorporado ao Kubernetes e concede permissões granulares para operações e recursos específicos dentro dos clusters.

Consulte a Visão geral do controle de acesso para mais informações sobre essas opções e quando usar cada uma delas.

Consulte o Guia de instruções do RBAC e o Guia de instruções do IAM para saber como usar esses sistemas de controle de acesso.

É possível usar as permissões do IAM e do RBAC juntas com namespaces para restringir interações de usuários com recursos de cluster no console Cloud de Confiance . Saiba mais em Ativar acesso e visualização de recursos do cluster por namespace.

Políticas de rede

As políticas de rede do cluster dão a você o controle sobre a comunicação entre os pods do cluster. Elas especificam com quais namespaces, rótulos e intervalos de endereços IP um pod pode se comunicar.

Consulte o guia de instruções das políticas de rede para saber como ativar a aplicação delas no GKE.

Siga o tutorial das políticas de rede para aprender como escrevê-las.

Cotas de recursos

As cotas de recursos gerenciam a quantidade de recursos usada pelos objetos em um namespace. É possível defini-las em termos de uso de CPU e memória ou de contagens de objetos. Com as cotas de recursos, é possível garantir que nenhum locatário use mais recursos do cluster do que a parcela atribuída a ele.

Consulte a documentação sobre cotas de recursos para mais informações.

Controle de admissão de pods com base em políticas

Para evitar que pods que violam seus limites de segurança sejam executados no cluster, use um controlador de admissão. Os controladores de admissão podem verificar as especificações do pod em relação às políticas definidas por você e impedir que pods que violam essas políticas sejam executados no cluster.

O GKE aceita os seguintes tipos de controle de admissão:

Antiafinidade de pods

É possível usar a Antiafinidade de pods para impedir que pods de locatários diferentes sejam programados no mesmo nó. As restrições antiafinidade são baseadas nos rótulos dos pods. Por exemplo, a especificação de pod abaixo descreve um pod com o rótulo "team": "billing" e uma regra antiafinidade que impede que o pod seja programado com pods sem o rótulo.

apiVersion: v1
kind: Pod
metadata:
  name: bar
  labels:
    team: "billing"
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - topologyKey: "kubernetes.io/hostname"
        labelSelector:
          matchExpressions:
          - key: "team"
            operator: NotIn
            values: ["billing"]

A desvantagem dessa técnica é que usuários mal-intencionados podem burlar a regra aplicando o rótulo team: billing para um pod arbitrário. Por si só, o uso de antiafinidade de pods não garante que a política seja aplicada com segurança em clusters com locatários não confiáveis.

Consulte a documentação sobre antiafinidade de pods para mais informações.

Nós dedicados com taints e tolerâncias

Os taints de nó são outra maneira de controlar a programação de cargas de trabalho. É possível usá-los para reservar nós especializados a serem usados por determinados locatários. Por exemplo, é possível dedicar nós equipados com GPU a locatários específicos com cargas de trabalho que exigem GPUs. Para clusters do piloto automático, as tolerâncias de nós são compatíveis apenas com a separação de carga de trabalho. Os taints de nó são adicionados automaticamente pelo provisionamento automático de nós, conforme necessário.

Para dedicar um pool de nós a um determinado locatário, aplique um taint com effect: "NoSchedule" ao pool de nós. Assim, apenas os pods com tolerância correspondente poderão ser programados para os nós no pool.

A desvantagem dessa técnica é que usuários mal-intencionados podem adicionar uma tolerância aos pode deles para ter acesso ao pool de nós dedicado. Por si só, o uso de tolerâncias e taints de nós não garante que a política seja aplicada com segurança em clusters com locatários não confiáveis.

Para mais informações, consulte Taints e tolerâncias na documentação do Kubernetes.

GKE Sandbox

O GKE Sandbox oferece uma camada extra de segurança para clusters multilocatários ao isolar cargas de trabalho não confiáveis do kernel do host nos nós do cluster. O GKE Sandbox usa o gVisor, uma tecnologia de sandbox de contêiner de código aberto, para fornecer um kernel de espaço do usuário separado para cada pod.

O GKE Sandbox é especialmente útil para provedores de SaaS ou organizações que executam código não confiável, porque ajuda a evitar que um locatário malicioso escape do contêiner ou afete o kernel do host. Para mais informações, consulte GKE Sandbox.

Gerenciamento de memória multilocatário

O kernel do Linux garante que as páginas de memória alocadas para novos processos sejam preenchidas com zeros (limpas) no momento da alocação. Esse processo também se aplica à criação de contêineres e impede que um novo contêiner leia dados residuais deixados na memória por um contêiner anterior. No entanto, esse é um limite lógico gerenciado pelo sistema operacional do host. Invasores que saem de um contêiner ou usuários com privilégios de raiz na VM do nó podem ignorar essas proteções para acessar o conteúdo bruto da memória de outros contêineres.

Para reforçar esse limite, use o GKE Sandbox para proteger contra invasões de contêineres, use uma política de admissão para restringir o acesso dos pods ao host e limite o acesso direto aos nós.

Os recursos padrão de GPU e TPU não limpam automaticamente a memória de alta largura de banda (HBM), a RAM estática (SRAM) ou os registros de controle entre as atribuições de pods. Dados residuais de uma carga de trabalho anterior podem persistir nas memórias do acelerador. Se a VM não for reinicializada entre as cargas de trabalho, a configuração será adequada apenas para multitenancy confiável, em que todas as cargas de trabalho programadas no mesmo acelerador compartilham a mesma sensibilidade de segurança.

Para cargas de trabalho sem confiança mútua, é necessário reiniciar a VM para limpar a memória do acelerador entre cada carga de trabalho programada. A exclusão da VM também faz com que a memória seja limpa antes que o acelerador seja reconectado a uma nova VM. Para mais informações sobre configuração e compartilhamento de aceleradores, consulte a documentação de TPU e GPU do GKE.

Compartilhamento de aceleradores, como GPUs e TPUs

Compartilhar aceleradores de GPU ou TPU entre pods acarreta riscos adicionais. As GPUs e TPUs podem ou não oferecer proteção contra acesso compartilhado. Essas proteções podem depender da versão do hardware, da versão do driver e da configuração do sistema de execução. A tabela a seguir destaca diferentes abordagens e o risco associado a cada uma delas.

Os pods que confiam uns nos outros podem decidir aceitar um amplo espectro de risco. A tabela indica o nível de risco para cada nível de isolamento.

Arquitetura Superfície de ataque principal Resumo de segurança
Os pods no mesmo nó compartilham diretamente um acelerador, incluindo o compartilhamento de tempo da GPU e o NVIDIA MPS. Memória da GPU e estado global Os pods são vulneráveis e precisam confiar uns nos outros.
Os pods no mesmo nó compartilham diretamente um acelerador e usam o GKE Sandbox, incluindo o compartilhamento de tempo de GPU e o NVIDIA MPS. Memória da GPU e driver do host O GKE Sandbox isola o kernel da carga de trabalho do kernel do host. Embora o gVisor reduza a superfície de ataque da GPU exposta ao aplicativo, ele não oferece separação dentro do ambiente da GPU, que permanece compartilhado. Para mais informações, consulte: Suporte a GPU: segurança.
Os pods no mesmo nó têm aceleradores dedicados, incluindo MIGs da NVIDIA. Kernel do host (via driver) Os pods ainda podem ser comprometidos por vulnerabilidades de acelerador ou driver que permitem o escalonamento para o kernel do host.
Os pods no mesmo nó têm aceleradores dedicados, incluindo MIGs da NVIDIA, e usam o GKE Sandbox. Interface do driver do host (nvproxy) O GKE Sandbox isola o kernel, mas a interface do driver de GPU do host (nvproxy) continua sendo uma superfície de ataque compartilhada. Uma exploração de driver pode permitir o escape do kernel do host. Também é possível que ocorram vazamentos de canal lateral entre instâncias do MIG.
Cada pod é executado em um nó dedicado, que tem aceleradores dedicados. Limite da VM / hipervisor Recomendado para cargas de trabalho não confiáveis. Qualquer comprometimento fica restrito a uma VM.

A seguir