Docker Compose или Kubernetes: что выбрать для одного приложения

Александр Киляков

Время прочтения 17 минут

Если спросить у техдира, что выбрать, Docker Compose или Kubernetes для одного приложения, то он отмахнётся и ответит что-то в духе: «Compose, конечно, проще, Kubernetes сложнее, выбирайте по масштабу приложения» или вовсе «как можно сравнивать инструмент локального развёртывания с платформой оркестрации?». Так-то оно так, но вы в блоге Сервер Молл Cloud — а мы любим копнуть глубже.

Куда интереснее разобрать, в какой момент одно приложение перестаёт быть задачей Docker Compose и становится задачей Kubernetes — и связан ли этот момент с количеством контейнеров? И где вообще граница между небольшим приложением и большим? Пять контейнеров? Десять? Сто? А если приложение собрано из тридцати контейнеров, но спокойно работает на одном сервере? Или наоборот: всего три контейнера, но все распределены по разным серверам?

Количество контейнеров здесь ни о чём не говорит.

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

Вы уже поняли, к чему это приведёт? К изобретению колеса Kubernetes. И тогда станет понятно, когда достаточно Docker Compose, а когда уже нужен Kubernetes.

Глоссарий для понимания статьи: что такое Docker, Kubernetes, контейнеры, поды и т.д.

Первым делом пройдёмся по терминологии. Если вы опытный админ, технарь со стажем, техдир или любой другой спец из касты просвещённых, сразу переходите к следующему разделу статьи (хотя освежить память никогда не помешает).

А мы приступим.

Контейнер — запущенный экземпляр приложения в изолированной среде (контейнер предоставляет ему свою файловую систему, сеть, ресурсы), внутри которой есть всё нужное, включая библиотеки, системные утилиты, настройки и другие зависимости, для запуска и стабильной работы вашей программы на любом компьютере. Главное отличие от виртуальных машин (ВМ) — контейнеры не содержат внутри себя целую операционную систему, а делят ОС хоста (хотя образ может содержать пользовательское пространство — например, Ubuntu/Debian-библиотеки, — но ядро остаётся общим), что позволяет запускать их за доли секунд с минимальным потреблением памяти, CPU и других ресурсов.

Docker — это платформа для упаковки, развёртывания и управления приложениями в изолированных контейнерах. Docker написан на языке Go и доступен как в бесплатной версии с открытым кодом, так и в коммерческих тарифах (например, Docker Pro с функциями отладки и техподдержкой).

Изначально Docker создан для Linux, где он и работает нативно. В Windows и macOS для его запуска используется специальная виртуальная среда (например, WSL 2 в Windows), которая входит в состав приложения Docker Desktop.

Docker Compose — инструмент для описания и запуска многосервисного приложения по одному конфигурационному файлу в формате YAML. Главная фича Compose — возможность управлять несколькими сервисами как единым целым.

YAML-файл (с расширением .yaml или .yml) — это текстовый файл с легкочитаемым форматом данных, основанный на парах «ключ-значение» и отступах из пробелов. Вместо того чтобы вручную вводить длинные команды docker run для каждого контейнера, вы описываете всю архитектуру приложения в одном файле и запускаете её одной командой.

Не путайте YAML-файл с образом (image) — неизменяемым шаблоном приложения. На основе образа создаётся контейнер, в котором запускается приложение определённой версии. Иерархия следующая: сначала вы пишете YAML-файл, далее (в секции image) указываете, какой образ нужно скачать из реестра, а следом команда docker compose up читает ваш YAML-файл, берёт указанный образ и разворачивает из него запущенный контейнер.

Простой пример файла compose.yaml:

    services:
  # Наш сайт (Backend)
  web:
    image: my-python-app:latest
    ports:
      - "80:80"
    depends_on:
      - db # Контейнер web запускается после контейнера db

  # Наша база данных
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: mysecretpassword

Docker Registry (реестр) — публичное или частное хранилище Docker-образов. В него загружают (push) образы, а при развёртывании скачивают (pull) их. В Docker по умолчанию включен Docker Hub — самый популярный в мире публичный реестр, откуда можно скачать официальные образы Linux, Python, Node.js, MySQL и тысячи других программ. Есть и сторонние облачные реестры, вроде Amazon ECR, Google Artifact Registry или Яндекс.Облако (Yandex Container Registry).

Некоторые компании из-за требований безопасности разворачивают реестр образов во внутренней корпоративной сети, чтобы контролировать доступ к ним и не зависеть от внешних реестров.

Kubernetes (часто сокращают как K8s) — это система оркестрации (управления) контейнерными приложениями. Она позволяет разворачивать приложения в кластере серверов, автоматически масштабировать их, распределять нагрузку и обновлять без простоев, а также решать другие задачи. Само приложение можно собрать в Docker, но для работы K8s движок Docker уже не требуется.

Интересные факты! Слово Kubernetes происходит из древнегреческого языка (κυβερνήτης — кубернетис) и означает «рулевой», «пилот» или «капитан корабля». K8s — сокращение (нумероним) слова Kubernetes, где цифра 8 обозначает количество букв, пропущенных между первой буквой k и последней s. Такой способ сокращения длинных слов (по первой и последней буквам с числом букв между) популярен в IT-среде. Известный аналогичный пример — сокращение слова internationalization до i18n.

Если Docker создаёт и запускает одиночные контейнеры, Docker Compose связывает несколько контейнеров на одном компьютере, то Kubernetes управляет огромным пулом приложений в контейнерах на группе серверов (кластере). K8s — мощный, но сложный в освоении инструмент.

Node (нода, или узел) в Kubernetes — это физический или виртуальный сервер, на котором запускаются поды. Узлы объединяют в кластер Kubernetes.

Pod (под) в Kubernetes — наименьшая развёртываемая единица кластера. В одном поде можно разместить один или несколько связанных контейнеров (например, контейнер с кодом сайта и контейнер для сбора логов). В Kubernetes основной объект запуска — Pod, а контейнеры размещаются внутри него — они обязательно делят сетевой namespace и поэтому имеют общий IP-адрес

Deployment (объект развёртывания) в Kubernetes — это не процесс, а описание желаемого состояния приложения (сколько копий подов запускать, какую версию образа, стратегию обновления и т.д.). Deployment задаёт желаемое состояние приложения (Desired state). На его основе Kubernetes создаёт ReplicaSet, а тот поддерживает нужное количество подов.

Ремарка! В Docker Compose вы в основном описываете, что и как запустить. В Kubernetes вы описываете, какое состояние должно поддерживаться — и он сам пытается его сохранить.

Service (сервис) в Kubernetes — абстракция для доступа к группе подов. Никто не вечен поды не вечны, и, например, после пересоздания они получают новые внутренние IP-адреса. Чтобы у других программ или пользователей был стабильный доступ к подам, нужен Service — он знает IP-адреса всех запущенных подов и распределяет (маршрутизирует) между ними трафик. Что-то вроде постоянного единого адреса (точки входа). Service задаёт устойчивый DNS и/или IP, балансирует трафик к актуальным репликам, скрывая детали масштабирования (например, ClusterIP, NodePort или LoadBalancer).

Control Plane (управляющий слой) Kubernetes — это мозг кластера, совокупность системных компонентов Kubernetes, принимающих команды администратора и отвечающих за общее состояние кластера (к примеру, API-сервер, etcd, контроллеры, scheduler). Control Plane решает, на каком именно сервере запустить новый под, собирает информацию о нужном числе подов и обеспечивает эту конфигурацию в кластере.

Итак, мы разобрали фундаментальные термины, которые понадобятся при обсуждении Docker Compose и Kubernetes. Остальное, вроде Volume, Environment variables, ConfigMap и Secret, будем разбирать по ходу статьи.

От простого к сложному — граница между Docker Compose и Kubernetes

Для начала отвечу на фундаментальный вопрос: а подходит ли вообще Docker Compose для продакшена? Да, если у вас минимальные требования к отказоустойчивости и небольшая статичная нагрузка. Многие используют Compose в рабочих задачах для монолитных приложений на одном хосте. Но в Docker Compose нет полноценного встроенного механизма оркестрации, который автоматически поддерживал бы нужное количество реплик и переносил их на другие узлы при отказе сервера. Мониторинг и резервное копирование нужно организовывать отдельно.

Итак, раз для прода подходит, разберём пример.

Предположим, что у нас есть классическое веб-приложение, например, небольшой интернет-магазин (не гигантский маркетплейс с миллионами запросов в секунду, а интернет-магазин среднего бизнеса с нагрузкой в 10–100 запросов в секунду, где пользователи открывают каталог, оформляют заказы, а в фоне идут различные процессы).

Архитектура такого магазина может выглядеть так: пользователь заходит с интернета ➔ его встречает веб-сервер на Nginx (главный входной шлюз, который принимает на себя абсолютно весь внешний трафик и распределяет его дальше по внутренним сервисам) ➔ Nginx передает запрос в бэкенд (серверную часть приложения) ➔ бэкенд общается с базой данных PostgreSQL и быстрым хранилищем Redis, которое используется для кэширования и организации очередей ➔ как только в Redis появляется задача, её забирает Worker (фоновый работяга, может быть отдельным процессом или контейнером) и не спеша выполняет (отправляет email, связывается со службой доставки по API и т.д.).

Ремарка! Пользователя сначала встречает не фронтенд, а, например, Nginx — он берёт с диска сервера файлы фронтенда (HTML/JS/CSS) и отправляет их пользователю. Только после этого браузер отрисовывает картинку. Разумеется, фронтенд можно закинуть в Nginx, а можно поднять для него отдельный контейнер — для нашего примера это непринципиально. Но на практике отдельный контейнер для фронтенда (например, на Node.js/Next.js) поднимают тогда, когда нужен SSR (Server-Side Rendering) — чтобы поисковые роботы Яндекс и Google сразу получали готовый HTML-код магазина для SEO-продвижения.

В итоге получаем пять сервисов: frontend, backend, PostgreSQL, Redis и worker. И всю эту компанию мы селим на один арендованный сервер (VPS/VDS) надёжного облачного провайдера.

Думаю, вы согласитесь, что Docker Compose для этой задачи подходит идеально — описываем сервисы в compose.yaml, создаём внутреннюю сеть, подключаем тома (volumes) для хранения информации базы данных, прописываем пароли и запускаем.

Огромное преимущество Docker Compose в том, что он позволяет описывать зависимости между сервисами и управлять их запуском. Если бы вы запускали всё вручную, вам пришлось бы сначала запустить базу, подождать, пока она прогреется (инициализация, проверка целостности и т.д.), потом запустить Redis, потом бэкенд, и только потом фронтенд. Если запустить бэкенд раньше базы данных (или одновременно), он может завершиться с ошибкой подключения. А Docker Compose считывает все эти зависимости, выстраивает правильную очередь запуска и может автоматически перезапускать сервисы, если они завершаются с ошибкой.

Ремарка! Когда вы начнёте запускать сборку (похожую на нашу) через docker compose up -d, может возникнуть проблема: контейнер с PostgreSQL уже запустился (с точки зрения Docker), но сама СУБД внутри контейнера ещё не успела инициализироваться и начать принимать подключения, а бэкенд уже пытается к ней постучаться и падает с ошибкой. Поскольку контейнеры изолированы друг от друга, они понятия не имеют, что происходит внутри соседа. Чтобы решить эту проблему, в Docker Compose используют depends_on совместно с healthcheck — они позволяют запускать зависимый сервис после того, как база данных пройдёт проверку готовности. Например, бэкенд не начнёт запускаться сразу, а подождет, пока проверка pg_isready не подтвердит, что PostgreSQL готов принимать подключения.

Резервное копирование базы данных можно организовать обычным таймером systemd или отдельным backup-сервисом, чтобы снизить риск человеческой ошибки и выполнять резервное копирование по расписанию.

Можно ли здесь поставить Kubernetes?

Процитирую современного классика: «Можно. А зачем?»

Да, Kubernetes запустит наши контейнеры. Но мы выпустим аналог BMW получим усложнённый способ управлять теми же контейнерами, который ещё и ресурсов потребляет больше (даже легковесный k3s). Docker Compose хорошо подходит для запуска нескольких сервисов на одном VPS. Он выигрывает, потому что вышеописанная задача не требует оркестратора.

Поэтому не надо стрелять из пушки по воробьям. Двигаемся дальше.

Проблема № 1. Интернет-магазин начал расти

Проблема, разумеется, техдира/админа/команды, а не владельца бизнеса 🙂 Итак, допустим, новая команда маркетинга стала нагонять трафик на сайт, запустила масштабную рекламную кампанию у блогеров, объявила распродажу со скидками 70%.

Результат — на сайт одновременно хлынули десятки тысяч покупателей.

Нужно ли техдиру срочно устанавливать Kubernetes?

Всё ещё: «Можно. А зачем?» Если бэкенд не падает и нормально работает, PostgreSQL справляется с нагрузкой без коллапсов базы, Redis и Worker не упираются в память, да и запас CPU и памяти ещё есть, то увеличение аудитории никак не смотивирует техдира начать переход на K8s.

Он может заранее настроить Nginx как балансировщик, запустить рядом ещё пять контейнеров с бэкендом и три воркера, чтобы распределить нагрузку, а для Redis и Postgres настроить репликацию и кэширование. Дополнительно можно увеличить количество VPS/VDS, оптимизировать запросы к базе, вынести статику, поставить CDN, масштабировать отдельные компоненты.

Интернет-магазин на такой архитектуре выдержит огромное количество запросов пользователей.

Ремарка! Если мы упираемся в производительность бэкенда, то действительно можно увеличить число его экземпляров и распределять запросы между ними через Nginx или другой балансировщик. Но тут нужно понимать, что для распределения нагрузки и повышения доступности на нескольких нодах нужны отдельные механизмы обнаружения реплик, маршрутизации и восстановления.

Слишком просто, поэтому подольём ещё масла в огонь!

Проблема № 2. Единая точка отказа

Напомню, что в нашей изначальной архитектуре отказуйстойчивость — это автоматический перезапуск контейнеров и резервное копирование. В общем, отказоустойчивости нет. Очевидно, что если VPS/VDS падает целиком, то и интернет-магазин тоже. Для отказоустойчивости нужно запустить вторую копию приложения, а для этого купить второй VPS/VDS. И тогда у нас будет две копии бэкенда:

  • VPS 1 — backend-1;
  • VPS 2 — backend-2.

Но что, если резервный VPS 2 упадёт (а основной работает)? Кто-то должен заметить проблему, понять, что одна реплика исчезла, сделать новую, решить, где её запустить (купить VPS 3?). Значит, нужен автоматизированный компонент системы, который в реальном времени следит за состоянием всей инфраструктуры и принимает решения о размещении контейнеров.

По сути нам нужен scheduler — планировщик, который сопоставляет требования приложений к ресурсам с доступными ресурсами узлов и выбирает место для запуска пода.

Ещё не Kubernetes, но небольшой шаг в его сторону.

Проблема № 3. Желаемое состояние

Важно, что одного лишь планировщика будет недостаточно. Docker может считать, что запущенный контейнер работает. Но приложение могло потерять соединения с базой данных, зависнуть на обработке запросов или оказаться в состоянии, когда новые подключения уже нельзя принимать — в любом из этих сценариев интернет-магазин работать не будет.

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

