Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Як виконати rolling update у Docker Swarm?». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`docker service update --image`** тригерить rolling update. Налаштуй parallelism, delay і failure-action через `--update-*` флаги або `update_config` у stack-файлі. ```bash docker service update \ --image myorg/api:1.1 \ --update-parallelism 1 \ --update-delay 10s \ --update-failure-action rollback \ --update-monitor 30s \ api ``` **Головне:** Swarm замінює task по одному (або N) за раз. Health-checks gate прогрес; failure може auto-rollback. Постав `update-order start-first`, щоб піднімати новий task перед знесенням старого (справжній zero-downtime, якщо застосунок підтримує).Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Rolling-update у Docker Swarm** замінює running-task по batch за раз, чекаючи health між batch. Вбудований механізм Swarm реально хороший у цьому, з auto-rollback на failure як first-class фічею. ## Теорія ### TL;DR - `docker service update` з `--image` тригер. Swarm замінює task за політикою `update_config`. - **Ключові параметри:** parallelism (скільки за раз), delay (між batch), monitor (як довго стежити за кожним), failure-action (continue/pause/rollback). - **Порядок:** `stop-first` (дефолт, короткий gap per task) або `start-first` (zero-downtime, якщо застосунок підтримує паралельні старий/новий). - **Rollback** одна команда (`docker service rollback`) або автоматично на failure. - Healthcheck на сервісі це те, що робить «failure» виявленим. Без нього Swarm вважає started=healthy. ### Update-flow ``` Сервіси: 6 реплік api:1.0 --update-parallelism=2 --update-delay=30s t=0: [v1.0 v1.0 v1.0 v1.0 v1.0 v1.0] випуск update t=0: [STOP STOP v1.0 v1.0 v1.0 v1.0] stop 2 (або start-first: додатковий v1.1 spawn) t=5: [v1.1 v1.1 v1.0 v1.0 v1.0 v1.0] 2 нових task healthy t=35: [v1.1 v1.1 STOP STOP v1.0 v1.0] delay+30s, наступний batch t=40: [v1.1 v1.1 v1.1 v1.1 v1.0 v1.0] t=70: [v1.1 v1.1 v1.1 v1.1 v1.1 v1.1] готово ``` Під час update трафік продовжує йти на ті репліки, що healthy. ### Імперативна форма (CLI) ```bash docker service update \ --image myorg/api:1.1 \ --update-parallelism 1 \ --update-delay 30s \ --update-monitor 30s \ --update-failure-action rollback \ --update-max-failure-ratio 0.2 \ --update-order start-first \ api ``` Що робить кожен флаг: - `--update-parallelism N` — замінити N task за раз (дефолт 1). - `--update-delay 30s` — чекати між batch. - `--update-monitor 30s` — стежити за кожним batch на failure стільки. - `--update-failure-action <continue|pause|rollback>` — що робити на failure. - `--update-max-failure-ratio 0.2` — щонайбільше 20% task можуть впасти перед тригером action. - `--update-order <stop-first|start-first>` — заміна через stop спочатку або start нового спочатку. ### Декларативна форма (stack-файл) ```yaml version: '3.9' services: api: image: myorg/api:1.0 deploy: replicas: 6 update_config: parallelism: 1 delay: 30s order: start-first failure_action: rollback monitor: 30s max_failure_ratio: 0.2 rollback_config: parallelism: 2 delay: 5s failure_action: pause ``` ```bash docker stack deploy -c stack.yaml mystack # Редагуй image на 1.1, redeploy → тригерить rolling update з config вище. ``` Stack-файл це канонічне місце, version-controlled, reviewable. ### Health-driven gating Swarm вирішує «чи цей batch healthy?» через: 1. Container стартонув успішно (без exit під час monitor-періоду). 2. Якщо `healthcheck` визначено, container `healthy`. 3. Не більше ніж `max_failure_ratio` failures у batch. Без healthcheck Swarm знає лише «процес стартонув». Застосунок, що стартує, але одразу misbehaving, ще рахується як «healthy» для Swarm. Healthcheck критичні для безпечного rolling-update. ### Rollback ```bash # Ручний rollback у будь-який час docker service rollback api # Повертає до попереднього image-tag ``` Або через `failure_action: rollback` Swarm rollback'ить автоматично, коли failure-ratio перевищено. У комбінації з `monitor` отримуєш «якщо 1 з 5 у новому batch unhealthy після 30 секунд, roll back усього сервісу» семантику. ### `start-first` vs `stop-first` ```yaml order: stop-first # дефолт — невеликий gap per task order: start-first # підняти новий поряд зі старим, тоді drain старий ``` `start-first` шлях до справжнього zero-downtime, але потребує застосунку, що толерує короткий overlap (дві версії крутяться разом). Для stateless web/API нормально. Для workers зі строгою singleton-семантикою може потребувати code-зміни. ### Типові помилки **Update без healthcheck** ```yaml services: api: image: myorg/api # БЕЗ healthcheck → Swarm не може виявити погані версії ``` Без healthcheck зламаний новий image rolls out на усі репліки до того, як failure стане видимим. Додай `healthcheck:`, щоб Swarm gate'нути прогрес на реальний app-readiness. **Поставити parallelism надто високим** ```yaml update_config: parallelism: 5 # усі 6 реплік одразу ``` Під час короткого replacement-вікна у тебе дуже мало healthy task. Сплеск load = накопичення. Нижчий parallelism = безпечніше. **Забути rollback_config** Rollback використовує свій окремий блок конфігурації. Якщо ставиш лише `update_config`, rollback бере дефолти (часто повільніший, ніж хочеш). Визнач `rollback_config` явно. **Image-tag все ще `latest` для `--rollback`** ```bash docker service rollback api No previous image to roll back to: same tag ``` Якщо обидва нові і старі були tagged `latest`, Swarm не може їх розрізнити. Завжди tag версією (або commit SHA), щоб rollback працював. ### Реальне застосування - **Прод-деплої на Swarm-кластерах** — кожен новий image тригерить `service update`; Swarm обробляє parallelism + monitoring. - **Staged canary** — спочатку deploy 1 з 10 з `parallelism=1` і довгим monitor; якщо стабілізується, підніми parallelism для решти. - **Hotfix-rollout** — `service update --image hotfix:1.0` з високим parallelism (швидше) і агресивним monitoring (ловити failures швидко). - **DB-міграції** — ніколи через rolling-update напряму. Спочатку запусти one-off migrator-сервіс, тоді update app-репліки. ### Питання для поглиблення **Q:** Що відбувається з in-flight запитами під час task-replacement? **A:** Task, scheduled for replacement, отримують SIGTERM і налаштований grace-період (`stop_grace_period`). Застосунки мають drain in-flight запити перед виходом. У комбінації з routing mesh трафік steer'иться від stopping-task перед SIGTERM. **Q:** Чи можу update'нути кілька сервісів разом? **A:** Edit stack-файл з новими image для кожного, тоді `docker stack deploy -c stack.yaml mystack`. Кожен сервіс update'ься незалежно за своїм config; cross-service ordering не отримаєш. **Q:** Як Swarm rolling-update відрізняється від K8s rolling-update? **A:** Концептуально ідентично. K8s deployment: `maxSurge`, `maxUnavailable` ≈ Swarm `parallelism` і order. K8s readiness-probes ≈ Swarm healthcheck. Та сама модель, інший синтаксис. **Q:** Яка різниця між `update_config` і `rollback_config`? **A:** `update_config` контролює forward-update (1.0 → 1.1). `rollback_config` контролює reverse-update (1.1 → 1.0). Часто хочеш повільніший, безпечніший rollback, ніж forward-update. **Q:** (Senior) Як спроектувати rolling-update параметри для сервісу, що бере 90 секунд на прогрів? **A:** `start_period` у healthcheck = 120с (дай warmup час перед рахунком failures). `update-monitor` = 180с (чекай досить довго, щоб побачити реальні failures emerge). `parallelism` = 1 (повільний rollout, 90с warmup × репліки = загальний update-час). `failure_action` = rollback. Патерн: monitor-period > start-period > observation, потрібний для стабільності. Швидші rollout ховають warmup-related failures; цей консервативний config їх ловить. ## Приклади ### Production-якості rollout ```yaml version: '3.9' services: api: image: myorg/api:1.0 deploy: replicas: 6 update_config: parallelism: 2 delay: 30s order: start-first failure_action: rollback monitor: 60s max_failure_ratio: 0.2 rollback_config: parallelism: 2 delay: 10s restart_policy: condition: any healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 10s timeout: 3s retries: 3 start_period: 30s ``` Deploy з новим image: ```bash sed -i 's/myorg\/api:1.0/myorg\/api:1.1/' stack.yaml docker stack deploy -c stack.yaml mystack docker service ps mystack_api # Дивись, як task замінюються 2 за раз, з 30с gap, monitored 60с кожен. ``` ### Manual rollout з імперативними флагами ```bash docker service update \ --image myorg/api:1.1 \ --update-parallelism 1 \ --update-delay 60s \ --update-monitor 120s \ --update-failure-action rollback \ --update-max-failure-ratio 0.0 \ --update-order start-first \ api # Строго: будь-який failure тригерить rollback. ``` Корисно для one-off tightly-controlled rollout. ### Watching rollout ```bash $ watch -n 2 'docker service ps mystack_api --format "table {{.Name}}\t{{.Image}}\t{{.CurrentState}}"' # Live-view, які task якої версії, у якому стані. ``` Чудово для верифікації, що rollout прогресує як очікувано.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.