1. Архитектура Control Plane и жизненный цикл API-запроса: механизмы аутентификации, авторизации и Admission Control
Когда администратор выполняет команду kubectl run nginx --image=nginx, в кластере не запускается ни одного контейнера. Kubernetes вообще не знает, что такое Docker, containerd или процессы операционной системы. Единственное, что происходит в этот момент — клиент формирует JSON-документ, описывающий желаемое состояние, и отправляет его через HTTP POST-запрос к единственному открытому порту кластера. Всё, что мы называем «магией оркестрации», — это лишь каскад асинхронных реакций системных компонентов на изменение данных в центральном хранилище.
Центральным узлом этой системы выступает Control Plane — управляющий слой кластера, который принимает решения, хранит состояние и координирует работу узлов. Понимание того, как именно Control Plane обрабатывает входящие запросы, является фундаментом для траблшутинга, настройки безопасности и разработки собственных расширений (операторов).
Архитектура Control Plane: единая точка входа
Управляющий слой Kubernetes спроектирован вокруг принципа декларативного управления состоянием. Он состоит из нескольких независимых компонентов, которые взаимодействуют друг с другом исключительно через REST API.
kubelet) и другие элементы Control Plane. Он не выполняет никакой бизнес-логики по управлению контейнерами, его задача — валидация запросов, применение политик безопасности и сохранение состояния.kube-apiserver, не имеет прямого доступа к etcd.nodeName пустое). Найдя такой Pod, планировщик вычисляет оптимальный узел и отправляет обратно в API-сервер запрос на обновление (Binding).Deployment, именно контроллер Deployment заметит это и создаст соответствующий ReplicaSet, который, в свою очередь, создаст Pod.!Архитектура Control Plane Kubernetes
Эта архитектура реализует паттерн «Hub and Spoke», где API-сервер является ступицей (hub), а все остальные компоненты — спицами (spokes). Ни один контроллер не вызывает другой контроллер напрямую. Все они работают по принципу Level-Triggered логики: подписываются на изменения ресурсов через механизм Watch (постоянное HTTP-соединение с потоковой передачей событий) и реагируют на новые или изменённые объекты.
Жизненный цикл API-запроса
Поскольку kube-apiserver является единственной дверью в кластер, он должен быть абсолютно надёжным стражем. Когда HTTP-запрос достигает API-сервера, он проходит через строгий конвейер обработки (Request Pipeline). Если запрос не проходит хотя бы один этап, он немедленно отклоняется.
!Конвейер обработки API-запроса
Весь жизненный цикл запроса можно разбить на пять ключевых фаз: терминация TLS, аутентификация, авторизация, Admission Control и сохранение в базу данных.
1. HTTP-обработчик и терминация TLS
Любое взаимодействие с kube-apiserver происходит по протоколу HTTPS. На первом этапе сервер принимает соединение, выполняет TLS-рукопожатие и расшифровывает трафик. Здесь же срабатывают базовые HTTP-фильтры:
429 Too Many Requests.После успешного прохождения базовых сетевых фильтров сервер извлекает HTTP-заголовки, URI и тело запроса, чтобы передать их подсистеме безопасности.
2. Аутентификация (Authentication / AuthN)
Задача этого этапа — ответить на вопрос: «Кто делает этот запрос?».
В Kubernetes нет встроенного объекта User или Group в виде ресурсов, которые можно было бы создать через kubectl create user. Кластер делегирует управление пользователями внешним системам. API-сервер последовательно прогоняет запрос через цепочку настроенных аутентификаторов. Как только один из них успешно распознает пользователя, процесс останавливается, и запрос передается дальше.
Основные механизмы аутентификации:
X.509 Клиентские сертификаты Это стандартный метод аутентификации администраторов и компонентов кластера. API-сервер проверяет, подписан ли сертификат клиента доверенным удостоверяющим центром (CA кластера). Если подпись верна, сервер извлекает идентификационные данные прямо из полей сертификата:
CN (Common Name) становится именем пользователя (например, CN=admin).O (Organization) интерпретируются как группы (например, O=system:masters).Bearer Tokens (OIDC / ServiceAccounts)
Для интеграции с корпоративными системами (Active Directory, Google Workspace) используется OpenID Connect (OIDC). Пользователь получает JWT-токен от внешнего провайдера и прикрепляет его к запросу в заголовке Authorization: Bearer <token>. API-сервер проверяет криптографическую подпись токена с помощью публичного ключа провайдера и извлекает из поля claims имя пользователя и группы.
Отдельный класс токенов — токены ServiceAccount. В отличие от обычных людей-пользователей, ServiceAccounts — это полноценные объекты внутри Kubernetes, предназначенные для аутентификации самих приложений (Pod'ов). Когда Pod запускается, kubelet монтирует токен ServiceAccount внутрь контейнера по пути /var/run/secrets/kubernetes.io/serviceaccount. Приложение может использовать этот токен для легитимного обращения к API-серверу.
Если ни один аутентификатор не смог опознать субъекта, запрос либо отклоняется со статусом 401 Unauthorized, либо помечается как system:anonymous (если анонимный доступ разрешен в конфигурации).
3. Авторизация (Authorization / AuthZ)
Узнав, кто пришел, API-сервер должен выяснить: «Имеет ли этот субъект право выполнить запрошенное действие?».
Запрос трансформируется во внутреннюю структуру AttributesRecord, которая содержит:
create, GET → get или list, PUT → update).pods) и его API-группу.В Kubernetes используется парадигма Deny-by-Default (запрещено всё, что не разрешено явно). Запрос проходит через модули авторизации (Node, ABAC, RBAC, Webhook). Самым распространенным и гибким является RBAC (Role-Based Access Control).
Механизм RBAC строится на трех китах:
get и list для ресурсов pods в группе core». Role действует в рамках одного Namespace, а ClusterRole — на уровне всего кластера.Когда приходит запрос, модуль RBAC ищет все Binding'и, связанные с данным пользователем и его группами. Затем он проверяет, покрывают ли правила из связанных ролей запрашиваемое действие. Если найдено хотя бы одно совпадение — запрос авторизован. Если после проверки всех политик совпадений нет, возвращается 403 Forbidden.
> Важный нюанс: RBAC не умеет проверять содержимое запроса. Он может разрешить пользователю создавать Pod'ы, но не может запретить создавать Pod'ы, требующие больше гигабайт памяти, или Pod'ы, использующие образ nginx:latest. Для инспекции полезной нагрузки используется следующий этап.
4. Admission Control (Контроль допуска)
Это самый сложный и мощный этап конвейера. В отличие от авторизации, Admission Control имеет доступ к полному JSON-телу запроса. Именно здесь реализуются корпоративные политики, мутации объектов и глубокая валидация.
Admission Control работает только для мутирующих запросов (CREATE, UPDATE, DELETE). Запросы на чтение (GET, LIST) этот этап пропускают.
Процесс разделен на две последовательные фазы: Mutating Admission (изменение) и Validating Admission (проверка).
#### Фаза 4.1: Mutating Admission
На этом этапе контроллеры могут модифицировать входящий объект до его сохранения. В Kubernetes встроено множество таких контроллеров. Например, DefaultStorageClass автоматически добавляет класс хранилища по умолчанию к объектам PersistentVolumeClaim, если пользователь его не указал.
Помимо встроенных плагинов, администраторы могут создавать собственные с помощью MutatingAdmissionWebhook. Это механизм, позволяющий API-серверу сделать внешний HTTP-вызов к вашему собственному сервису.
Классический пример использования Mutating Webhook — инъекция sidecar-контейнеров в Service Mesh (например, Istio).
containers еще один контейнер с образом envoy-proxy».Поскольку мутирующие вебхуки могут изменять объект последовательно, и один вебхук может изменить данные, которые важны для другого, API-сервер может прогнать объект через цепочку мутаций несколько раз, пока состояние не стабилизируется.
#### Фаза 4.2: Object Schema Validation
После завершения всех мутаций API-сервер проверяет итоговый объект на соответствие OpenAPI-схеме. Если в манифесте указано строковое значение там, где ожидается число (например, replicas: "три"), запрос будет отклонен на этом этапе.
#### Фаза 4.3: Validating Admission Финальный этап проверки. Здесь объект уже нельзя изменить — можно только сказать «да» или «нет».
Встроенные контроллеры, такие как ResourceQuota или LimitRanger, проверяют, не превышает ли создаваемый объект выделенные лимиты ресурсов в Namespace.
Как и в случае с мутациями, здесь можно использовать ValidatingAdmissionWebhook. Это основной инструмент для обеспечения безопасности и комплаенса. Инструменты вроде OPA Gatekeeper или Kyverno работают именно как Validating Webhooks. Они могут, например, отклонить запрос, если образ контейнера скачивается не из доверенного приватного реестра, или если контейнер пытается запуститься в привилегированном режиме (securityContext.privileged: true).
Если вебхук недоступен (например, сервис упал), поведение API-сервера определяется параметром failurePolicy в конфигурации вебхука. Значение Fail означает, что запрос будет отклонен (строгая безопасность), а Ignore — что запрос пройдет дальше (высокая доступность, но риск нарушения политик).
5. Сохранение в etcd (Persistence)
Если запрос успешно прошел аутентификацию, авторизацию и обе фазы Admission Control, API-сервер сериализует итоговый объект и инициирует транзакцию записи в etcd.
Здесь вступает в игру механизм оптимистичной блокировки (Optimistic Concurrency Control), который предотвращает состояние гонки (race conditions) при одновременном обновлении одного объекта разными контроллерами.
Каждый объект в Kubernetes имеет скрытое поле metadata.resourceVersion. Это строковое представление внутреннего счетчика ревизий etcd.
Когда контроллер хочет обновить объект, он отправляет PUT-запрос, в котором указывает ту resourceVersion, которую он прочитал ранее.
API-сервер передает этот запрос в etcd. Если текущая версия в базе данных совпадает с присланной, запись происходит успешно, и resourceVersion инкрементируется. Если же другой контроллер успел обновить объект долей секунды раньше, версия в базе уже изменилась. В этом случае etcd отклоняет транзакцию, а API-сервер возвращает клиенту ошибку 409 Conflict.
Получив 409 Conflict, клиент (например, ваш кастомный оператор) обязан заново прочитать актуальное состояние объекта из API, заново применить свои изменения и повторить попытку записи.
Завершение жизненного цикла
После успешного сохранения данных в etcd, API-сервер формирует HTTP-ответ (например, 201 Created для новых объектов) и отправляет его клиенту.
Но на этом работа кластера только начинается. Как только транзакция зафиксирована в etcd, API-сервер генерирует событие Added или Modified и рассылает его всем компонентам, которые удерживают открытое соединение Watch для данного типа ресурсов. Планировщик видит новый Pod и начинает искать для него узел. Kubelet на выбранном узле видит, что ему назначен Pod, и начинает скачивать образы. Контроллер конечных точек (Endpoint Controller) замечает появление новых IP-адресов и обновляет правила маршрутизации.
Каждый компонент выполняет свою узкую задачу, реагируя на изменение состояния в базе данных. Именно эта хореография, управляемая строгими правилами API-сервера, делает Kubernetes столь масштабируемой и расширяемой платформой. Понимая каждый шаг конвейера обработки запроса, инженер получает возможность не просто использовать кластер, но и органично встраивать в него собственную логику на любом этапе — от кастомной аутентификации до динамической мутации ресурсов на лету.