6.0 KiB
6.0 KiB
Урок 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
}'