Namespaces em Kubernetes: Isolamento Lógico e Segurança
Namespaces são um recurso fundamental do Kubernetes que permite particionar um cluster em múltiplos ambientes virtuais, isolando logicamente recursos como pods, serviços e deployments. Diferentemente de uma máquina virtual ou container individual, namespaces compartilham a mesma rede de cluster, mas oferecem isolamento a nível de API e política. Isso permite que equipes diferentes, projetos ou ambientes (desenvolvimento, staging, produção) coexistam no mesmo cluster físico sem interferência.
Cada recurso no Kubernetes pertence a um namespace, exceto por recursos de escopo de cluster como nodes e namespaces em si. Quando você não especifica um namespace, o Kubernetes assume default. Um ponto crítico: namespaces não oferecem isolamento de rede por si só — para isso você precisa de Network Policies. Porém, combinados com RBAC e quotas de recursos, eles formam a base de um cluster seguro e organizado.
Criando e Gerenciando Namespaces
A criação de um namespace é simples, mas devemos entender as melhores práticas. Você pode criar via YAML ou imperativamente:
# namespace-producao.yaml
apiVersion: v1
kind: Namespace
metadata:
name: producao
labels:
ambiente: producao
tier: critical
Aplicar com kubectl apply -f namespace-producao.yaml. Você também pode criar imperativamente com kubectl create namespace producao, mas o arquivo YAML é preferível em ambientes de produção porque é versionável e reproduzível.
Para listar namespaces e ver quantos recursos existem em cada um:
kubectl get namespaces
kubectl get all -n producao
kubectl describe namespace producao
Um aspecto importante: quando você deleta um namespace, todos os recursos dentro dele são deletados também. Use com cuidado em produção. Para proteger namespaces críticos, implemente policies de admission e backups automáticos.
RBAC (Role-Based Access Control): Autorização Granular
RBAC é o mecanismo do Kubernetes que define quem pode fazer o quê em quais recursos. Diferentemente de autenticação (que responde "você é quem diz ser?"), autorização responde "você tem permissão para fazer isso?". RBAC opera em quatro primitivas: Role, RoleBinding, ClusterRole e ClusterRoleBinding. Roles e RoleBindings são scoped a um namespace, enquanto ClusterRole e ClusterRoleBinding valem para todo o cluster.
O conceito central é simples: você define uma Role (um conjunto de permissões), depois vincula essa role a um Subject (usuário, grupo ou service account) através de um RoleBinding. Cada Role contém regras que especificam verbos (get, create, delete, etc.), recursos (pods, services, etc.) e opcionalmente nomes específicos de recursos.
Estrutura e Componentes do RBAC
Uma Role define permissões em um namespace específico:
# role-developer.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer
namespace: producao
rules:
# Permite listar e obter pods
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
# Permite ver logs de pods
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get"]
# Permite criar e deletar deployments
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "create", "update", "patch", "delete"]
# Permite acessar configmaps e secrets (leitura)
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list"]
Agora você vincula essa Role a um usuário ou service account através de um RoleBinding:
# rolebinding-developer-producao.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: developer-binding
namespace: producao
subjects:
- kind: User
name: joao@empresa.com
apiGroup: rbac.authorization.k8s.io
- kind: ServiceAccount
name: app-deployer
namespace: producao
roleRef:
kind: Role
name: developer
apiGroup: rbac.authorization.k8s.io
Neste exemplo, o usuário joao@empresa.com e a service account app-deployer agora têm as permissões definidas na Role developer, mas apenas no namespace producao.
ClusterRole e ClusterRoleBinding
Para recursos de escopo de cluster ou permissões que precisam valer em todos os namespaces, use ClusterRole:
# clusterrole-admin-logs.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: log-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
E o ClusterRoleBinding que o vincula:
# clusterrolebinding-team-logs.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: log-reader-global
subjects:
- kind: Group
name: monitoring-team
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: log-reader
apiGroup: rbac.authorization.k8s.io
Boas Práticas no RBAC
O princípio fundamental é o least privilege: conceda apenas as permissões mínimas necessárias. Nunca use * (wildcard) em verbos ou recursos em produção, pois isso equivale a acesso total. Use kubectl auth can-i para testar permissões antes de aplicar em produção:
# Testar se um usuário pode listar pods em um namespace
kubectl auth can-i list pods --as=joao@empresa.com -n producao
# Testar se uma service account pode criar deployments
kubectl auth can-i create deployments --as=system:serviceaccount:producao:app-deployer -n producao
Segurança em Clusters Kubernetes: Defesa em Profundidade
Segurança em Kubernetes não é um único recurso, mas um conjunto de camadas. Além de RBAC e Namespaces, você precisa pensar em autenticação, autorização, policies de rede, segurança de imagens, e auditoria. A abordagem correta é "defesa em profundidade" — múltiplas camadas que, mesmo se uma falhar, a próxima ainda protege o cluster.
As ameaças em um cluster incluem: acesso não autorizado (resolvido com autenticação + RBAC), movimento lateral entre pods (resolvido com Network Policies), execução de containers privilegiados (resolvido com Pod Security Policies ou Pod Security Standards), e vazamento de secrets em logs ou imagens (resolvido com RBAC em secrets e image scanning).
Network Policies: Isolamento de Rede
Network Policies definem regras de tráfego entre pods, bloqueando por padrão e permitindo apenas o necessário:
# network-policy-app-db.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app-to-db
namespace: producao
spec:
podSelector:
matchLabels:
tier: database
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
tier: app
ports:
- protocol: TCP
port: 5432
Esta policy permite que pods com label tier: app acessem pods com label tier: database apenas na porta 5432. Todo outro tráfego é bloqueado. Aplique Network Policies em cada namespace e teste com kubectl exec de um pod para outro.
Pod Security Standards e Admission Controllers
Pod Security Standards (PSS) definem níveis de segurança mínimos para pods. Ao invés do antigo Pod Security Policy (deprecado), você usa labels no namespace:
# namespace-producao-seguro.yaml
apiVersion: v1
kind: Namespace
metadata:
name: producao
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Com enforce: restricted, o Kubernetes rejeita qualquer pod que não cumpra o padrão restricted, que proíbe containers privilegiados, acesso a root, e mais. O nível audit apenas registra em logs, e warn avisa o usuário.
Gerenciamento Seguro de Secrets
Secrets no Kubernetes armazenam dados sensíveis, mas por padrão são apenas base64-encoded (não criptografados). Use RBAC para limitar quem pode ver secrets:
# role-secret-restricted.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: database-admin
namespace: producao
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["db-credentials"] # Apenas este secret
verbs: ["get", "list"]
Em produção, ative criptografia em repouso para etcd (o banco de dados do Kubernetes) e considere usar soluções externas como HashiCorp Vault ou AWS Secrets Manager, integradas via External Secrets Operator.
Auditoria e Logging
Configure audit logging no API server para registrar todas as ações. Isso é crítico para compliance e forensics:
# audit-policy.yaml (simplificado)
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log de alta verbosidade para deletions
- level: RequestResponse
verbs: ["delete", "deletecollection"]
omitStages:
- RequestReceived
# Log de metadata para tudo else
- level: Metadata
Configure no API server com --audit-policy-file=/etc/kubernetes/audit-policy.yaml --audit-log-path=/var/log/kubernetes/audit.log. Envie logs de auditoria para um SIEM ou ferramenta centralizada.
Verificação de Vulnerabilidades em Imagens
Sempre scaneie imagens em busca de vulnerabilidades conhecidas antes de colocar em produção:
# Usando Trivy (ferramenta open-source)
trivy image --severity HIGH,CRITICAL seu-registry/sua-app:v1.0
# Integrado no pipeline CI/CD
docker build -t seu-registry/sua-app:v1.0 .
trivy image --exit-code 1 --severity HIGH seu-registry/sua-app:v1.0
docker push seu-registry/sua-app:v1.0
Mantenha imagens base atualizadas e implemente políticas que rejeitam imagens com vulnerabilidades críticas usando Admission Webhooks.
Exemplo Integrado: Deployment Seguro em Produção
Vamos juntar tudo: namespace isolado, RBAC restritivo, Network Policy, e Pod Security Standards:
# 1. Namespace com PSS
apiVersion: v1
kind: Namespace
metadata:
name: app-producao
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
---
# 2. Service Account para a aplicação
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: app-producao
---
# 3. Role com permissões mínimas
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: app-reader
namespace: app-producao
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["app-db-secret"]
verbs: ["get"]
---
# 4. RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-reader-binding
namespace: app-producao
subjects:
- kind: ServiceAccount
name: app-sa
namespace: app-producao
roleRef:
kind: Role
name: app-reader
apiGroup: rbac.authorization.k8s.io
---
# 5. Network Policy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-network-policy
namespace: app-producao
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
---
# 6. Deployment com segurança
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: app-producao
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
serviceAccountName: app-sa
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsReadOnlyRootFilesystem: true
containers:
- name: app
image: seu-registry/myapp:v1.0
imagePullPolicy: Always
ports:
- containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Para aplicar: kubectl apply -f arquivo-completo.yaml. Valide com kubectl describe namespace app-producao, kubectl get roles -n app-producao, e teste permissões com kubectl auth can-i.
Conclusão
Ao longo deste artigo, você aprendeu que Namespaces fornecem isolamento lógico e particionamento de recursos, servindo como base para multi-tenância em um cluster. Não confunda com isolamento de rede — use Network Policies para isso. Em segundo lugar, RBAC é o mecanismo de autorização que implementa least privilege, separando permissões por Role e RoleBinding em escopo de namespace, ou ClusterRole/ClusterRoleBinding globalmente. Sempre teste com kubectl auth can-i antes de confiar em uma política em produção. Por fim, segurança em Kubernetes é multi-camadas: autenticação, RBAC, Network Policies, Pod Security Standards, secrets criptografados, image scanning, e auditoria trabalham juntas. Nenhuma camada isolada é suficiente — implemente todas.