В Kubernetes для этого есть механизм readiness probe — он проверяет, готово ли приложение принимать запросы и можно ли направлять на него пользовательский трафик. Readiness probe нужно проектировать исходя из того, способен ли экземпляр приложения обслуживать запросы. Проверка может учитывать доступность критически важных зависимостей, но не должна превращать любой временный сбой внешнего сервиса в причину массового исключения реплик из балансировки.

Напоминание! При деплое новой версии контейнер запускается сразу, но бэкенду нужно время, чтобы подключиться к PostgreSQL и прогреть компоненты. До завершения этой инициализации направлять запросы на под нельзя.

А также liveness probe — он смотрит, не нужно ли перезапустить приложение, например, если процесс завис и больше не может обрабатывать запросы.

Важно! Критические сбои процесса и временная потеря связности с внешними сервисами — не одно и то же. Потеря соединения с PostgreSQL переводит приложение в статус readiness (не готового к приему трафика), но не требует рестарта. Даже каскадный перезапуск подов при недоступности БД не исправит ошибку конфигурации или инфраструктуры, зато приведёт к неконтролируемым перезапускам бэкенда.

И третий механизм — startup probe. Он помогает запускать приложения, которым нужно много времени на инициализацию. Пока проверка запуска не пройдёт успешно, Kubernetes не выполняет обычные liveness и readiness-пробы. Если же startup probe не проходит заданное число попыток, Kubernetes завершит контейнер и сделает перезапуск. Это не бесконечное ожидание готовности.

Итак, распределённая отказоустойчивая система должна различать состояния реплик.

  • backend-1 → готов принимать запросы;
  • backend-2 → запускается;
  • backend-3 → готов принимать запросы.

Вторая реплика (backend-2) временно исключается из обработки трафика. После успешной проверки она снова становится доступной.

Но представим, что мы хотим, чтобы у нас всегда было три работающие копии бэкенда. Когда backend-2 упадёт, инфраструктура должна самостоятельно создать третью реплику и разместить её на подходящем узле.

Это и есть переход к желаемому состоянию (у приложения должно быть три работающих реплики) — система сама отслеживает расхождение между желаемым и фактическим состояниями и пытается устранить его.

Проблема № 4. Обновление приложения без простоя

Допустим, мы всё настроили — и приложение работает стабильно. Но как обновить его без простоя?

От:

  • backend-1 v1;
  • backend-2 v1;
  • backend-3 v1.

Нужно перейти к:

  • backend-1 v2;
  • backend-2 v2;
  • backend-3 v2.

На одном сервере вполне хватит команды docker compose pull && docker compose up -d. Но если у нас интернет-магазин, приложение должно оставаться доступным во время обновления, а значит одновременно останавливать все реплики нельзя. Поэтому обновление нужно выполнять постепенно, заменяя экземпляры по одному:

  • backend-1 v2 → backend-2 v1 → backend-3 v1;
  • backend-1 v2 → backend-2 v2 → backend-3 v1;
  • backend-1 v2 → backend-2 v2 → backend-3 v2.

Сначала запускается новая реплика, затем система проверяет её готовность. Если она успешно принимает запросы, можно убрать одну из старых реплик и заменить следующую. Так постепенно весь backend обновляется на новую версию, а сервис продолжает работу — это называется rolling update (поэтапное обновление).

В Kubernetes этот механизм доступен из коробки. Он запускает новые контейнеры с новой версией кода, проверяет их здоровье (тот самый healthcheck), и только после этого плавно гасит старые с Zero Downtime (нулевым простоем). Пользователи даже не заметят, что на сайте обновился бэкенд. Но учтите, что стратегия rolling update не гарантирует нулевые простои.

Проблема № 5. Откат обновлений

Как по мне, масла ещё маловато, поэтому представим, что версия backend v2 содержит критическую ошибку. Первая новая реплика вроде бы запускается и работает без сбоев, но через время начинает падать. Это значит, что обновление нужно срочно остановить, а уже обновлённые экземпляры восстановить до предыдущей версии.

