GitHub EN PT

K8s em Exemplos: Pod Security Standards

Pod Security Standards (PSS) substituem a deprecada PodSecurityPolicy. Definem três níveis de segurança: Privileged (sem restrições), Baseline (previne escalações conhecidas), Restricted (hardened). Aplique via labels de namespace sem instalar controllers adicionais.

namespace-baseline.yaml

Aplique security standards via labels de namespace. O label pod-security.kubernetes.io/enforce define o nível requerido. Pods violando a política são rejeitados.

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/enforce-version: latest

Três modos: enforce (rejeita), audit (loga), warn (avisa usuário). Use audit/warn para testar antes de enforçar.

metadata:
  labels:
    # Rejeitar violações
    pod-security.kubernetes.io/enforce: baseline
    # Logar violações (para monitoramento)
    pod-security.kubernetes.io/audit: restricted
    # Avisar no kubectl apply
    pod-security.kubernetes.io/warn: restricted
security-levels.yaml

Privileged: Sem restrições. Use para componentes de sistema que precisam de acesso total (plugins CNI, agentes de monitoramento).

# Privileged: permite tudo
# - hostNetwork, hostPID, hostIPC
# - containers privilegiados
# - qualquer capability
# - qualquer volume
# - rodar como root

apiVersion: v1
kind: Namespace
metadata:
  name: kube-system
  labels:
    pod-security.kubernetes.io/enforce: privileged

Baseline: Previne escalações de privilégio conhecidas. Padrão razoável para maioria dos workloads. Bloqueia hostNetwork, privileged e capabilities perigosas.

# Baseline bloqueia:
# - hostNetwork, hostPID, hostIPC
# - privileged: true
# - capabilities: SYS_ADMIN, NET_ADMIN, etc.
# - volumes hostPath
# - hostPorts

apiVersion: v1
kind: Namespace
metadata:
  name: staging
  labels:
    pod-security.kubernetes.io/enforce: baseline

Restricted: Máxima segurança. Requer non-root, dropa todas capabilities, filesystem root read-only. Use para workloads sensíveis.

# Restricted adicionalmente requer:
# - runAsNonRoot: true
# - allowPrivilegeEscalation: false
# - capabilities.drop: ALL
# - seccompProfile: RuntimeDefault
# - runAsUser: diferente de zero

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
pod-baseline-compliant.yaml

Um pod compatível com baseline. Sem hostNetwork, sem modo privileged, sem capabilities perigosas. Maioria das aplicações funciona com baseline.

apiVersion: v1
kind: Pod
metadata:
  name: app
  namespace: staging       # baseline enforçado
spec:
  containers:
    - name: app
      image: myapp:v1
      ports:
        - containerPort: 8080
      securityContext:
        allowPrivilegeEscalation: false
        # Sem privileged: true
        # Sem hostNetwork, hostPID, hostIPC
pod-restricted-compliant.yaml

Um pod compatível com restricted. Roda como non-root, dropa todas capabilities, usa seccomp. Esta é a configuração mais segura.

apiVersion: v1
kind: Pod
metadata:
  name: app
  namespace: production    # restricted enforçado
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: myapp:v1
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir: {}
terminal

Quando um pod viola a política, é rejeitado com uma mensagem de erro clara explicando quais campos não são compatíveis.

$ kubectl apply -f privileged-pod.yaml
Error from server (Forbidden): pods "bad-pod" is forbidden:
  violates PodSecurity "baseline:latest":
  privileged (container "app" must not set
    securityContext.privileged=true)

Use —dry-run=server para testar pods contra políticas de namespace sem criá-los.

$ kubectl apply -f pod.yaml --dry-run=server
pod/app created (server dry run)

# Verificar warnings para política restricted
$ kubectl apply -f pod.yaml
Warning: would violate PodSecurity "restricted:latest":
  runAsNonRoot must be true
pod/app created  # Baseline permitido, restricted avisou
terminal

Audite quais namespaces têm políticas de segurança. Namespaces sem labels default para privileged (sem restrições).

$ kubectl get ns --show-labels | grep pod-security
default      pod-security.kubernetes.io/warn=baseline
kube-system  pod-security.kubernetes.io/enforce=privileged
production   pod-security.kubernetes.io/enforce=restricted
staging      pod-security.kubernetes.io/enforce=baseline

Aplique baseline para todos novos namespaces por padrão usando um admission controller ou política GitOps.

# Adicionar política em namespace existente
$ kubectl label ns myapp \
    pod-security.kubernetes.io/enforce=baseline \
    pod-security.kubernetes.io/warn=restricted

# Verificar o que seria bloqueado
$ kubectl get pods -n myapp -o yaml | \
    kubectl apply -f - --dry-run=server 2>&1 | \
    grep -i "forbidden\|warning"
exemptions.yaml

Alguns componentes de sistema precisam de exceções. Configure o API server com —admission-control-config-file para isentar usuários, namespaces ou runtime classes específicos.

# /etc/kubernetes/admission-control-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
  - name: PodSecurity
    configuration:
      apiVersion: pod-security.admission.config.k8s.io/v1
      kind: PodSecurityConfiguration
      defaults:
        enforce: baseline
        audit: restricted
        warn: restricted
      exemptions:
        usernames:
          - system:serviceaccount:kube-system:*
        namespaces:
          - kube-system
          - istio-system
        runtimeClasses:
          - gvisor

Índice | Use as setas do teclado para navegar