АрхитектураОблако и инфраструктураИнженер платформенной инфраструктуры

Перед созданием пода кластер автоматически добавляет в него контейнер для сбора телеметрии. Какой механизм ...

Перед созданием пода кластер автоматически добавляет в него контейнер для сбора телеметрии. Какой механизм Kubernetes выполняет такое изменение?

Проходите собеседования с ИИ помощником Hintsage

Краткий ответ

Такое изменение обычно выполняет мутационный admission webhook. API-сервер Kubernetes перед сохранением объекта отправляет его внешнему webhook, получает изменённую версию пода и продолжает обработку уже с добавленным контейнером.

Исторический контекст

Механизм admission нужен для централизованного контроля объектов Kubernetes до их сохранения в хранилище состояния. Он решает проблему, при которой каждый разработчик должен был вручную добавлять одинаковые настройки безопасности, наблюдаемости или сетевого взаимодействия в каждый манифест.

Разделение на мутацию и проверку позволяет сначала автоматически изменить объект, а затем проверить итоговый результат политиками кластера.

Постановка проблемы

Если sidecar для телеметрии добавлять вручную, часть подов может остаться без него. Это приводит к неполному мониторингу, различиям между окружениями и ошибкам при обновлении шаблонов развертывания.

Централизация решает проблему единообразия, но добавляет зависимость от webhook. Его задержки или недоступность могут замедлить либо заблокировать создание подов, поэтому поведение при сбое должно быть осознанно настроено.

Подробное решение

Запрос к API-серверу проходит аутентификацию, авторизацию и затем admission-контроль. MutatingAdmissionWebhook получает подходящий объект через API-сервер, обычно в формате AdmissionReview, и возвращает набор изменений либо изменённый объект.

После применения мутаций Kubernetes выполняет последующие этапы admission-обработки, включая проверяющие политики. Поэтому валидировать нужно итоговый объект, а не только исходный манифест пользователя.

Webhook выбирает объекты по правилам применимости: группе ресурсов, версии, операции, ресурсу и, при необходимости, пространству имён или меткам. Для безопасного взаимодействия API-сервер проверяет TLS-соединение с webhook и использует настройки тайм-аута и поведения при ошибке.

Ключевые компромиссы:

  • failurePolicy: Fail сохраняет обязательность политики, но недоступность webhook может остановить создание подов;
  • failurePolicy: Ignore повышает доступность кластера, но допускает появление объектов без требуемой мутации;
  • дополнительный сетевой вызов увеличивает задержку каждого подходящего запроса;
  • мутация должна быть идемпотентной, чтобы повторная обработка не добавляла дубликаты;
  • webhook получает чувствительные данные объектов, поэтому его доступ, сертификаты и область действия нужно ограничивать;
  • порядок взаимодействия нескольких мутационных webhook не следует использовать как скрытый механизм координации.

Для обязательного sidecar обычно выбирают отказоустойчивую конфигурацию с контролем доступности webhook, коротким тайм-аутом, ограниченным набором ресурсов и явной проверкой результата. Для необязательной телеметрии иногда допустима политика пропуска при сбое, если временная потеря метрик предпочтительнее остановки развертывания.

Ситуация из практики

В кластере необходимо добавлять агент трассировки во все поды приложений, кроме системных. Рассматривались три варианта: вручную менять манифесты, использовать общий шаблонизатор или применить mutating webhook.

Ручное изменение проще для отладки, но со временем приводит к пропускам и расхождениям. Шаблонизатор делает результат предсказуемым на этапе сборки, однако не защищает от объектов, созданных другим инструментом. Webhook контролирует сам вход в API-сервер, но добавляет сетевую зависимость и риск влияния на доступность кластера.

Выбрали webhook с исключением системных пространств имён, ограниченными правилами выбора объектов и проверкой идемпотентности. Для обязательных приложений использовали отказ при недоступности webhook, а для тестовых пространств — разрешение продолжить создание без агента. В результате новые поды получили единый способ подключения телеметрии, а область отказа webhook ограничили настройками применимости.

Что кандидаты часто упускают

  1. Что произойдёт, если mutating webhook недоступен во время создания пода?

Ответ: результат определяется его политикой обработки ошибки. При Fail API-сервер отклонит запрос после тайм-аута или ошибки webhook, поэтому под не будет создан. При Ignore запрос продолжится без изменения, что сохраняет доступность, но может нарушить обязательное требование к телеметрии или безопасности.

Выбор зависит от назначения мутации. Для обязательного ограничения безопасности пропуск обычно неприемлем, а для необязательного агента наблюдаемости он может быть допустим. В обоих случаях нужно отслеживать ошибки webhook и его задержку.

  1. Почему мутация webhook должна быть идемпотентной?

Ответ: один объект может обрабатываться повторно из-за повторной отправки запроса, механизмов переобработки или взаимодействия нескольких мутационных webhook. Неидемпотентная логика при каждом вызове будет снова добавлять контейнер, том или переменную окружения.

Идемпотентная мутация сначала проверяет наличие нужного элемента и изменяет объект только при необходимости. Это предотвращает дубликаты, конфликт имён, некорректные спецификации пода и непредсказуемое поведение при повторной обработке.

  1. Чем mutating admission webhook отличается от контроллера, исправляющего объект после создания?

Ответ: webhook изменяет запрос синхронно до сохранения объекта. Пользователь и последующие компоненты сразу видят уже изменённую спецификацию, а не временно некорректное состояние.

Контроллер работает асинхронно после появления объекта и обычно наблюдает его через API-сервер, затем создаёт или изменяет связанные ресурсы. Это лучше подходит для длительных процессов и согласования состояния, но не гарантирует, что объект с нужным изменением никогда не существовал даже кратковременно. Для обязательной предварительной инъекции sidecar подходит admission webhook, а для управления жизненным циклом связанных ресурсов — контроллер.