Кастомные Admission Webhooks: валидация и мутация в Kubernetes

Стандартные политики не всегда справляются со сложной логикой проверки и автоматического изменения ресурсов Kubernetes. Мы разрабатываем кастомные Admission Webhooks, которые валидируют и мутируют объекты по вашим уникальным правилам. Наша команда реализует проект под ключ — от аудита до внедрения и последующей поддержки.
Часто задаваемые вопросы

Разработка кастомных Admission Webhooks для Kubernetes

Наша команда часто сталкивается с ситуацией: инженеры деплоят Pod без resources.requests, с securityContext и imagePullPolicy: Never, используя latest-тег. Политики Kyverno или OPA Gatekeeper могут запретить это на уровне правил. Но если логика требует обращения к внешнему сервису — корпоративному API для проверки секретов или автоматической простановки аннотаций на основе бизнес-правил? В таких случаях стандартные инструменты бессильны. Мы разрабатываем кастомные Admission Webhooks — гибкое решение для валидации и мутации любых ресурсов Kubernetes. Свяжитесь с нами, чтобы обсудить ваш кейс — мы поможем автоматизировать политики и сэкономить бюджет на поддержку кластера.

Два типа вебхуков: Validating и Mutating

ValidatingAdmissionWebhook получает объект, возвращает разрешить или отклонить, не изменяя его. Используется для проверок: "этот ImagePullSecret существует?", "у namespace есть approved label?", "образ не содержит уязвимостей?" через сторонний сканер. MutatingAdmissionWebhook может изменять объект с помощью JSON Patch перед сохранением. Применяется для автоподстановки sidecar-контейнеров, добавления аннотаций, нормализации полей, инжекции переменных окружения.

Характеристика Validating Webhook Mutating Webhook
Изменяет объект? Нет Да (JSON Patch)
Порядок вызова После всех мутаций Первыми, параллельно
Типичное применение Валидация параметров безопасности Добавление sidecar, аннотаций

Порядок вызова: сначала все Mutating вебхуки (параллельно, затем при изменениях повторно), затем все Validating (параллельно). Validating вебхук видит финальный объект после всех мутаций.

Почему кастомный webhook, а не Kyverno?

Kyverno — отличный инструмент для статических политик на основе Rego. Но когда требуется обращение к внешнему API (например, проверка лицензии контейнера), сложная бизнес-логика с ветвлениями и циклами, интеграция с системой тикетов (Jira) или CMDB, динамическая генерация конфигурации на основе метаданных кластера — тогда кастомный webhook на Go или Python даёт полный контроль. Он работает в 2–3 раза быстрее при большом количестве обращений, так как не тратит время на интерпретацию Rego-правил. Стоимость разработки окупается за счёт предотвращения сбоев и сокращения времени на ручные проверки.

Как обеспечить отказоустойчивость вебхука?

Admission Webhook должен быть развёрнут минимум с двумя репликами (HPA) и настроен с failurePolicy: Fail для критических проверок. Используйте namespaceSelector, чтобы исключить системные namespace (kube-system). Сертификаты TLS обновляются автоматически через cert-manager. Таймаут вебхука — не более 5 секунд, иначе замедлится работа кластера. Экономия на инцидентах может составить до 30% времени простоя.

Структура вебхука: что внутри

Вебхук — это HTTPS-сервер, принимающий AdmissionReview запросы. Пример на Go:

package main

import (
	"encoding/json"
	"net/http"

	admissionv1 "k8s.io/api/admission/v1"
	corev1 "k8s.io/api/core/v1"
)

func validatePod(w http.ResponseWriter, r *http.Request) {
	var admReview admissionv1.AdmissionReview
	json.NewDecoder(r.Body).Decode(&admReview)

	pod := &corev1.Pod{}
	json.Unmarshal(admReview.Request.Object.Raw, pod)

	allowed := true
	message := ""

	for _, container := range pod.Spec.Containers {
		if container.Resources.Requests == nil {
			allowed = false
			message = "container " + container.Name + " must specify resources.requests"
			break
		}
	}

	response := admissionv1.AdmissionReview{
		TypeMeta: admReview.TypeMeta,
		Response: &admissionv1.AdmissionResponse{
			UID:     admReview.Request.UID,
			Allowed: allowed,
			Result: &metav1.Status{
				Message: message,
			},
		},
	}

	json.NewEncoder(w).Encode(response)
}

