Files
2026-04-08 20:22:14 +07:00
..
2026-04-08 20:22:14 +07:00
2026-04-08 20:22:14 +07:00
2026-04-08 20:22:14 +07:00

Урок 6.2 — Отладка проблем с политиками

Файлы

Файл Описание
policy-exception-example.yaml Пример PolicyException
debug-context-inspector.yaml DEBUG политика для инспекции переменных

Диагностический чеклист

Когда политика не работает — проверяйте по порядку:

Шаг 1: Политика применена и Ready?

kubectl get clusterpolicies
# Колонка READY должна быть True

kubectl get clusterpolicy my-policy -o yaml | grep -A 10 "status:"
# conditions[0].status: "True"
# conditions[0].type: Ready

Шаг 2: Match срабатывает?

# Kyverno CLI — самый быстрый способ проверить
kyverno apply my-policy.yaml \
  --resource my-resource.yaml \
  --detailed-results

# Вывод:
# Rule my-rule -> resource: PASS/FAIL/SKIP
# SKIP = match не сработал

Шаг 3: Ресурс не попадает в exclude?

# Проверить лейблы namespace
kubectl get namespace my-namespace --show-labels

# Проверить лейблы ресурса
kubectl get pod my-pod --show-labels

Шаг 4: Логи admission controller

# Включить более детальные логи временно
kubectl set env deployment/kyverno-admission-controller \
  -n kyverno \
  KYVERNO_LOG_LEVEL=4

# Затем смотреть логи
kubectl logs -n kyverno \
  -l app.kubernetes.io/component=admission-controller \
  --tail=50 -f | grep "my-policy\|my-resource"

# Вернуть обратно
kubectl set env deployment/kyverno-admission-controller \
  -n kyverno \
  KYVERNO_LOG_LEVEL=2

Шаг 5: Dry-run для проверки мутаций

# Видеть итоговый ресурс после мутации без создания
kubectl apply -f my-pod.yaml --dry-run=server -o yaml

# Diff оригинала и мутированной версии
diff <(cat my-pod.yaml) \
     <(kubectl apply -f my-pod.yaml --dry-run=server -o yaml 2>/dev/null)

Типичные ошибки и решения

Ошибка 1: JMESPath — экранирование аннотаций

# НЕПРАВИЛЬНО — парсер не поймёт /
key: "{{ request.object.metadata.annotations.company.com/env }}"

# ПРАВИЛЬНО — экранировать / через \"
key: "{{ request.object.metadata.annotations.\"company.com/env\" }}"

Ошибка 2: Опциональные поля

# НЕПРАВИЛЬНО — упадёт если поле не задано
pattern:
  spec:
    securityContext:
      runAsNonRoot: true

# ПРАВИЛЬНО — = для опциональных полей
pattern:
  spec:
    =(securityContext):
      =(runAsNonRoot): true

Ошибка 3: foreach по несуществующему массиву

# НЕПРАВИЛЬНО — упадёт если initContainers не задан
foreach:
- list: "request.object.spec.initContainers"

# ПРАВИЛЬНО — fallback на пустой массив
foreach:
- list: "request.object.spec.initContainers || `[]`"

Ошибка 4: Match по kind без учёта controller

# Если хотите проверять Deployment — матчите Deployment
match:
  resources:
    kinds:
    - Deployment    # проверяет сам Deployment

# Если хотите проверять Pod через Deployment — матчите Pod
# (Deployment controller создаёт Pod — Kyverno поймает его)
match:
  resources:
    kinds:
    - Pod

Инспекция переменных через debug-политику

# Создать namespace для отладки
kubectl create namespace debug-namespace

# Применить debug политику (она всегда выдаёт fail с данными)
kubectl apply -f debug-context-inspector.yaml

# Создать тестовый под — получить ошибку с содержимым переменных
kubectl run debug-pod --image=nginx:1.25.3 \
  --restart=Never -n debug-namespace \
  --dry-run=server 2>&1

# Вывод покажет все переменные в сообщении ошибки:
# [DEBUG] Pod: debug-pod
# Namespace: debug-namespace
# Namespace labels: map[kubernetes.io/metadata.name:debug-namespace]
# ...

# Удалить debug политику после использования
kubectl delete -f debug-context-inspector.yaml
kubectl delete namespace debug-namespace

Работа с PolicyException

# Применить исключение
kubectl apply -f policy-exception-example.yaml

# Проверить что исключение работает
kubectl run legacy-app-test \
  --image=nginx:1.25.3 \
  --restart=Never \
  -n production
# Под без limits должен создаться без ошибок

# Посмотреть все активные исключения
kubectl get policyexceptions -A

# Найти истекающие исключения (скрипт)
kubectl get policyexceptions -A -o json | \
  jq -r '.items[] |
  .metadata.name + " expires: " +
  .metadata.annotations["exception.company.com/expires"]' | \
  sort

Анализ PolicyReport для диагностики

# Найти ресурс который нарушает политику
POLICY="require-resource-limits"
kubectl get policyreports -A -o json | \
  jq --arg p "$POLICY" \
  -r '.items[] | .metadata.namespace as $ns |
  .results[] |
  select(.policy == $p and .result == "fail") |
  "\($ns)/\(.resources[0].name): \(.message)"'

# Сводная статистика
kubectl get policyreports -A -o json | \
  jq '{
    total: [.items[].results[]] | length,
    pass:  [.items[].results[] | select(.result=="pass")] | length,
    fail:  [.items[].results[] | select(.result=="fail")] | length
  }'