Pod Security Standards и Admission
Pod Security Admission (PSA) — это built-in admission controller, который проверяет каждый создаваемый Pod на соответствие одному из трёх стандартов: Privileged, Baseline, Restricted. PSA включён по умолчанию с v1.23, GA c v1.25, и полностью заменил PodSecurityPolicy (PSP) — последний удалён в v1.25. На v1.35 это единственный официальный mechanism для namespace-level security policy в core K8s. Применение — через labels на Namespace. На CKAD это знание концептуальное: понять три уровня, mode-флаги, и какие поля SecurityContext нужны для каждого уровня.
Rootless Docker и user namespaces
Три уровня (Pod Security Standards)
Стандарты определены документом Kubernetes Pod Security Standards и фиксированы версией кластера (можно ссылаться на latest или конкретный v1.34, v1.35).
Что Restricted требует от SecurityContext
Самый детализированный уровень. Pod проходит, если соблюдены все правила:
apiVersion: v1
kind: Pod
metadata:
name: restricted-ok
spec:
securityContext:
runAsNonRoot: true # либо на Pod-level, либо на всех containers
seccompProfile:
type: RuntimeDefault # либо RuntimeDefault либо Localhost
containers:
- name: app
image: app:1.0
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
add: [NET_BIND_SERVICE] # единственный allowed add
# readOnlyRootFilesystem НЕ обязательно в restricted v1.35
Применение через namespace labels
PSA не имеет собственного API-объекта в обычном случае — конфигурируется через labels на Namespace:
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
# Mode: enforce — block non-compliant Pods
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
# Mode: audit — log violations to audit log
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
# Mode: warn — print warning к kubectl при создании
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
Прикладной императивный паттерн:
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest
Проверить:
kubectl get namespace production -o jsonpath='{.metadata.labels}' | jq
Three modes: enforce, audit, warn
Каждый mode — независимый. Можно поставить enforce=baseline, audit=restricted, warn=restricted — это значит «блокирую baseline нарушения, логирую и предупреждаю о restricted нарушениях». Это типичный pattern: enforce baseline (минимум), audit restricted (видеть прогресс к более жёсткому уровню).
Killer-момент: enforce на existing namespace
PSA проверяет только при создании / обновлении Pod. Уже запущенные Pods не аффектятся новым label. Но при их rolling restart (новый ReplicaSet, deployment update, scaling, node drain → reschedule) — kubelet попробует создать новые Pods, apiserver их отвергнет, deployment останется без healthy replicas.
Production playbook применения restricted к существующему namespace:
- Поставить
warn=restricted+audit=restricted. Сделать deployment apps — увидеть violations в kubectl и audit log. - Исправить SecurityContext во всех manifests.
- Дождаться полного rollout — проверить что новых violations нет.
- Только потом включить
enforce=restricted.
Альтернатива при неотложности — поставить enforce=baseline, который много легче, и потом мигрировать к restricted.
Privileged Pods для system needs
Системные DaemonSets (CNI, monitoring agents) часто требуют privileged: true или hostNetwork. Они НЕ должны жить в restricted namespace. Стандартные подходы:
- Запускать их в
kube-systemnamespace сenforce=privileged(или вообще без label — equivalent to privileged). - Если нужен dedicated namespace (например,
monitoring), пометить егоenforce=privileged.
# Promtail DaemonSet, читающий /var/log/containers на хосте
apiVersion: v1
kind: Namespace
metadata:
name: logging
labels:
pod-security.kubernetes.io/enforce: privileged
PSA vs admission webhooks vs OPA/Kyverno
PSA покрывает базовые сценарии. Для более сложных — например, «запретить images не из нашего registry» или «требовать lab team» — нужны:
- OPA Gatekeeper — admission webhook на основе Rego policies.
- Kyverno — admission и mutation на основе YAML policies (proще чем Rego).
- Custom ValidatingAdmissionWebhook — собственный сервис.
- ValidatingAdmissionPolicy (v1.30+ GA) — CEL expressions без external webhook.
На CKAD они не требуются — экзамен ограничен built-in PSA. Но знать что PSA — не единственный механизм admission, полезно для рассуждения в production.
Команды для quick reference
# Применить enforce restricted к namespace
kubectl label ns production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest
# Применить warn для discovery
kubectl label ns dev \
pod-security.kubernetes.io/warn=restricted
# Снять label (вернуть к privileged по умолчанию)
kubectl label ns production \
pod-security.kubernetes.io/enforce-
# Создать Pod и увидеть warning (с warn label)
kubectl apply -f pod.yaml -n dev
# Warning: would violate "latest" version of "restricted" PodSecurity profile:
# allowPrivilegeEscalation != false (container "app"), ...