Вебхук должен работать по HTTPS с TLS-сертификатом, подписанным кластерным или доверенным CA. Kubernetes не принимает HTTP и не принимает самоподписанные сертификаты без явного caBundle в WebhookConfiguration.

Регистрация вебхука

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: pod-validator
webhooks:
  - name: validate.pods.example.com
    admissionReviewVersions: ["v1"]
    clientConfig:
      service:
        name: pod-validator
        namespace: webhook-system
        path: /validate
      caBundle: <BASE64_CA_CERT>
    rules:
      - operations: ["CREATE", "UPDATE"]
        apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]
    failurePolicy: Fail # Ignore или Fail
    namespaceSelector:
      matchExpressions:
        - key: webhook-validation
          operator: In
          values: ["enabled"]
    sideEffects: None
    timeoutSeconds: 5
Параметр Fail Ignore
Если вебхук недоступен Блокирует создание ресурса Пропускает проверку
Для каких политик Критические политики безопасности Вспомогательные аннотации
Влияние на кластер Останавливает деплой при сбое вебхука Позволяет игнорировать ошибки вебхука

timeoutSeconds: 5 — Kubernetes ждёт ответа вебхука максимум 5 секунд. Медленный вебхук замедляет создание всех Pod в кластере. Это главная причина, почему вебхук должен быть быстрым: никаких синхронных обращений к медленным внешним API.

namespaceSelector — вебхук применяется только к namespace с лейблом webhook-validation=enabled. Обязательно исключите kube-system и webhook-system, иначе вебхук может заблокировать системные компоненты.

Mutating вебхук: JSON Patch

Возврат патча для автодобавления labels и переменных окружения:

patch := []map[string]interface{}{
	{
		"op":    "add",
		"path":  "/metadata/labels/injected-by",
		"value": "admission-webhook",
	},
	{
		"op":    "add",
		"path":  "/spec/containers/0/env/-",
		"value": map[string]string{
			"name":  "TENANT_ID",
			"value": tenantID,
		},
	},
}
patchBytes, _ := json.Marshal(patch)
patchType := admissionv1.PatchTypeJSONPatch
response.Patch = patchBytes
response.PatchType = &patchType

TLS и деплой

Для управления TLS-сертификатами используем cert-manager. Ресурс Certificate с issuerRef на кластерный CA автоматически создаёт Secret с сертификатом и обновляет его при истечении. Webhook caBundle обновляется через аннотацию:

metadata: annotations: cert-manager.io/inject-ca-from: webhook-system/pod-validator-cert 

Это избавляет от ручной ротации сертификата — одной из самых частых причин инцидентов, когда webhook cert expires и все деплои начинают падать.

Что входит в работу

  • Разработка сервера на Go (или Python) с бизнес-логикой
  • Unit-тесты и интеграционные тесты (envtest, kind)
  • Настройка TLS через cert-manager
  • Helm-чарт для деплоя в кластер
  • CI/CD пайплайн (GitLab CI) с авторазвёртыванием
  • Документация по настройке и эксплуатации
  • Пост-релизная поддержка в течение 2 недель
  • Обучение команды по администрированию

Этапы работы

  1. Аналитика — аудит текущих политик, описание требований (что валидировать/мутировать, какие ресурсы, namespace)
  2. Проектирование — архитектура webhook, схема данных, сценарии отказов
  3. Разработка — написание сервера, интеграционных тестов
  4. Тестирование — проверка на тестовом кластере (kind), нагрузочное тестирование
  5. Деплой — развёртывание в production с HPA и мониторингом
  6. Документация — инструкции для команды по изменению правил

Сроки и стоимость

Срок разработки — от 3 до 5 дней в зависимости от сложности логики. Стоимость рассчитывается индивидуально после аудита инфраструктуры. Свяжитесь с нами для оценки вашего проекта — мы имеем 5+ лет опыта с Kubernetes, реализовали более 30 подобных решений. Оставьте заявку, и мы подготовим предложение. Закажите консультацию, чтобы узнать, как кастомный вебхук может сэкономить ваш бюджет.

Официальная документация Kubernetes описывает Admission Webhooks как основной механизм расширения политик кластера (см. Kubernetes Admission Webhooks).

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1141