Pular para o conteúdo
NyverraNyverra
Artigos
⌘K
InícioArtigosSite institucional
🇧🇷

Nyverra

Canal editorial

Artigos sobre tecnologia, operações e parceiros — infraestrutura, monitoramento e ambientes críticos.

Explorar

  • Início
  • Artigos
  • Categorias
  • Tags
  • Autores
  • Sobre
  • Contato
  • RSS
  • Site institucional

© 2026 Nyverra. Todos os direitos reservados.

blog.nyverra.com

  1. Início
  2. Kubernetes
  3. Curso Kubernetes 25 — Segurança: RBAC, PSA, NetworkPolicy e secrets
Kubernetes
#Curso Kubernetes#Kubernetes#K8S

Curso Kubernetes 25 — Segurança: RBAC, PSA, NetworkPolicy e secrets

Wedson LopesWedson Lopes
30 de outubro de 20265 min de leitura

Segurança em Kubernetes não é uma ferramenta. É um conjunto de padrões que impedem o próximo incidente — quase sempre causado por um cluster-admin esquecido ou um namespace sem rede isolada.

Este capítulo monta o mínimo que todo cluster de produção deveria ter.

Selo do curso: testado em Kubernetes 1.35 com PSA e Calico/Cilium.

Modelo de ameaça prático

Perguntas que valem mais que um checklist genérico:

  1. Se um pod for comprometido, o que ele alcança? (rede, API, secrets)
  2. Quem pode criar pod? Pod cria acesso ao nó.
  3. Onde estão os segredos e quem lê?
  4. O que roda com privileged: true e por quê?

RBAC sem cluster-admin

Nunca dê cluster-admin a aplicação. Crie uma Role no namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: portal-backend
  namespace: portal
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: portal-backend
  namespace: portal
subjects:
  - kind: ServiceAccount
    name: portal-backend
    namespace: portal
roleRef:
  kind: Role
  name: portal-backend
  apiGroup: rbac.authorization.k8s.io

No Deployment:

spec:
  template:
    spec:
      serviceAccountName: portal-backend
      automountServiceAccountToken: false

automountServiceAccountToken: false quando a app não fala com a API é o ganho mais barato do capítulo: sem token montado, credencial vazada no container não serve para nada.

Audite:

kubectl auth can-i --list --as=system:serviceaccount:portal:portal-backend -n portal
kubectl get clusterrolebindings -o json | jq -r '.items[] | select(.roleRef.name=="cluster-admin") | .metadata.name'

Pessoas: cada um com o próprio usuário (OIDC), não um kubeconfig compartilhado.

Pod Security Admission

PSA substituiu o PSP. Três níveis:

Nível O que exige
privileged nada
baseline bloqueia o pior (privileged, hostNetwork, hostPath)
restricted roda como non-root, sem privilege escalation, seccomp, capabilities dropadas

No namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: portal
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/audit: restricted

Comece com warn + audit, corrija as cargas, depois enforce.

Pod compatível com restricted:

spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 10001
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]

readOnlyRootFilesystem quebra app que escreve em /tmp. Monte emptyDir em /tmp — e descubra quantas apps escrevem onde não deviam.

NetworkPolicy: default-deny

Sem política, todo pod fala com todo pod. Comece negando:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: portal
spec:
  podSelector: {}
  policyTypes: ["Ingress", "Egress"]

Depois libere o necessário:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: backend-allow
  namespace: portal
spec:
  podSelector:
    matchLabels:
      app: portal-backend
  policyTypes: ["Ingress", "Egress"]
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: ingress-nginx
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: portal-postgres
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53

Dois erros clássicos:

  • Esquecer DNS no egress: tudo vira timeout.
  • Confiar em IP: pod muda de IP; use selectors.

Teste:

kubectl -n portal run tmp --rm -it --image=busybox -- sh
# dentro: nc -zv portal-postgres 5432  (deve falhar se não liberado)

Segredos

O que não fazer:

  • Secret em values.yaml ou no Git.
  • Secret em variável de ambiente impressa em log.
  • Mesmo segredo em todos os ambientes.

Opções:

  • External Secrets Operator + Vault/AWS SM.
  • Sealed Secrets (criptografado no Git).
  • SOPS + age.

Independente da escolha:

  • rotacione credenciais;
  • limite leitura de Secret por Role (Secret é namespaced, mas leitura é poder);
  • habilite encryption at rest no etcd;
  • evite kubectl get secret -o yaml em pipeline.

E o alerta que já apareceu neste curso: minioadmin, changeme, admin/admin em manifest é incidente esperando data.

Runtime e imagens

  • Imagens de registry confiável, por digest.
  • imagePullPolicy: IfNotPresent com tag imutável.
  • Admission policy (Kyverno) barrando :latest, privileged e hostPath.
  • Scanner de vulnerabilidade no pipeline (capítulo 24).
  • Runtime security (Falco) para detectar shell em container.

Laboratório

  1. Aplique default-deny no namespace e observe o que quebra.
  2. Libere DNS e as dependências reais; valide com nc/curl.
  3. Ative PSA em warn e liste os pods não conformes.
  4. Corrija securityContext de um Deployment e passe para enforce.
  5. Crie ServiceAccount + Role mínima e teste com kubectl auth can-i.
  6. Tente kubectl exec como non-root e escrever em / (deve falhar).

Erros comuns

Sintoma Causa
Timeout após NetworkPolicy DNS não liberado no egress
Pod rejeitado pelo PSA falta runAsNonRoot/seccomp
App quebra com readOnlyRoot escrita em /tmp sem emptyDir
Cluster-admin em todo lugar RBAC copiado de tutorial
Secret legível por qualquer pod falta RBAC + namespace isolado
Token da API montado sem uso automountServiceAccountToken padrão
Policy não aplica CNI sem suporte a NetworkPolicy

Checklist

  • [ ] ServiceAccount por aplicação, token desmontado quando possível.
  • [ ] Roles mínimas e auditoria de cluster-admin.
  • [ ] PSA restricted (ou baseline justificado) por namespace.
  • [ ] securityContext com non-root, seccomp e capabilities dropadas.
  • [ ] NetworkPolicy default-deny + liberações explícitas.
  • [ ] DNS liberado no egress.
  • [ ] Segredos fora do Git e rotação definida.
  • [ ] etcd com encryption at rest.
  • [ ] Admission policy para imagens e privilégios.
  • [ ] Runtime detection (Falco) avaliada.

Glossário

  • RBAC: controle de acesso por papel.
  • ServiceAccount: identidade do pod.
  • PSA: Pod Security Admission.
  • NetworkPolicy: firewall entre pods.
  • default-deny: nega tudo e libera o necessário.
  • seccomp: filtro de syscalls.
  • External Secrets: operador que sincroniza segredos externos.

Próximo

Cluster endurecido. Agora a pergunta que derruba ambiente: quanta carga ele aguenta? Capacidade, k6, rate limit e o que acontece quando o banco vira o gargalo.

Próximo: Curso Kubernetes 26 — Capacidade e carga: HPA, k6 e rate limit

Compartilhar

Continuar a ler

Leia também

  • Kubernetes de Verdade — do zero ao cluster em produção
    Kubernetes

    Kubernetes de Verdade — do zero ao cluster em produção

    Uma trilha prática para entender, montar e operar um cluster Kubernetes — do primeiro pod ao failover do Postgres.

    30 de outubro de 20264 min de leitura
  • Curso Kubernetes 28 — DR e capstone: provar que o cluster volta
    Kubernetes

    Curso Kubernetes 28 — DR e capstone: provar que o cluster volta

    RPO, RTO e drills reais: cenários de desastre, runbook, restore medido e o capstone que fecha o curso com um cluster que se recupera.

    30 de outubro de 20265 min de leitura
  • Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless
    Kubernetes

    Curso Kubernetes 27 — SLO/SLI, on-call e postmortem blameless

    O que prometer, como medir e o que fazer quando o erro estoura: SLI, SLO, error budget, alertas que acordam alguém e postmortem sem caça às bruxas.

    30 de outubro de 20264 min de leitura

Comentários

Ainda sem comentários

Seja o primeiro a compartilhar sua opinião sobre este artigo.

Deixe um comentário

Newsletter

Receba novos artigos

Inscreva-se para receber publicações do blog Nyverra no seu e-mail. Enviaremos um link de confirmação.

​