DevOps Admin

Dominando Namespaces, RBAC e Segurança em Clusters Kubernetes em Projetos Reais Já leu

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 . 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ê

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.

Referências


Artigos relacionados