"Cada time no seu namespace" é a resposta padrão quando se pergunta como separar equipes no mesmo cluster. É um bom começo e é uma resposta perigosa se parar aí, porque contém uma suposição falsa: namespace não é uma fronteira de segurança.
Namespace é um agrupamento de nomes. Ele separa objetos e permite aplicar políticas — mas, sozinho, não impede que um pod de um namespace converse com outro, consuma todos os recursos do cluster ou alcance o nó por baixo.
O isolamento real vem de camadas que precisam ser configuradas explicitamente. Este texto cobre quais são, e onde está o limite do que dá para fazer em um cluster só.
As camadas
| Camada | Mecanismo | Sem ela |
|---|---|---|
| Nomes e objetos | Namespace | Colisão e confusão |
| Permissão | RBAC | Qualquer um lê e altera tudo |
| Rede | NetworkPolicy | Todo pod fala com todo pod |
| Recursos | ResourceQuota, LimitRange | Um time consome o cluster |
| Execução | Pod Security, políticas de admissão | Pod privilegiado alcança o nó |
| Nós | Taints, tolerations, afinidade | Cargas dividem hardware sem controle |
Falhar em qualquer uma compromete o conjunto. E a mais subestimada é a de rede, porque o padrão do Kubernetes é permitir tudo.
Rede: o padrão é o pior possível
Em cluster sem NetworkPolicy, qualquer pod alcança qualquer outro pod, em qualquer namespace. O banco de dados do time A é acessível a partir de um pod do time B. Um pod comprometido varre o cluster inteiro sem obstáculo.
O desenho correto começa por negar:
- Política padrão de negação de entrada em todo namespace. Nada entra a menos que uma política permita.
- Liberações explícitas: o namespace da aplicação pode alcançar o do banco, na porta específica.
- Negação de saída para destinos sensíveis, no mínimo. Bloquear a saída completa é mais trabalhoso — exige liberar DNS, registry e serviços externos — e é o que de fato contém um pod comprometido.
- Bloqueio de acesso aos endereços do plano de controle e aos serviços de metadados do provedor de nuvem. Este último é um caminho clássico de escalonamento de privilégio.
Uma advertência importante: NetworkPolicy exige suporte do plugin de rede. Alguns plugins aceitam os objetos e não os aplicam — você cria a política, ela aparece na listagem, e o tráfego continua passando. Verifique, com teste real, que a política surte efeito. É um dos achados mais comuns em auditoria de cluster.
Permissão: o cluster é mais que namespaces
RBAC no Kubernetes tem dois escopos, e a confusão entre eles é a fonte dos erros:
- Papel de namespace, que vale dentro dele.
- Papel de cluster, que vale em todo lugar.
E há uma armadilha específica: vincular um papel de cluster a um sujeito, com escopo de cluster, dá acesso a todos os namespaces. É fácil fazer isso por engano ao copiar um exemplo.
O desenho para múltiplos times:
- Um grupo por time, vindo do provedor de identidade, nunca usuários individuais.
- Papel por função dentro do namespace: desenvolvedor, operador, leitor.
- Permissão mínima. Desenvolvedor não precisa criar objetos que alteram o comportamento do cluster.
- Nada de acesso a recursos de escopo de cluster para times de aplicação: nós, volumes persistentes, definições de recursos personalizados, classes de prioridade.
- Contas de serviço por aplicação, com permissão própria e mínima — e não a conta padrão do namespace.
Dois cuidados que valem regra explícita: ninguém de time de aplicação cria definição de recurso personalizado ou webhook de admissão, porque ambos afetam o cluster inteiro; e acesso à leitura de segredos precisa ser deliberado, já que quem lê segredo de um namespace tem as credenciais daquele time.
Recursos: quota é isolamento
Sem limite, um time consome o cluster inteiro — por erro, por autoscaling mal configurado ou por um vazamento.
- ResourceQuota por namespace, limitando CPU, memória, armazenamento e quantidade de objetos. O limite de quantidade importa: um controlador em laço criando pods sem parar é um incidente real.
- LimitRange por namespace, com padrões para quem não declarou e tetos por container. É o que elimina o pod sem requests, que cairia na classe de despejo mais frágil.
- Classes de prioridade controladas pela plataforma, não pelos times. Se qualquer um pode marcar a própria carga como prioritária, a prioridade deixa de significar algo.
E vale monitorar a relação entre reservado e usado por namespace, porque quota generosa com uso baixo é capacidade travada que poderia estar servindo outro time.
Execução: o que impede alcançar o nó
A camada que separa isolamento fraco de isolamento sério.
Sem política de admissão, um manifesto pode pedir pod privilegiado, montar o sistema de arquivos do host, usar a rede do host ou rodar como root — e, a partir daí, o comprometimento do pod é o comprometimento do nó, e do cluster.
O que precisa estar aplicado:
- Padrões de segurança de pod no nível restrito para namespaces de aplicação, aplicados pelo mecanismo nativo de admissão.
- Proibição explícita de pod privilegiado, rede do host, sistema de arquivos do host e escalonamento de privilégio.
- Execução sem root, com capacidades do kernel removidas e raiz somente leitura.
- Um motor de políticas para as regras que o mecanismo nativo não cobre: registries permitidos, rótulos obrigatórios, limites de tolerância, proibição de tags móveis.
Este último é o que permite governança real em cluster compartilhado, e é o investimento que mais reduz o risco de manifesto mal escrito virar incidente.
O limite honesto: quando um cluster não basta
Vale ser direto, porque é onde muita arquitetura se ilude.
Multi-tenancy em um cluster funciona bem para times da mesma organização, que confiam uns nos outros e compartilham a mesma política de segurança. Chamamos isso de tenancy branda, e é o caso da grande maioria das empresas.
Não funciona bem para inquilinos que não confiam uns nos outros — clientes externos, código de terceiro, cargas de origem desconhecida. Os motivos são estruturais:
- O kernel é compartilhado. Uma vulnerabilidade de escapada de container atinge todos os pods do nó.
- O plano de controle é compartilhado. Um time consumindo a API agressivamente afeta todos.
- Definições de recursos personalizados e webhooks são globais e alteram o comportamento de todos.
- Alguns componentes de infraestrutura não são isoláveis por namespace.
Para inquilinos sem confiança mútua, as respostas reais são: cluster por inquilino, nós dedicados por inquilino com taints e afinidade, ou VM por inquilino rodando o cluster dele. Em provedor de cloud, a regra que aplicamos é a mesma da virtualização: carga de cliente roda em VM, não em container compartilhando kernel com a de outro cliente.
O caminho de adoção
- Namespace por time, com convenção de nomes.
- Grupos do provedor de identidade mapeados a papéis por namespace.
- LimitRange e ResourceQuota em todos os namespaces.
- Padrões de segurança de pod no nível restrito.
- NetworkPolicy de negação padrão, com liberações explícitas — testadas de verdade.
- Motor de políticas para as regras adicionais.
- Nós dedicados, se houver requisito de separação de hardware.
- Revisão periódica de permissões e de quotas.
A ordem importa: quota e política de segurança antes da rede, porque são menos propensas a quebrar aplicação em produção e já eliminam boa parte do risco.
Erros comuns
- Tratar namespace como fronteira de segurança.
- Nenhuma NetworkPolicy, com todo pod alcançando todo pod.
- Criar NetworkPolicy sem verificar se o plugin de rede a aplica.
- Vincular papel de cluster com escopo de cluster por engano.
- Time de aplicação com acesso a recursos de escopo de cluster.
- Permitir criação de definições personalizadas e webhooks por times de aplicação.
- Usar a conta de serviço padrão do namespace nas aplicações.
- Namespace sem ResourceQuota nem LimitRange.
- Sem limite de quantidade de objetos, e controlador em laço criando pods.
- Times definindo a própria classe de prioridade.
- Nenhuma política de admissão, permitindo pod privilegiado.
- Não bloquear o serviço de metadados do provedor de nuvem.
- Colocar clientes externos no mesmo cluster, compartilhando kernel.
- Nunca revisar permissões concedidas.
Onde a Solvefy/Cloud entra
Implantamos multi-tenancy em camadas, na ordem que reduz risco sem quebrar produção: quotas e limites, padrões de segurança de pod, RBAC por grupo do seu provedor de identidade, NetworkPolicy com negação padrão e verificação real de que o plugin aplica as regras, e motor de políticas para a governança adicional. Também ajudamos a tomar a decisão difícil — quando o requisito de isolamento exige cluster separado, nós dedicados ou VM por inquilino, que é o desenho que recomendamos para quem opera para clientes externos.
Um pod comprometido no seu cluster alcançaria o banco do outro time? Diagnóstico gratuito, sem compromisso, em solvefy.cloud.
Solvefy/Cloud — Infraestrutura que cresce com você.