Docker Compose v3, Swarm и Kubernetes: что выбрать для небольшого проекта
Docker Compose v3 поддерживает deploy-секции для Swarm и K8s одновременно. Разбираем с клиентом: это удобно, но не отменяет вопрос о том, куда вообще идти.
Docker Compose v3 поддерживает deploy-секции одновременно для Docker Swarm и Kubernetes, позволяя описывать оркестрацию в одном файле
На прошлой неделе сидели с клиентом и обсуждали довольно стандартный вопрос: есть небольшой проект, три-четыре сервиса, нужен оркестратор - что брать, Swarm или Kubernetes? Вопрос этот не новый, но Docker Compose v3 добавил к нему новое измерение.
Суть в том, что Compose v3 теперь понимает секцию deploy - и в зависимости от того, чем ты разворачиваешь файл, эта секция работает по-разному. docker stack deploy читает её для Swarm, а Kompose или нативная поддержка в Docker Desktop for Mac/Windows - для Kubernetes. Один файл, два рантайма.
version: "3.7"
services:
api:
image: registry.example.com/api:latest
deploy:
replicas: 2
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
ports:
- "8080:8080"
db:
image: postgres:10
deploy:
placement:
constraints:
- node.role == manager
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
Выглядит заманчиво: можно стартануть на Swarm - он проще поднимается, меньше движущихся частей - а потом переехать на Kubernetes. Клиент именно так и рассуждал: «Давайте сначала попробуем на Swarm, потом мигрируем».
Почему это не совсем так работает
Проблема в том, что секция deploy не является полным отображением возможностей ни одной из платформ. Для Swarm она описывает примерно 70-80% того, что нужно для реального деплоя. Для Kubernetes при конвертации через Kompose получается базовый Deployment без Ingress, без ConfigMap, без нормального управления секретами и без половины политик. Это отправная точка, а не готовый манифест.
То есть сценарий «написал один Compose-файл, потом одной командой переехал на K8s» работает ровно до тех пор, пока проект настолько прост, что ему, строго говоря, и оркестратор особо не нужен.
Как только появляется что-то нетривиальное - тонкая настройка healthcheck, canary-деплой, ресурсные лимиты по namespace, network policies - начинается ручная работа с нативными манифестами. И тогда оказывается, что ты потратил время на Swarm-конфигурацию, которую всё равно придётся выбросить.
Swarm не плохой инструмент. Он отлично подходит для небольших команд, где не хочется тратить время на изучение K8s-абстракций, и где достаточно базовой оркестрации. Если проект - это два-три сервиса без сложных требований к сети и хранилищу, Swarm закроет задачу с меньшими накладными расходами.
Но если проект будет расти - а клиент обычно именно так и отвечает на вопрос «планируете масштабироваться?» - то Swarm становится промежуточной остановкой, а не решением. Ты всё равно придёшь к Kubernetes, просто с задержкой и с дополнительной миграцией.
Мы в итоге рекомендовали клиенту сразу смотреть на K8s. Не потому что это модно, а потому что экосистема вокруг него - Helm, нативный мониторинг через Prometheus с операторами, нормальная RBAC-модель, Auto DevOps в GitLab - даёт практические вещи, которых в Swarm нет или они реализованы хуже. А managed-инфраструктура снимает боль первоначального поднятия кластера - именно то, чем Swarm обычно привлекает.
Что реально полезного дал Compose v3
Вернёмся к тому, что полезного в самом формате. Главное - это возможность держать описание сервиса в одном месте для dev и prod окружений. В docker-compose.override.yml для локальной разработки маунтишь исходники, в основном файле описываешь production-конфигурацию с репликами и ограничениями.
# docker-compose.override.yml - только для локальной разработки
version: "3.7"
services:
api:
build: .
volumes:
- .:/app
environment:
- DEBUG=true
Это реально удобно и не зависит от того, что ты выберешь в продакшне. Dev-окружение через Compose, прод - Swarm или K8s по выбору. Формат файла унифицирован, и разработчикам не надо знать про манифесты Kubernetes, чтобы запустить проект локально.
Другой момент - secrets и configs как first-class citizens в v3. В Swarm это работает напрямую, в Kubernetes конвертируется в Secret/ConfigMap. Концептуально правильно описывать это на уровне сервиса, а не разбросанными env-переменными.
Короткий итог
Docker Compose v3 как формат для описания сервисов - хорошая идея. Как аргумент «давайте стартуем на Swarm и потом переедем» - слабоватый, потому что реальная миграция всё равно требует переписывать конфиги под платформу. Если горизонт у проекта больше полугода и команда не совсем маленькая - K8s с самого начала экономит время в перспективе.
Swarm при этом никуда не делся и продолжает работать там, где и должен - на простых сценариях без больших амбиций по росту.