Это дополнительное усложнение — IT-инфраструктура должна не просто раскатить и запустить новую версию, а управлять процессом изменения состояния приложения, отслеживать его результат и при необходимости выполнять откат.

ВАЖНО! Откат контейнеров не то же самое, что и откат всей системы. Если новая версия приложения изменила схему или данные базы, предыдущая версия уже может быть несовместима с ними. Поэтому миграции БД нужно проектировать с учётом последовательного обновления и возможного отката: например, сначала добавлять новые поля, сохранять обратную совместимость, а удалять старые только после завершения перехода.

Подытог: Docker Compose или Kubernetes

Пока приложение помещается на одном сервере и его отказ с задержками на восстановление допустим, то K8s не нужен — достаточно Docker Compose. Если у вас два-три сервиса и небольшая команда, то Docker Compose на мощном VPS с ежедневными бэкапами и мониторингом, вероятно, тоже подойдёт.

Но если нам нужна система, которая одновременно следит за состоянием нескольких узлов, распределяет нагрузки, поддерживает нужное количество реплик, проверяет готовность приложений, управляет трафиком и выполняет контролируемые (предсказуемые) обновления и автоматические восстановления без простоев, то уже нужен Kubernetes либо другая система для решения задач оркестрации.

Например, оркестрация нужна, если интернет-магазин из нашего примера не должен падать, даже когда у хостинг-провайдера сгорит целая стойка с серверами, а обновления бэкенда или каталога должны проходить фоном (незаметно для покупателей даже в пик распродаж). Здесь Kubernetes в частности и оркестрация в целом окупают свою сложность.

Суть оркестрации не в размере приложения, а в топологии инфраструктуры и требованиях к SLA (Service Level Agreement или Соглашение об уровне услуг). Главная мысль для DevOps: выбор инструмента зависит от требований бизнеса к доступности и надёжности. И не забываем квалификацию команды.

КритерийDocker ComposeKubernetes (K8s)
Основное назначениеЛокальная разработка, тестирование и запуск простых монолитных или небольших приложений на одном узле.Оркестрация, обеспечение высокой доступности и масштабирование микросервисов на кластере серверов.
Управление отказамиЕсли падает сам сервер (хост), падают и все контейнеры. Автоматического переноса на другую машину нет.Автоматически перезапускает упавшие контейнеры и переносит их на живые узлы кластера при отказе железа. Но результат зависит от типа контроллера, состояния кластера, доступных ресурсов, сетевой инфраструктуры и хранилища. Контейнер с данными или приложением, привязанным к конкретному узлу, не всегда получается просто запустить в другом месте.
ОбновленияПри обновлении сервиса часто требуется кратковременная остановка контейнера.Поэтапные обновления (Rolling updates) и стратегии вроде Canary/Blue-Green без прерывания обслуживания пользователей.
Балансировка трафикаТребует ручной настройки внешнего прокси (например, Nginx/Traefik Proxy) для распределения запросов.Service обеспечивает доступ к репликам и распределяет трафик между ними. Ingress описывает правила внешнего HTTP(S)-доступа при наличии соответствующего контроллера.
Порог входа и поддержкаНизкий. Конфигурация описывается в одном простом YAML-файле, администрирование минимально.Высокий. Требует глубоких знаний сетевой архитектуры и безопасности, а также регулярного администрирования кластера.

Даже Kubernetes не гарантирует полной отказоустойчивости:

