Модуль 4.2: Pod Security Admission (PSA)
Складність:
[MEDIUM]— основна навичка CKSЧас на виконання: 40-45 хвилин
Передумови: Модуль 4.1 (Контексти безпеки), основи просторів імен
Що ви зможете робити
Розділ «Що ви зможете робити»Після завершення цього модуля ви зможете:
- Налаштувати мітки Pod Security Admission на просторах імен для режимів enforce, audit та warn
- Реалізувати профілі безпеки baseline та restricted по просторах імен кластера
- Діагностувати повідомлення про відхилення PSA та скоригувати специфікації Pod для відповідності стандартам безпеки
- Спроєктувати стратегію безпеки на рівні простору імен з використанням профілів PSA відповідно до чутливості навантажень
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Pod Security Admission (PSA) застосовує стандарти безпеки на рівні простору імен. Замість ручної перевірки контексту безпеки кожного Pod, PSA автоматично валідує Pod відповідно до визначених профілів безпеки та блокує невідповідні.
PSA замінив PodSecurityPolicy (видалено в Kubernetes 1.25). Це критична тема CKS.
Стандарти безпеки Pod
Розділ «Стандарти безпеки Pod»┌─────────────────────────────────────────────────────────────┐│ СТАНДАРТИ БЕЗПЕКИ POD │├─────────────────────────────────────────────────────────────┤│ ││ Privileged (найбільш дозвільний) ││ ───────────────────────────────────────────────────────── ││ • Без обмежень ││ • Для системних навантажень ││ • CNI, CSI, агенти логування ││ ││ Baseline (розумний стандарт) ││ ───────────────────────────────────────────────────────── ││ • Запобігає відомим підвищенням привілеїв ││ • Блокує hostNetwork, hostPID, hostIPC ││ • Блокує привілейовані контейнери ││ • Дозволяє запуск від root ││ ││ Restricted (найбільш безпечний) ││ ───────────────────────────────────────────────────────── ││ • Максимальна безпека ││ • Вимагає запуск не від root ││ • Вимагає скидання ВСІХ capabilities ││ • Вимагає файлову систему тільки для читання ││ • Вимагає профіль seccomp ││ │└─────────────────────────────────────────────────────────────┘Режими PSA
Розділ «Режими PSA»┌─────────────────────────────────────────────────────────────┐│ РЕЖИМИ ЗАСТОСУВАННЯ PSA │├─────────────────────────────────────────────────────────────┤│ ││ enforce ││ └── Відхиляти Pod, що порушують політику ││ (Створення Pod не вдається) ││ ││ warn ││ └── Дозволити, але показати попередження ││ (Добре для міграції) ││ ││ audit ││ └── Записати порушення в журнал аудиту ││ (Pod все одно створюється) ││ ││ Можна використовувати різні профілі для кожного режиму: ││ • enforce: baseline (блокувати очевидні проблеми) ││ • warn: restricted (показати, що не пройде) ││ • audit: restricted (логувати для перевірки) ││ │└─────────────────────────────────────────────────────────────┘Налаштування PSA через мітки
Розділ «Налаштування PSA через мітки»# Apply PSA to a namespace using labelsapiVersion: v1kind: Namespacemetadata: name: secure-ns labels: # Enforce baseline standard pod-security.kubernetes.io/enforce: baseline pod-security.kubernetes.io/enforce-version: latest
# Warn on restricted violations pod-security.kubernetes.io/warn: restricted pod-security.kubernetes.io/warn-version: latest
# Audit restricted violations pod-security.kubernetes.io/audit: restricted pod-security.kubernetes.io/audit-version: latestФормат міток
Розділ «Формат міток»pod-security.kubernetes.io/<MODE>: <PROFILE>pod-security.kubernetes.io/<MODE>-version: <VERSION>
MODE: enforce | warn | auditPROFILE: privileged | baseline | restrictedVERSION: latest | v1.28 | v1.27 | etc.Вимоги профілів
Розділ «Вимоги профілів»Обмеження профілю Baseline
Розділ «Обмеження профілю Baseline»# Baseline блокує ці налаштування:hostNetwork: true # BlockedhostPID: true # BlockedhostIPC: true # Blockedprivileged: true # BlockedhostPorts: [80, 443] # Blocked (hostPort)
# These capabilities blocked:capabilities: add: - NET_ADMIN # Blocked - SYS_ADMIN # Blocked - ALL # Blocked
# Baseline ДОЗВОЛЯЄ:runAsUser: 0 # Running as root OKrunAsNonRoot: false # Not requiredreadOnlyRootFilesystem: false # Not requiredВимоги профілю Restricted
Розділ «Вимоги профілю Restricted»# Restricted ВИМАГАЄ:securityContext: runAsNonRoot: true # Required allowPrivilegeEscalation: false # Required seccompProfile: type: RuntimeDefault # Required (or Localhost) capabilities: drop: ["ALL"] # Required
# For containers specifically:containers:- name: app securityContext: runAsNonRoot: true allowPrivilegeEscalation: false readOnlyRootFilesystem: true # Recommended but not required capabilities: drop: ["ALL"]Практичні приклади
Розділ «Практичні приклади»Створення простору імен з Restricted
Розділ «Створення простору імен з Restricted»# Create namespace with restricted enforcementcat <<EOF | kubectl apply -f -apiVersion: v1kind: Namespacemetadata: name: production 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: restrictedEOFТестування застосування політики
Розділ «Тестування застосування політики»# This pod will be REJECTED in restricted namespacecat <<EOF | kubectl apply -f - -n productionapiVersion: v1kind: Podmetadata: name: insecure-podspec: containers: - name: app image: nginxEOF
# Error: pods "insecure-pod" is forbidden:# violates PodSecurity "restricted:latest":# allowPrivilegeEscalation != false,# unrestricted capabilities,# runAsNonRoot != true,# seccompProfile
# This pod SUCCEEDS in restricted namespacecat <<EOF | kubectl apply -f - -n productionapiVersion: v1kind: Podmetadata: name: secure-podspec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: app image: nginx securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"]EOFВинятки
Розділ «Винятки»Винятки на рівні простору імен
Розділ «Винятки на рівні простору імен»# Exempt specific namespaces in AdmissionConfigurationapiVersion: apiserver.config.k8s.io/v1kind: AdmissionConfigurationplugins:- name: PodSecurity configuration: apiVersion: pod-security.admission.config.k8s.io/v1 kind: PodSecurityConfiguration defaults: enforce: "baseline" enforce-version: "latest" exemptions: # Exempt kube-system namespace namespaces: - kube-system # Exempt specific users usernames: - system:serviceaccount:kube-system:* # Exempt specific runtime classes runtimeClasses: - gvisorВиключення системних просторів імен
Розділ «Виключення системних просторів імен»# kube-system typically needs privileged accesskubectl label namespace kube-system pod-security.kubernetes.io/enforce=privileged --overwriteСтратегія міграції
Розділ «Стратегія міграції»┌─────────────────────────────────────────────────────────────┐│ СТРАТЕГІЯ МІГРАЦІЇ PSA │├─────────────────────────────────────────────────────────────┤│ ││ Фаза 1: Тільки аудит ││ ───────────────────────────────────────────────────────── ││ pod-security.kubernetes.io/audit: restricted ││ • Всі Pod все ще створюються ││ • Порушення логуються ││ • Перегляд журналів аудиту на проблеми ││ ││ Фаза 2: Попередження та аудит ││ ───────────────────────────────────────────────────────── ││ pod-security.kubernetes.io/warn: restricted ││ pod-security.kubernetes.io/audit: restricted ││ • Розробники бачать попередження ││ • Все ще неблокуючий режим ││ ││ Фаза 3: Застосування Baseline, попередження Restricted ││ ───────────────────────────────────────────────────────── ││ pod-security.kubernetes.io/enforce: baseline ││ pod-security.kubernetes.io/warn: restricted ││ • Блокування очевидних порушень ││ • Попередження про restricted ││ ││ Фаза 4: Повне застосування ││ ───────────────────────────────────────────────────────── ││ pod-security.kubernetes.io/enforce: restricted ││ • Максимальна безпека ││ │└─────────────────────────────────────────────────────────────┘Реальні сценарії іспиту
Розділ «Реальні сценарії іспиту»Сценарій 1: Увімкнення режиму Restricted
Розділ «Сценарій 1: Увімкнення режиму Restricted»# Apply restricted enforcement to namespacekubectl label namespace production \ pod-security.kubernetes.io/enforce=restricted \ pod-security.kubernetes.io/enforce-version=latest
# Verify labelkubectl get namespace production --show-labelsСценарій 2: Виправлення Pod для Restricted простору імен
Розділ «Сценарій 2: Виправлення Pod для Restricted простору імен»# Original pod (fails in restricted)apiVersion: v1kind: Podmetadata: name: webspec: containers: - name: nginx image: nginx
# Fixed pod (works in restricted)apiVersion: v1kind: Podmetadata: name: webspec: securityContext: runAsNonRoot: true runAsUser: 101 # nginx user seccompProfile: type: RuntimeDefault containers: - name: nginx image: nginx securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"] readOnlyRootFilesystem: true volumeMounts: - name: cache mountPath: /var/cache/nginx - name: run mountPath: /var/run volumes: - name: cache emptyDir: {} - name: run emptyDir: {}Сценарій 3: Налагодження відхилення PSA
Розділ «Сценарій 3: Налагодження відхилення PSA»# Check namespace labelskubectl get namespace production -o yaml | grep -A10 labels
# Create pod and see detailed errorkubectl apply -f pod.yaml -n production 2>&1 | head -20
# Dry run to check without creatingkubectl apply -f pod.yaml -n production --dry-run=serverЧи знали ви?
Розділ «Чи знали ви?»-
PSA замінив PodSecurityPolicy (PSP), який був оголошений застарілим у Kubernetes 1.21 та видалений у 1.25. PSA простіший і базується на мітках просторів імен.
-
Версія “latest” слідує за версією Kubernetes. Використання “latest” означає, що політика оновлюється при оновленні Kubernetes.
-
Системні простори імен потребують privileged. Pod у kube-system (CNI, CSI, kube-proxy) часто потребують доступ до хоста. Завжди виключайте або використовуйте рівень privileged.
-
PSA вбудований в API server і увімкнений за замовчуванням з Kubernetes 1.25. Додаткова інсталяція не потрібна.
Поширені помилки
Розділ «Поширені помилки»| Помилка | Чому це шкідливо | Рішення |
|---|---|---|
| Застосування restricted до kube-system | Системні Pod не працюють | Використовуйте privileged для системних просторів імен |
| Без runAsNonRoot у restricted | Pod відхиляються | Додайте runAsNonRoot: true |
| Відсутній seccompProfile | Restricted вимагає його | Додайте RuntimeDefault |
| Не скинуті capabilities | Restricted вимагає скидання | Скиньте ALL |
| Пропуск фази warn | Раптові збої | Мігруйте поступово |
Тест
Розділ «Тест»-
Які три стандарти безпеки Pod існують?
Відповідь
Privileged (без обмежень), Baseline (запобігає відомим підвищенням привілеїв) та Restricted (максимальна безпека). Кожен рівень прогресивно безпечніший. -
Яка різниця між режимами enforce, warn та audit?
Відповідь
Enforce: Відхиляти Pod, що порушують. Warn: Дозволити, але показати попередження. Audit: Логувати в журнал аудиту, але дозволити. Можна використовувати різні профілі для кожного режиму. -
Які поля контексту безпеки потрібні для профілю restricted?
Відповідь
runAsNonRoot: true, allowPrivilegeEscalation: false, capabilities.drop: ["ALL"] та seccompProfile.type: RuntimeDefault (або Localhost). -
Як застосувати PSA до простору імен?
Відповідь
За допомогою міток: `pod-security.kubernetes.io/enforce:` та необов'язково `-version: latest` на просторі імен.
Практична вправа
Розділ «Практична вправа»Завдання: Налаштувати та протестувати Pod Security Admission.
# Step 1: Create namespace with baseline enforcementkubectl create namespace psa-testkubectl label namespace psa-test \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/warn=restricted
# Step 2: Verify labelskubectl get namespace psa-test --show-labels
# Step 3: Test baseline allows regular podskubectl run baseline-test --image=nginx -n psa-testkubectl get pod baseline-test -n psa-test
# Step 4: Test baseline blocks privilegedcat <<EOF | kubectl apply -f - -n psa-testapiVersion: v1kind: Podmetadata: name: privileged-podspec: containers: - name: app image: nginx securityContext: privileged: trueEOF# Should be rejected
# Step 5: Upgrade to restrictedkubectl label namespace psa-test \ pod-security.kubernetes.io/enforce=restricted --overwrite
# Step 6: Previous pod now shows warning at restricted level# Delete and recreatekubectl delete pod baseline-test -n psa-testkubectl run restricted-test --image=nginx -n psa-test 2>&1 || echo "Rejected (expected)"
# Step 7: Create compliant podcat <<EOF | kubectl apply -f - -n psa-testapiVersion: v1kind: Podmetadata: name: compliant-podspec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: type: RuntimeDefault containers: - name: app image: busybox command: ["sleep", "3600"] securityContext: allowPrivilegeEscalation: false capabilities: drop: ["ALL"]EOF
kubectl get pod compliant-pod -n psa-test
# Cleanupkubectl delete namespace psa-testКритерії успіху: Зрозуміти, як PSA блокує невідповідні Pod.
Підсумок
Розділ «Підсумок»Стандарти безпеки Pod:
- Privileged: Без обмежень
- Baseline: Блокує відомі підвищення привілеїв
- Restricted: Максимальна безпека
Режими:
- enforce: Блокувати порушення
- warn: Показувати попередження
- audit: Логувати порушення
Необхідне для Restricted:
- runAsNonRoot: true
- allowPrivilegeEscalation: false
- capabilities.drop: [“ALL”]
- seccompProfile: RuntimeDefault
Поради для іспиту:
- Знайте формат міток простору імен
- Запам’ятайте вимоги restricted
- Мігруйте поступово (audit → warn → enforce)
Наступний модуль
Розділ «Наступний модуль»Модуль 4.3: Управління секретами — Захист секретів Kubernetes.