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
2026-04-08 20:22:14 +07:00

Урок 7.2 — Работа с внешними данными и API

Файлы

Файл Описание
check-image-vulnerabilities.yaml Проверка уязвимостей через внешний API
external-data-cache.yaml ConfigMap + CronJob + RBAC для кэша внешних данных
validate-registry-from-cache.yaml Валидация реестра через кэшированный ConfigMap

Паттерн 1: Прямой вызов внешнего API

# Требует включения в 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

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 политика ◄───┘
                              (кэш, быстро)

Применение кэша

# Применить всё: 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 интеграция

# Проверить доступность 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

# 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 для внешних вызовов

# Webhook timeout влияет на все вызовы включая внешние API
helm upgrade kyverno kyverno/kyverno \
  --namespace kyverno \
  --reuse-values \
  --set config.webhooks.timeoutSeconds=15

# По умолчанию 10 секунд. Увеличьте если внешний API медленный.
# Максимум — 30 секунд (ограничение Kubernetes).

Мониторинг внешних вызовов

# Проверить что 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 минут

Безопасность при работе с внешними данными

# НЕ хардкодьте токены в политиках — используйте 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(@)"