Дополнительные контейнеры в Kubernetes и где они обитают: от паттернов к автоматизации управления

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Всем известно, что pod в Kubernetes может включать в себя несколько контейнеров: для Service Mesh, работы с внешним хранилищем секретов, журналирования и т. д. В итоге это множество вызывает вопросы. Правильно ли использовать столько контейнеров? Как их изолировать от пользовательских приложений? Можно ли вообще исключить дополнительные контейнеры из пользовательских релизов?

Я Максим Чудновский, занимаюсь Synapse Service Mesh в СберТехе. Расскажу, какие есть паттерны применения дополнительных контейнеров в Kubernetes, как они могут помочь в платформенной инженерии, и, самое главное, как полностью автоматизировать процесс управления жизненным циклом таких контейнеров.

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

Можно ли использовать много контейнеров в одном поде

Для ответа на этот вопрос обратимся к замечательной книге «Kubernetes Patterns» от O'Reilly.

В части, посвящённой структурным паттернам, описано, как организовать своё приложение в Kubernetes с точки зрения структуры пода в Kubernetes: что там должно быть, а от чего лучше отказаться.

В общем виде можно выделить 4 вида дополнительных «полезных» контейнеров:

  1. Init;

  2. Sidecar;

  3. Adapter;

  4. Ambassador.

Давайте рассмотрим их подробнее.

Init Containers

Как видно из названия, init-контейнеры нужны для того, чтобы инициализировать приложение. В отличие от обычных, они имеют собственный жизненный цикл: всегда выполняются первыми, а основные контейнеры стартуют только по их завершению. Это удобно, когда необходимо что-то подготовить, например, можно получить доступ к каким-то секретам или сделать редирект сетевого трафика через модификацию iptables. А после этого запустить само приложение и забыть про эти вещи.

Sidecar Containers

В общем случае sidecar-контейнер — это контейнер с законченной функциональностью, которая нужна приложению, но не является частью его бизнес-логики. За счёт такого разделения разработчики могут фокусироваться на одной задаче. Платформенная команда отвечает за дополнительные возможности, например, делает приложение более отказоустойчивым, надёжным. В свою очередь прикладные разработчики занимаются исключительно бизнес-логикой приложения.

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

  • Service Mesh — в этом случае добавляется сетевой прокси, который обрабатывает все запросы, добавляет observability, делает mutual TLS и остальные полезные вещи.

  • Журналирование, если вам по каким-то причинам не нравится решение собирать логи через daemon, который бежит на воркере Kubernetes и забирает данные сразу с контейнерного runtime'а.

  • Централизованный аудит.

Adapter Containers

Адаптеры — такие же sidecar’ы, но узкоспециализированные. Они используются тогда, когда в приложение нужно добавить новый API, но не хочется (или не получается) сделать это на уровне приложения.

Вот классические примеры:

  • Metrics API. Есть система мониторинга на базе Prometheus и приложение, которое про эту систему мониторинга вообще ничего не знает. У этого приложения есть либо только свои метрики, либо нет вообще нет никаких. Для «неинвазивного» решения проблемы достаточно добавить Prometheus экспортер отдельным контейнером, который опубликует все нужные метрики в правильном формате.

  • Custom API. Позволяет добавить произвольный API по аналогии с примером метрик.

  • RBAC Proxy. Дополнительный контейнер становится точкой входа в приложение и добавляет стандартный RBAC Kubernetes. Это делается очень быстро и во многих случаях бывает полезно.

Ambassador Containers

Эти контейнеры похожи на адаптеры, но работают в обратную сторону: они инкапсулируют в себя всю сложность внешнего API и позволяют использовать его понятным для приложения способом.

Распространённые примеры использования:

  • Kubernetes API Access. Допустим, наше приложение умеет работать только с файлами и может читать оттуда свои конфигурации. При этом количество файлов не ограничено, и состав часто меняется — пользователи добавляют новые и удаляют неактуальные. Стандартная история с ConfigMaps тут не слишком удобная.

