Files
kyverno-2026-example/07-advanced/02-external-data/README.md
2026-04-08 20:22:14 +07:00

173 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Урок 7.2 — Работа с внешними данными и API
## Файлы
| Файл | Описание |
|------|----------|
| `check-image-vulnerabilities.yaml` | Проверка уязвимостей через внешний API |
| `external-data-cache.yaml` | ConfigMap + CronJob + RBAC для кэша внешних данных |
| `validate-registry-from-cache.yaml` | Валидация реестра через кэшированный ConfigMap |
## Паттерн 1: Прямой вызов внешнего API
```yaml
# Требует включения в Kyverno:
# admissionController.extraArgs:
# - --enableExternalDataCall=true
context:
- name: result
apiCall:
urlPath: "https://your-api.company.com/check"
method: POST
data:
- key: image
value: "{{ request.object.spec.containers[0].image }}"
jmesPath: "status"
```
### Включение external data calls
```bash
helm upgrade kyverno kyverno/kyverno \
--namespace kyverno \
--reuse-values \
--set admissionController.extraArgs="{--enableExternalDataCall=true}"
# Проверить
kubectl get deployment kyverno-admission-controller -n kyverno \
-o jsonpath='{.spec.template.spec.containers[0].args}' | \
grep enableExternalDataCall
```
## Паттерн 2: Кэш через ConfigMap (рекомендуется)
Прямые вызовы внешних API медленные и создают зависимость.
Лучший паттерн: CronJob обновляет ConfigMap → политика читает из ConfigMap.
```
Внешний API ──(каждые N минут)──► CronJob ──► ConfigMap
Kyverno политика ◄───┘
(кэш, быстро)
```
### Применение кэша
```bash
# Применить всё: ConfigMap + CronJob + RBAC
kubectl apply -f external-data-cache.yaml
# Проверить ConfigMap
kubectl get configmap external-data-cache -n kyverno -o yaml
# Запустить CronJob вручную для немедленного обновления
kubectl create job --from=cronjob/update-policy-cache \
manual-update -n kyverno
# Следить за логами
kubectl logs -n kyverno \
-l job-name=manual-update \
--follow
# Применить политику использующую кэш
kubectl apply -f validate-registry-from-cache.yaml
```
## Паттерн 3: HashiCorp Vault интеграция
```bash
# Проверить доступность Vault перед деплоем с Vault секретами
kubectl apply -f - <<EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-vault-availability
spec:
rules:
- name: verify-vault-health
match:
resources:
kinds: [Pod]
preconditions:
any:
- key: "{{ request.object.metadata.annotations.\"vault.hashicorp.com/agent-inject\" }}"
operator: Equals
value: "true"
context:
- name: vaultHealth
apiCall:
urlPath: "https://vault.company.com:8200/v1/sys/health"
jmesPath: "initialized"
validate:
message: "Vault недоступен. Деплой с Vault секретами временно заблокирован."
deny:
conditions:
- key: "{{ vaultHealth }}"
operator: NotEquals
value: true
EOF
```
## Обработка недоступности внешнего API
```bash
# Fail-open vs Fail-closed
# Выбор зависит от критичности проверки
# Fail-open (разрешить если API недоступен):
# jmesPath: "result || 'ALLOWED'"
# deny если result == "DENIED"
# При недоступности: result = "ALLOWED" → под создаётся
# Fail-closed (запретить если API недоступен):
# jmesPath: "result || 'DENIED'"
# deny если result != "ALLOWED"
# При недоступности: result = "DENIED" → под НЕ создаётся
```
## Настройка timeout для внешних вызовов
```bash
# Webhook timeout влияет на все вызовы включая внешние API
helm upgrade kyverno kyverno/kyverno \
--namespace kyverno \
--reuse-values \
--set config.webhooks.timeoutSeconds=15
# По умолчанию 10 секунд. Увеличьте если внешний API медленный.
# Максимум — 30 секунд (ограничение Kubernetes).
```
## Мониторинг внешних вызовов
```bash
# Проверить что CronJob работает регулярно
kubectl get cronjobs -n kyverno
kubectl get jobs -n kyverno | grep update-policy-cache
# Последнее обновление кэша
kubectl get configmap external-data-cache -n kyverno \
-o jsonpath='{.data.last-updated}'
# Алерт если кэш устарел (добавьте в PrometheusRule)
# Используйте kube_configmap_info метрику и проверяйте
# что last-updated не старше N минут
```
## Безопасность при работе с внешними данными
```bash
# НЕ хардкодьте токены в политиках — используйте Secret
kubectl create secret generic external-api-token \
--from-literal=token=your-secret-token \
-n kyverno
# В политике читаем из Secret
# context:
# - name: apiToken
# apiCall:
# urlPath: "/api/v1/namespaces/kyverno/secrets/external-api-token"
# jmesPath: "data.token | base64_decode(@)"
```