Помимо сложности может показаться, что K8s околобезупречная система для автоматической отказоустойчивости IT-инфраструктуры. Если один сервер выйдет из строя, K8s запустит приложение на другом в кластере. Если нагрузка вырастет, можно увеличить число экземпляров.

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

  • База данных. Если приложение использует PostgreSQL или другую СУБД, перезапуск её контейнера не гарантирует сохранность и доступность данных. Для этого нужны отдельные механизмы резервного копирования и, если требуется высокая доступность (High Availability или HA), репликации базы данных. Kubernetes не делает это автоматически.
  • Хранение данных. Постоянный том (PersistentVolume или PV) позволяет сохранить данные при пересоздании пода, но сам по себе не защищает от отказа накопителя, повреждения данных или сбоя системы хранения. Надёжность зависит от архитектуры хранилища и организации резервного копирования. Резервные копии нужно регулярно проверять, в том числе тестовым восстановлением данных. Рекомендуется, конечно, не использовать PV, а использовать отказоустойчивые БД и распределенные объектные хранилища S3.
  • Сеть и доступность. Kubernetes может направлять запросы к готовым к обслуживанию репликам приложения, но для внешнего доступа иногда нужна дополнительная инфраструктура: балансировщик нагрузки, сетевые компоненты и резервирование точек входа. Если один из этих элементов станет единой точкой отказа (и откажет), сервис будет недоступен.
  • Размещение экземпляров. Несколько копий приложения не гарантируют работу приложения при отказе сервера. Если все поды разместить на одном узле, то результат при отказе очевиден. Поэтому нужно планировать распределение реплик, доступность других узлов и запас ресурсов для восстановления после сбоя.
  • Свободные ресурсы. Чтобы перенести приложение на другой узел или запустить дополнительные экземпляры, кластеру нужны свободные вычислительные ресурсы. Если все серверы загружены под 100%, то у K8s не будет места для новых подов. Резерв мощности — это всегда дополнительные затраты, но без него возможности восстановления K8s стремятся к нулю.
  • Управляющие компоненты. Kubernetes сильно зависит от рабочих узлов, но и управляющий кластером слой (Control Plane) архиважен — чтобы реализовать высокую доступность (HA), каждый критически важный компонент нужно резервировать с учётом его роли и требований к отказоустойчивости.

Главная мысль для DevOps: Kubernetes автоматизирует восстановление приложений в пределах настроенной инфраструктуры, но не заменяет проектирование отказоустойчивости. Нужно продумывать репликацию баз данных, резервное копирование с тестами, надёжное хранилище, распределение нагрузки и запас ресурсов отдельно от K8s.

Вместо выводов

Можно ли использовать Docker без Kubernetes? Да. Docker и Docker Compose можно использовать независимо от Kubernetes. Вы можете развернуть приложение на одном или нескольких серверах с помощью Docker Compose или Docker Swarm, не используя Kubernetes. Compose отлично подходит для небольших проектов, особенно для локальной разработки и развёртывания в продакшене.

Может ли кластер Kubernetes состоять из одного узла? Технически — да (например, все компоненты Control Plane и один Worker на одной ВМ). Но при таком варианте не будет преимуществ отказоустойчивости и горизонтального масштабирования. По сути, это Compose на Kubernetes. Поэтому нужен хотя бы второй узел (а лучше ещё третий для HA).

Сделает ли Kubernetes приложение быстрее? Нет. Kubernetes — не бустит производительность одного экземпляра приложения. Скорость обработки запросов зависит от самого приложения, конфигурации контейнера и доступных ресурсов. Kubernetes даёт автоматическое масштабирование (при наличии ресурсов), но контейнеры в нём не работают быстрее, чем на Docker Compose.

Kubernetes умеет восстанавливать желаемое состояние инфраструктуры, но не знает, какое состояние нужно бизнесу. Он может пересоздать под, запустить три реплики и направить к ним трафик. Но он не гарантирует, что запрос не обработается дважды, база данных будет доступна, а новая версия приложения будет совместимой со старыми данными. Это уже задача проектирования самого приложения и всей системы.

Каждый проект уникален. Если требования к доступности невысоки и команда маленькая — может хватить Compose. Если же нужны высокая доступность, независимые развёртывания и гибкое масштабирование — стоит смотреть в сторону Kubernetes, при этом учитывая затраты на поддержку (или взять Managed Kubernetes у провайдера).

Подпишитесь на нашу рассылку и получайте статьи и новости

    Ознакомьтесь с другими нашими материалами