От переводчика: в апреле 2025 года вышел релиз Kubernetes 1.33, который принёс множество значимых нововведений — читайте наш подробный обзор новых возможностей. А в этом переводе мы рассказываем об одной из важных возможностей из этого релиза — поддержке мультиконтейнерных подов и связанных с ними паттернов, таких как сайдкар (sidecar).
По мере развития нативных облачных архитектур Kubernetes утвердился в качестве основной платформы для развёртывания сложных распределённых систем. Одним из наиболее мощных, но в то же время требующих тонкого подхода паттернов проектирования в этой экосистеме является сайдкар — методика, которая позволяет разработчикам расширять функциональность приложений без глубокого вмешательства в их исходный код.

Происхождение сайдкар-паттерна
Исторически в ИТ-инфраструктурах всегда использовались вспомогательные сервисы для выполнения критически важных задач. До появления контейнеров для управления логированием, мониторингом и сетью полагались на фоновые процессы и демоны-помощники. Микросервисы изменили этот подход, превратив сайдкары в структурированное и осознанное архитектурное решение.
С ростом популярности микросервисов паттерн «сайдкар» оформился окончательно. Он позволяет разработчикам «выгрузить» часть задач из главного сервиса, не трогая его код. Сервис-меши (service mesh) типа Istio и Linkerd сделали прокси на базе сайдкаров очень популярными. Опыт их эксплуатации показывает, что такие контейнеры-напарники отлично решают вопросы наблюдаемости, безопасности и управления трафиком в распределённых системах.
Как это выглядит в Kubernetes
В Kubernetes сайдкары работают в том же поде, что и основное приложение. Это позволяет им обмениваться данными и совместно использовать ресурсы. Выглядит все так, словно в поде работает не один, а несколько обычных контейнеров… Собственно, так оно и было до версии Kubernetes 1.28 — в ней сайдкар-контейнеры наконец получили нативную поддержку. Теперь их можно прописать в манифесте пода в поле spec.initContainers
. Сайдкаром такой контейнер делает политика перезапуска restartPolicy: Always
. Посмотрите на пример ниже — это фрагмент манифеста Kubernetes:
initContainers:
- name: logshipper
image: alpine:latest
restartPolicy: Always
command: ['sh', '-c', 'tail -F /opt/logs.txt']
volumeMounts:
- name: data
mountPath: /opt
Название поля spec.initContainers
может вызывать недоумение. Почему сайдкар-контейнер описывается в разделе spec.initContainers
? Ведь init-контейнеры (из spec.initContainers
) отрабатывают всего один раз перед стартом основного приложения, в то время как сайдкары часто работают параллельно с главным контейнером приложения. Дело в том, что сочетание spec.initContainers
и restartPolicy:Always
отличает классические init-контейнеры от нативных сайдкаров Kubernetes и гарантирует, что последние работают постоянно.
Отличия от контейнеров приложений
Сайдкары работают вместе с контейнерами приложений в одном поде. Однако они никак не участвуют в базовой логике. Их задача — помогать основному приложению, предоставляя ему дополнительные возможности.
У сайдкар-контейнеров собственный, независимый жизненный цикл. Их можно запускать, останавливать и перезапускать независимо от контейнеров приложения. То есть сайдкары можно обновлять, масштабировать или обслуживать, не затрагивая основное приложение.
Сайдкар-контейнеры живут в тех же пространствах имён, что и основной контейнер. Такое близкое размещение позволяет им тесно взаимодействовать и использовать ресурсы (например, сети и хранилища) совместно.
Для Kubernetes корректное завершение работы сайдкар-контейнера не так важно. Если другие контейнеры исчерпают время, выделенное на корректное завершение работы (graceful shutdown), сайдкары получат сигнал SIGTERM, а затем SIGKILL — у них не будет времени завершиться корректно. Поэтому ненулевые коды выхода (0 означает успешный выход) для сайдкаров при завершении работы пода — это нормально, и внешним инструментам обычно следует их игнорировать.
Отличия от init-контейнеров
Сайдкар-контейнеры работают рядом с основным контейнером, расширяя его функциональность и предоставляя дополнительные сервисы.
Сайдкары работают одновременно с контейнером основного приложения. Они активны в течение всего жизненного цикла пода, и их можно запускать и останавливать независимо от основного контейнера. В отличие от init-контейнеров, сайдкары поддерживают пробы (probes), которые позволяют отследить их состояние, и обработчики жизненного цикла PostStart
и PreStop
.
Сайдкары могут напрямую взаимодействовать с контейнерами основного приложения, потому что, как и init-контейнеры, они находятся в одном пространстве имён.
Init-контейнеры останавливаются до того, как запускаются основные контейнеры, поэтому они не могут обмениваться сообщениями с контейнером приложения в поде. Передача данных возможна только в одну сторону (например, init-контейнер может записать информацию в том emptyDir).
Изменение образа сайдкар-контейнера не приведёт к перезапуску всего пода, однако инициирует перезапуск самого контейнера.
Когда следует и не следует использовать сайдкары
Сайдкар-паттерн бывает очень кстати, но обычно это не лучший выбор по умолчанию — его стоит применять, только если это действительно необходимо. Сайдкар — это всегда усложнение, повышенный расход ресурсов и потенциальное увеличение сетевых задержек. Поэтому сначала подумайте, нельзя ли обойтись без него (например, встроенными библиотеками или какой-то общей инфраструктурой).
Когда стоит использовать сайдкары:
При необходимости расширить возможности приложения, не трогая его основной код.
Для реализации общих (сквозных) задач, таких как сбор логов, мониторинг или безопасность.
При работе с legacy-приложениями, которым требуются современные сетевые возможности.
При разработке микросервисов, которые должны масштабироваться и обновляться независимо друг от друга.
Когда не стоит использовать сайдкары:
Если для вас главное — экономия ресурсов.
Если критически важна минимальная задержка в сети.
Если задачу можно решить более простыми способами.
Если нужно максимально упростить поиск и устранение проблем.
Четыре основных паттерна для подов с несколькими контейнерами
Паттерн Init
Init-контейнер выполняет важные подготовительные шаги перед запуском основного контейнера приложения. В отличие от обычных контейнеров, init-контейнеры запускаются, выполняют свою задачу и останавливаются.
Идеально подходят для:
подготовки конфигов;
загрузки секретов;
проверки, доступны ли нужные зависимости;
миграций баз данных.
Init-контейнер обеспечивает запуск приложения в предсказуемой, контролируемой среде, при этом не нужно вносить изменения в код этого приложения.
Паттерн Ambassador
Ambassador-контейнер предоставляет локальные вспомогательные сервисы для пода, которые обеспечивают простой доступ к сетевым сервисам. Обычно ambassador-контейнеры отправляют сетевые запросы от имени контейнера приложения и берут на себя решение таких задач, как обнаружение сервисов (service discovery), проверка подлинности узла (peer identity verification) или шифрование при передаче данных (encryption in transit).
Идеально подходят для:
разгрузки клиентского приложения от забот, связанных с сетевым подключением;
реализации сетевых фич, которые будут работать независимо от языка приложения;
добавления слоёв безопасности вроде TLS;
внедрения надёжных предохранителей (circuit breakers) и механизмов повторных запросов.
Паттерн Configurator
Сайдкар-помощник динамически обновляет настройки приложения. Так у приложения всегда будут свежие параметры, а его работа не прервётся. Зачастую такой помощник отвечает и за начальную настройку, без которой приложение не сможет запуститься.
Сценарии использования:
получение переменных окружения и секретов;
отслеживание изменений в конфигурации;
отделение управления конфигурацией от логики приложения.
Паттерн Adapter
Контейнер типа «Адаптер» (иногда называемый «Фасад») обеспечивает взаимодействие между основным контейнером приложения и внешними сервисами. Это достигается путём перевода форматов данных, протоколов или API из одного вида в другой.
Сильные стороны:
умеет преобразовывать старые форматы данных;
помогает наладить связь между разными протоколами;
упрощает интеграцию несовместимых сервисов.
Подведем итоги
Сайдкары обеспечивают огромную гибкость, но это не палочка-выручалочка на все случаи жизни. Каждый добавленный сайдкар — это усложнение, рост потребляемых ресурсов и, возможно, дополнительная головная боль при эксплуатации. Всегда сначала подумайте, нельзя ли обойтись решением попроще. Главное — использовать сайдкары стратегически: как точные инструменты для конкретных архитектурных проблем, а не как стандартный способ сделать всё. Если применять их правильно, они помогут повысить безопасность, облегчить работу с сетью и управление конфигами в мире контейнеров. Так что выбирайте с умом, внедряйте осторожно, и пусть ваши сайдкары сделают вашу контейнерную экосистему лучше.
P. S.
Читайте также в нашем блоге: