5 років на Docker Swarm: чому ми досі не на Kubernetes

💡 Усі статті, обговорення, новини про DevOps — в одному місці. Приєднуйтесь до DevOps спільноти!

Привіт, я — Павло, CTO Adheart. Майже 5 років і до сьогодні наш прод крутиться на Docker Swarm, хоч це і звучить як певне «guilty pleasure». Ця стаття — не рекомендація щодо того, «чи варто тобі стартувати новий проєкт на Swarm», і не антагонізм «ви всі дарма в Kubernetes», а мій власний постмортем за цей період.

2026: чи живий Docker Swarm?

Перше враження — що тільки в мемах та документації. Втім існує немало маленьких та середніх продакшнів, які досі на Swarm, серед яких і ми, які просто не кричать про це, бо трохи соромно. Swarm досі залишається робочою конячкою для тих, кому k8s ще кусючий, а хмарна оркестрація — надто золота. Напиши коментар, якщо ваш проєкт також ще досі на свормі :)

Крива входу в цю технологію набагато нижча, ніж в k8s. Якщо ти здатний описати докерфайл і звʼязати пару сервісів між собою в docker compose — можна сказати, що ти вже знаєш Swarm. Купуємо декілька дешевих VPS — і наш проєкт виїжджає в продакшн.

Чому ми обрали Swarm і як виросли в ньому

Власне, такою і була мотивація нашого вибору. Ми прийняли від «попередників» проєкт з шаленим техборгом по всіх напрямах. Не існувало не те, що контейнерізації, навіть git не використовувався — це багато про що говорить. Наша команда на той момент складалась всього з двох людей, тому потрібно було швидко ліквідувати цей розрив. Swarm в такій ситуації став оптимальним вибором.

Нині ми доросли до кластера Swarm з 15 нод (3 менеджера + 12 воркерів), які крутять під собою 2000+ контейнерів, маємо солідні ворклоади у воркерах (нам потрібно збирати більше 100 тисяч реклами з фейсбук за годину), blue/green деплой, повний моніторинг всього кластера, логи — і це все ще у Swarm.

Swarm на стероїдах vs Kubernetes

З коробки Swarm дає лише базовий інструментарій, якого вистачить на пів року чи рік, залежно від росту інженерного рівня твоєї команди. Якщо проєкт вийшов в продакшн або ліквідували базовий техборг, як в нашому випадку — то апетити зростають, і базовий набір функцій їх не задовольнить. Це не проблема, оскільки навколо Docker Swarm також існує розвинена екосистема.

Ingress і роутинг

Swarm має тільки базовий routing mesh. Можна підняти port-forwading, можна прикрутити зверху над цим HAProxy чи інший балансер — і таким чином зшити кластер та отримати high-availability. Навіть для старту це відверто недостатнє рішення, тому ми відразу стартувати з Traefik.

Traefik це реверс-проксі/контролер трафіку, який чудово інтегрується зі Swarm:

  • Надає можливість service-discovery через service labels.
  • Маршрутизує як HTTP, так і TCP-трафік (в нас чудово живе в кластері redis, rabbit, kafka).
  • Проста робота з сертифікатами, https, let’s encrypt, яка знімає весь головний біль.
  • blue/green та canary-deployments, не у два кліки, але цілком можливо.

Фактично це повноцінний Ingress з k8s-світу. І до речі, найбезпроблемніший компонент в межах нашого кластера — за 5 років саме з траефіком ми не отримали жодних проблем. Він успішно тримав DDOS-атаки в десятки тисяч RPS, тим більше — стабільний аптайм прода.

CI/CD та deployments

docker stack deploy — це, звісно, непогано для старту, але в реальному проєкті дуже швидко приходиш до потреби побудови CI/CD-процесу. Достатньо поширених рішень тут не так багато. Але коштом простоти Swarm нескладно зібрати свій велосипед, який відкатає 5 років без капремонту.

Ми використовуємо Github actions та Portainer — тому таким велосипедом для нас став власний portainer-deploy-action, який використовує API-портейнер, деплоїть стеки через нього, і дає легкий менеджмент через UI далі.

З реальних проблем тут: розвиток Portainer йде в першу чергу в бік k8s. Для Swarm нових фіч вже навряд чи хтось завезе, а старі баги не факт, що пофіксять. А вони є. Інколи портейнер втрачає звʼязок зі своїми агентами на нодах, через що менеджмент кластера зводиться до старої доброї консолі, а деплої відкладаються на декілька хвилин, а інколи й годин.

Configs / Secrets

Ми ж усі погодились, що сікрети в git — погана ідея, правда? Але у Swarm їх менеджмент непростий і незручний. І сікрети, і конфіги — імутабельні, тобто оновити конфіг можна тільки через створення нового, а видалити старий, поки він використовується, звісно, не можна. Що й призводить до появи my_config_version_100500, оскільки іншого шляху тут і не дають.

Або шукати шляхи спрощення, або городити чудернацькі пайплайни (хоча якщо твоя команда на Swarm, то й інженера, який майстерно це може зробити, ймовірно, немає). Тож ми пішли на компроміс, тримаючи конфіги та сікрети в Github, а в стеки передаючи просто як значення. Не ідеально безпечно, але краще, ніж нічого.

Stateful services / persistent volumes

Коли у вашому кластері починають зʼявлятись сервіси зі стейтом, ти дізнаєшся про те, що Swarm не дає інструментів для розподілених сховищ з коробки. Вихід — або прибивати цвяхами сервіс до якоїсь ноди і забувати про high-availability, або використовувати сторонні розподілені файлові системи, або плагіни.

Ceph — складно, NFS — дуже обмежено. Нам потрібна була з одного боку проста, з іншого — повноцінна файлова система, якою став для нас GlusterFS. Звісно, що не треба реплікувати всі волюми, достатньо виділити якийсь синхронізований простір для сервісів, які потребують розподілених. Ми пропрацювали з GlusterFS близько двох років, без істотних проблем, але з часом все ж прийшли до того, що краще у Swarm тримати тільки stateless-сервіси.

Темна сторона Docker Swarm — реальні проблеми за 5 років

Overlay networks — сім кіл пекла

Коли тільки стартуєш кластер, мало замислюєшся про CIDR, MTU чи розмір мереж. Docker Swarm — це легкий старт, памʼятаємо ж? Який приносить страждання, коли ворклоад кластера перевалює за сотні реплік, які активно комунікують між собою внутрішніми мережами.

І проблема навіть не з самим концептом overlay-мережі як такої, вона використовується і в k8s, і загалом проста, проте робоча технологія. Проблема в менеджменті цих мереж, про що знову ж, не замислюєшся одразу.

Більша мережа — більші проблеми

За замовчуванням Docker видає /24 підмережі для overlay, що дозволяє запускати десь до 240-250 реплік в одній мережі. Цей параметр можна і треба збільшувати, якщо відразу плануєте мати більше реплік, але треба підходити до цього з холодним розрахунком.

В той день, коли один з наших сервісів став потребувати більше реплік, назрів чудовий, здавалось, план: створюємо вручну /16 overlay-мережу, щоб точно вистачило на роки вперед, аттачимо сервіс до неї і маємо щастя... на роки вперед в цій схемі вистачило тільки проблем.

Менеджери Swarm-кластера (а їх для продакшна потрібно мінімум три для консенсусу) постійно тримають таблиці відповідності IP <-> container і синхронізують їх між собою та воркер-нодами. Поки таблиці невеликі, це не складає проблеми, але коли у вас /16 мережа, в якій за весь час вже стартували і відпрацювали тисячі контейнерів, її синхронізація стає накладною. А при відсутності синхронізації починаються мережеві збої: нода1 думає, що контейнер Х в ноді2, хоча фактично він в ноді3, або менеджер взагалі не може заасайнити контейнер на якусь ноду, бо знає, що він не знає стан мережі.

Найпоширеніший приклад: Traefik намагається запроксювати запит на якийсь бекенд, не може отримати від нього відповідь — timeout, 502, і незадовольні клієнти.

Як ми намагались обійти ці проблеми

Повноцінної відповіді на питання «як уникнути проблем з мережами» в мене нема. Всі наші 5 років зі Swarm пройшли в ключі «ура, ми вирішили проблеми з мережами. Через дні, тижні чи місяці знову проблеми». Але якщо їх і можна побороти остаточно — то тільки жорстким, спланованим менеджментом:

  • Не підіймати дефолтний розмір мережі без причини (240 вузлів достатньо для більшості сервісів).
  • Створювати вручну мережі для великих сервісів з чітким усвідомленням їх розміру. Не набирати вузлів на перспективу років. Перестворити мережу навіть в проді не є величезною проблемою.
  • Контролювати, в яких мережах знаходиться кожен сервіс, уникати комбінацій, де сервіси можуть комунікувати у двох і більше мережах одночасно.
  • Ретельно моніторити NetworkDB stats і вчасно реагувати на потенційні проблеми. Якщо запустити проблему синхронізації — часто простіше перестворити мережу.

Планувальник задач

Ще одна проблема, яка істотно потріпала нам нерви — це планувальник задач. Для Docker swarm нема нічого простішого, ніж закинути ще пару контейнерів на ноду, яка вже ледве дихає, або навпаки дати відпочинок комусь, поки інші працюють. Типовий сценарій: перевантажується одна з нод, перестає навіть відповідати менеджеру, в якийсь момент він прибирає з неї всі задачі й розкидає так само нерівномірно на інші ноди, викликаючи ефект снігового кому.

Що варто винести з цього:

  • Планувальник не ідеальний, і краще вже не стане — потрібно думати за нього.
  • Reservations не менш, а може, навіть більш важливі, ніж limits. Дивлячись на reservations, планувальник з меншою ймовірністю поставить задачу на ноду, яка вже й так задихається.
  • Оптимізація сервісів по CPU/RAM. На етапі прототипування при роботі з великими обʼємами даних багато проблем вирішується на рівні «дати більше памʼяті», але коли сервіс на всі репліки починає віджирати сотні гігабайт — потрібно взяти час на оптимізацію.

Тулінг та екосистема

Як би ми не намагались зробити зі Swarm k8s — це коштує зусиль, часу на ресерч і розробку. Ми створили десятки кастомних екшенів для github, python/bash скриптів для менеджменту кластера, написали інструкції «як поводитись черговому в разі...» — але кубернетесом від того він так і не став.

До того ж частину проблем ми так і не вирішили:

  • Зручний менеджмент конфігів та стеків.
  • Шаблонізація стеків.
  • Observability самого кластера.

А окремий пласт проблеми — людський. 1-2 людини в команді достеменно розуміють, як працює той кластер (попри всю легкість Docker Swarm, з якої ми починали). Ще 3-4 вміють щось подивитись/поміняти в портейнері. Для решти це «я комітнув, воно кудись задеплоїлось (або ні)». Звісно, сам по собі Kubernetes це питання не вирішує, але ж стандартизація тулінга і підходів в ньому незрівнянно вища — потреба вигадувати велосипеди, відповідно, менша.

Ми рухаємось до Kubernetes

Час переходити до логічного фіналу: ми переходимо в k8s. Якщо бути чесним, ми б могли ще довго жити зі Swarm, адже:

  • Навчились деплоїти в нього тисячі контейнерів.
  • Обросли кастомним просунутим тулінгом для canary deployments, auto-scaling.
  • Ефективно покрили ворклоад в кластері логами і метриками.
  • Навчились розуміти, де і як ламається кластер, як швидко ремонтувати його, або взагалі обходити збій.
  • Достеменно розібрались з overlay-мережами (хоч і не знайшли фінальний рецепт щастя, ймовірно).

Тож причина переїзду не в тому, що «Swarm категорично не підходить». Скоріше ми просто доросли, щоб спробувати інший технологічний рівень: номінально складніший, але більш документований, освітлений чужим досвідом та з більш розвиненою екосистемою. Там, де ми платимо годинами і днями часу на розробку кастомного рішення, в Kubernetes є великий шанс за хвилини встановити і користуватись готовим інструментом. Іноді треба міняти не тільки масло в машині, а й саму машину.

Що я виніс із цих п’яти років на Swarm

  1. Swarm був доречним для свого часу. Він дозволив нам легко ліквідувати величезний техборг і дозволити зростати далі.
  2. Простота — кредит. Спочатку ти радієш, що немає зайвої складності, потім починаєш породжувати ще більшу складність.
  3. Технологія обирається під ресурси. На старті проєкту вдвох з партнером ми і не мріяли про складні технології, але коли команда вже кратно виросла — цілком можемо собі їх дозволити.
  4. Обирати середній горизонт планування. У Swarm не треба планувати «на роки», але й діяти виключно задля вирішення сьогоднішніх проблем — не можна.
  5. Треба вчасно зрозуміти, що виріс зі старого одягу. Swarm відпрацював своє, дав нам цінний досвід, але час іти далі.

Я дуже вдячний, читачу, що ти дійшов аж до кінця цієї статті. Сподіваюсь, цей досвід буде корисним для тебе. Я свідомо намагався уникати в ній прямих глобальних порад на кшталт «обирай або не обирай Swarm». Натомість дав ілюстрацію досвіду нашої команди, наших проблем, і кілька практичних порад з їх вирішення. Бажаю тобі не зіштовхнутися з ними, а якщо в тебе залишились запитання — ласкаво прошу в коментарі до обговорення.

Сподобалась стаття? Підписуйтесь на автора, щоб отримувати сповіщення про нові публікації на пошту.

👍ПодобаєтьсяСподобалось17
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Працюю на open source проекті, 8 років на docker swarm, ми робимо готовий продукт, що використовується в 10-х країн, в державному секторі — OpenCRVS.

Майже рік рухаємося в бік k8s, маємо робочий варіант який використовує одна з країн. Міграція дається важко:
— переробили docker compose на helm chart
— swarm на k8s
— переробили інсталятор
— managed на self hosted runners
— правила збору логів filebeat
— Через потребу зворотної сумісності доводиться на кілька років приймати компроміси і використовувати власні helm chart для баз даних і моніторингу.
— ми досі залежні від traefik, не можемо його замінити на istio, чи інший варіант ingress controller.

Мігруємо не тому що swarm поганий, а для того щоб розширити свою присутність на ринку. Нажаль з swarm, ми не можемо розгорнути свій продукт на aws, google cloud як cloud native, k8s це дозволяє зробити. В нашому випадку міграція на k8s диктується ринком.

Сидел я какое-то время на сварме, оно простое но с кучей проблем, которые решает кубер. Наймите нормального девопса он сварм выкинет и запилит нормальный кластер с CI / ArgoCD и тд после этого будет небо и земля. Для простых проектов swarm ok, когда поднимается вопрос отказоустойчивости, мастштабируемости тут кубер во всем переигрывает докер, но ценой сложности, если просто надо уметь правильно готовить

Цікаво, чи був у вас момент коли дивились у бік Dokploy, або з самого початку орієнтувались на Kubernetes?
Те, що ви витягнули Swarm до такого масштабу, виглядає реально геройством :)
Для невеликої команди це мабуть ок, але з ростом починає лізти вся класика — доступи, volumes, людський фактор (навіть якщо є бекапи).
До речі, а для менеджменту серверів у вас Proxmox?

Дякую за коментар і цікаві референси. Не використовуємо жодного з цих інструментів. Dokploy навіть не чув раніше, зараз подивився — здається цікавою технологією для тих, хто деплоїть багато сервісів одночасно. У нас — моноліт, періодично робимо мікросервіси навкого, але там є шаблони під CI/CD то не відчуваємо сильних проблем

Proxmox — також не використовуємо, менеджимо залізо напряму з Ansible+semaphore.

Сам kubernetes досить нескладний. Проблеми починаються коли обмазуюються всякими Istio/Prometheus/Grafana/OpenTelemetry/ArgoCD/Keycloak/DevSecOps/RBAC/вставити назву технології. Нагадує відому цитату про об’єктно-орієнтоване програмування: «Ви хотіли банан, а отримали горилу з бананом і всі джунглі в комплекті»

Ну, ця інфраструктура вам потрібна в цілому хоч при наявності, хоч при відсутності k8s, я маю на увазі графану, метрики, логи, деплой

в чем трудность с

Prometheus/Grafana/OpenTelemetry/ArgoCD

? Эти вещи просто дефакто в сервисах должны быть по-умолчанию. Достаточно тупо экспортнуть метрики, а кубер уже сам умеет забирать метрики с пода или сервиса

Цікаво слухати коменти адептів з церкви Кубернетису...

стаття цікава, але, на жаль, порівнювать swarm і k8s недоцільно. Порівнювати з k3s ще більш -меньш можливе. Swarm вакжк спримайти як повноцінний оркестратор контейнерів, оскільки йому бракує нормального забезпечення в базових сервісах.
Цікаво буде почитати ваш досвід переходу в K8s:
— а саме що ви виберете як Ci/CD.
— як буде забезпечена IaC і GitOps.
— ну і скільки часу займей міграція, затягнете на роки чи вкладетесь в декілька місяців.

Наскільки я знаю, k3s рішуче не рекомендують використовувати в продакшені. На відміну від сворма, ну зараз його вже й не рекомендують, але в свій час це було прод рішення.

Стосовно міграції в кубер — життя вносить свої корективи як завжди. Я очікував що на момент виходу статті ми вже будемо в k8s, але я помилявся :D

Я доєднуюсь. Дуже буду чекати на сіквел: «k8s після 5-ти років на swarm»

Дякую за статтю, цікаво було почитати. Чекаю на наступну статтю про досвід міграції на k8s.

Який жах — 5 років використовувати docker swarm. 15-ти нодовий «кластер». Купа часу і ресурсів викинута у сміття. Дуже нагадує анекдот про їжачків.

Ніде не казав про жах, їжачків і викинуту у сміття купу ресурсів

Але прочиташи цю статтю і маючи розуміння технологій за останні +/- 10 років саме такий висновок і приходить. P.S. Але Ви праві — про їжачкив Ви нічого не писали. :)

Підписатись на коментарі