Придётся либо постоянно менять спецификацию приложения и добавлять новые каталоги монтирования, либо все файлы будут в одной ConfigMap, и её крайне сложно редактировать в многопользовательском режиме. Для решения этой проблемы можно научить приложение самостоятельно ходить в Kubernetes API и доставать нужную информацию. Но ещё проще поставить рядом Ambassador sidecar, который всё это сделает и за нас, и за приложение.

  • Distributed or Local Cache Access. Можно унифицировать доступ к сложным распределённым кешам со стороны приложения.

  • Data Access within a Data Mesh. Можно построить витрину данных, которая доступна непосредственно приложению.

Как добавлять контейнеры?

Самый простой способ — использовать обычные Kubernetes-манифесты. Достаточно добавить нужные контейнеры в спецификацию деплоймента (template spec). Но этот способ приводит к огромному количеству boilerplate yaml-файлов.

Кажется, что решением могут стать различные template-менеджеры (Helm, Kustomize, CUE и т. д.). Они дадут какое-никакое управление зависимостями: платформенные команды смогут публиковать свои артефакты, на которые уже прикладные разработчики будут ссылаться и использовать. В результате количество yaml-кода сильно сократится.

Но есть нюанс: template-менеджеры в конечном итоге развернут все в тот самый Raw Kubernetes Resource, который будет использован в кластере.

В целом это рабочий подход. Но есть нюанс: у платформенных и прикладных разработчиков разный релизный цикл. И платформенным командам нужно публиковать свои sidecars независимо, без запроса на обновление бизнес-приложения, а сделать это будет невозможно.

Для enterprise-решений это довольно серьезная проблема, поэтому важно разводить эти два релизных процесса. Хорошо, что Kubernetes позволяет это сделать.

Automated Approach — k8s admission

Когда вы создаёте объект внутри Kubernetes (например, делаете kubectl apply -f myfile.yaml), он проходит предобработку из нескольких этапов, которые реализуются с помощью специализированных admission контроллеров.

Они встроены в kube-api, включаются определёнными флагами и делают много полезного. Например, есть admission-контроллер Service Account, который монтирует токен Service Account в под, чтобы вы могли ходить в kube-api. Но нам интересен другой — mutation admission.

Когда Kubernetes видит новый запрос, он вызывает этот контроллер (как и все остальные), чтобы обработать ресурс. Суть в том, что mutating admission— кастомизируемый. Таким образом мы получаем инструмент расширения admission-контроллеров, чтобы создавать свою кастомную логику, которая отвечает за изменение («мутацию») создаваемых ресурсов «на лету».

Это очень удобно и Kubernetes-native. Мы создаем Mutating Admission Configuration, регистрируем webhook и выполняем нужные мутации. Например, автоматически добавляем sidecar-контейнеры при старте пода.

Решения, которые используют данный подход, называются Sidecar Injectors. В следующем материале подробно расскажу, как они устроены, а заодно поделюсь опытом автоматизации управления sidecars и готовыми open source решениями, которые позволяют комплексно решать такие задачи.

Источник: https://habr.com/ru/companies/oleg-bunin/articles/761662/


Интересные статьи

Интересные статьи

Давайте поговорим о записи логов событий, происходящих в кластере Kubernetes. Эти логи можно использовать для устранения неполадок на уровне кластера, чтобы восстановить, когда и как конфигурация клас...
Любая распределенная система, например включающая несколько микросервисов со своими источниками данных (и особенно запущенная внутри сложной системы оркестрации, которая сама по сути является распреде...
Если вы подыскиваете программнное обеспечение для управления проектами, то Asana или Jira будут отличным выбором. В этой статье обсудим плюсы и минусы каждого из них, чтобы вы смогли выбрать самое под...
Здесь есть поклонники Kubernetes? Я уже довольно давно пользуюсь Kubernetes как на работе, так и в других местах, где занимаюсь частными проектами, но иногда мне нужно ме...
Поддержка в рабочем состояние заданного набора контейнеров является одним из главных преимуществ использования KubernetesВ этой статье я хотел бы на практике разобраться ...