Нататкі: ноды ў кластары Docker Swarm
Docker Swarm — гэта ўбудаваны аркестратар Docker аб'ядноўваючы некалькі сэрвероў у адзін кластар зь цэнтралізаваным кіраўніцтвам. Адна зь самых частых задач пры эксплуатацыі кластара — далучэньне і выдаленне нодаў. Разбярэм кожны крок падрабязна.
Тыпы нодаў у Swarm
У Docker Swarm ёсць два тыпы нодаў:
- Manager — удзельнічае ў кіраванні кластарам (Raft consensus), можа выконваць каманды
docker service,docker stackі гэтак далей. Таксама можа запускаць кантэйнеры (калі не абмежаваны). - Worker — толькі выконвае задачы (таскі), не мае доступу да кіравання кластарам.
Усе каманды кіравання кластарам выконваюцца на любой мэнэджар-нодзе.
Змяніць hostname перад далучэннем
Docker Swarm выкарыстоўвае hostname сэрверу як назву ноды. Калі ўсе сэрверы маюць аднолькавы дэфолтны hostname (напрыклад, ubuntu або localhost), гэта прывядзе да блытаніны.
Мяняем hostname да далучэння да кластара і дадаем радок да /etc/hosts (каб лакальнае імя рэзолвілася):
hostnamectl set-hostname host-endor
echo "127.0.1.1 host-endor" >> /etc/hostsЗмены ўступяць у сілу пасля перазапуску сесіі ці перазагрузкі. Пасля гэтага далучаемся да кластара — нода будзе адлюстравана з правільным іменем.
Калі нода ўжо ў кластары і трэба перайменаваць яе:
docker node update --label-add alias=new-name <NODE_ID>Змяніць лэйбл (display label) ноды — НЕ мяняе фактычны hostname
Для рэальнага перайменавання — змяніць hostname на сэрверы і перазапусціць docker daemon:
hostnamectl set-hostname host-mustafar
systemctl restart dockerІніцыялізацыя першага мэнэджара
Каб стварыць новы кластар, на першым сэрверы выконваем:
docker swarm init --advertise-addr <IP_АДРАС>--advertise-addr — гэта IP, па якім іньшыя ноды будуць падключацца да гэтага мэнэджару. Выкарыстоўваецца зьнешні ці ўнутраны (адрас у прыватнай сетцы, дасяжны для ўсіх астатніх хастоў) сеткавы адрас сэрверу, а не 127.0.0.1.
Прасьцей за ўсё паглядзець адрас камандай
~$ hostname -I
21.127.43.17 172.18.0.1 172.17.0.1 2211:468:ccbb:dd77::1Прыклад:
docker swarm init --advertise-addr 21.127.43.17Пасля выканання каманды Docker вывядзе токен для далучэння воркераў і падказку, як атрымаць токен для даданьня дадатковых менеджараў:
Swarm initialized: current node (host-endor) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-xxx 21.127.43.17:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.Цалкам магчымасьці каманды ініцыялізацыі выглядаюць так:
Usage: docker swarm init [OPTIONS]
Initialize a swarm
Options:
--advertise-addr string Advertised address (format: "<ip|interface>[:port]")
--autolock Enable manager autolocking (requiring an unlock key to start a stopped manager)
--availability string Availability of the node ("active", "pause", "drain") (default "active")
--cert-expiry duration Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
--data-path-addr string Address or interface to use for data path traffic (format: "<ip|interface>")
--data-path-port uint32 Port number to use for data path traffic (1024 - 49151). If no value is set or is set to 0, the default port (4789) is used.
--default-addr-pool ipNetSlice default address pool in CIDR format (default [])
--default-addr-pool-mask-length uint32 default address pool subnet mask length (default 24)
--dispatcher-heartbeat duration Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
--external-ca external-ca Specifications of one or more certificate signing endpoints
--force-new-cluster Force create a new cluster from current state
--listen-addr node-addr Listen address (format: "<ip|interface>[:port]") (default 0.0.0.0:2377)
--max-snapshots uint Number of additional Raft snapshots to retain
--snapshot-interval uint Number of log entries between Raft snapshots (default 10000)
--task-history-limit int Task history retention limit (default 5)Порт 2377 — стандартны порт Swarm для міжнодавай камунікацыі. Яго трэба адкрыць у firewall паміж усімі нодамі.
📖 Дакументацыя: docker swarm init
Якія сеткавыя парты выкарыстоўвае Docker Swarm
Docker Swarm выкарыстоўвае тры парты для камунікацыі паміж нодамі. Важна разумець, якія з іх патрэбны толькі мэнэджарам, а якія — усім нодам без выключэння.
Порт 2377/TCP — кіраванне кластарам
Выкарыстоўваецца выключна для камунікацыі паміж мэнэджарамі і для далучэння новых нодаў (docker swarm join). Воркеры не камунікуюць па гэтым порце пасля далучэння.
- Адкрыць толькі на мэнэджарах
- Напрамак: усе ноды → мэнэджары
Для UFW:ufw allow from 10.0.0.0/24 to any port 2377 proto tcp
Для iptables:
iptables -A INPUT -p tcp --dport 2377 -s 10.0.0.0/24 -j ACCEPT
Порт 7946/TCP і 7946/UDP — gossip-пратакол (discovery)
Выкарыстоўваецца для выяўлення нодаў і абмену станам кластара праз Serf gossip. Патрэбен усім нодам — і мэнэджарам, і воркерам.
- Адкрыць на ўсіх нодах
- Абодва пратаколы: TCP і UDP
- Напрамак: двухбаковы, паміж усімі нодамі
Для UFW:ufw allow from 10.0.0.0/24 to any port 7946 proto tcpufw allow from 10.0.0.0/24 to any port 7946 proto udp
Порт 4789/UDP — overlay-сеткі (VXLAN)
Выкарыстоўваецца для трафіку ўнутры overlay-сетак (docker network create --driver overlay). Патрэбен усім нодам, на якіх запускаюцца кантэйнеры з overlay-сеткамі.
- Адкрыць на ўсіх нодах
- Толькі UDP
- Напрамак: двухбаковы, паміж усімі нодамі
Для UFW:ufw allow from 10.0.0.0/24 to any port 4789 proto udp
Важна: порт 4789 выкарыстоўваецца ядром Linux для VXLAN-інкапсуляцыі. Калі сервер знаходзіцца за знешнім фаерволам (напрыклад, у хостэра), правілы трэба дадаваць і там.
Рэзюмэ:
2377: [TCP] Мэнэджары - Кіраванне кластарам, swarm join7946 [TCP + UDP] Усе ноды - Gossip (выяўленне нодаў, стан кластара)4789 [UDP] Усе ноды - Overlay-сеткі (VXLAN)
📖 Дакументацыя: firewall configuration for Docker Swarm
Калі ўсе ноды звязаны паміж сабой прыватнай сеткай — часам прасцей дазволіць увесь трафік унутры падсеткі замест адкрыцьця партоў паасобку. Але калі ноды раскіданы па розных сэрверах/правайдарах/датацэнтрах і зносіны адбываюцца паверх публічных сетак - правілы па партах абавязковыя.
Дадаць воркер ноду
На новым сэрверы выконваем каманду, якую выдаў swarm init (ці атрымоўваем яе зноўку на мэнэджары):
docker swarm join-token workerЗатым на новым сэрверы:
docker swarm join --token SWMTKN-1-xxx 21.127.43.17:2377Пасля далучэння праверыць спіс нодаў можна на мэнэджэр хасце:
docker node lsВывад будзе прыкладна такім:
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
l6dccl2z3gi8z2jnurssh5xr2* host-endor Ready Active Leader 28.5.2
ucx5iyh1orschlhnxe9n0ve45 host-tatooine Ready Active 28.5.2📖 Дакументацыя: docker swarm join
Дадаць дадатковы мэнэджар
Колькі мэнэджараў трэба і чаму
Docker Swarm выкарыстоўвае алгарытм Raft для дасягнення кансэнсусу ў кластары. Гэта азначае, што для прыняцця любога рашэння (разгортванне сэрвісу, змена канфігурацыі) патрэбна большасць мэнэджараў — кворум.
Формула кворуму: ⌊N/2⌋ + 1, дзе N — агульная колькасць мэнэджараў.
| Колькасьць мэнэджэраў | Кворум | Дапушчальная страта |
|---|---|---|
| 1 | 1 | 0 |
| 2 | 2 | 0 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 3 | 2 |
| 7 | 4 | 3 |
Рэкамендацыі:
- 1 мэнэджар — для
devасяродку і тэставых стэндаў. Страта адзінага менеджара == страта кластара. - 3 мэнэджары — мінімум для
prodасяродку. Кластар перажыве страту аднаго. - 5 мэнэджараў — добры выбар для буйных інсталяцый. Перажыве страту двух адначасова.
- Больш за 7 — не рэкамендуецца. Накладныя выдаткі на Raft-камунікацыю расцуць, а надзейнасць ужо не павялічваецца значна.
Заўвага: Заўсёды выкарыстоўваць няцотную колькасць мэнэджэраў. 2 або 4 мэнэджары не даюць ніякай перавагі перад 1 і 3 адпаведна, але патрабуюць той жа кворум.
Кворум: чаму гэта важна
Кворум — гэта мінімальная колькасць мэнэджараў, якія павінны быць даступны, каб кластар мог прымаць рашэнні. Калі кворум губляецца:
- Новыя сэрвісы не могуць быць разгорнуты.
- Бягучыя сэрвісы працягваюць працаваць (таскі ужо запланаваны і выконваюцца воркерамі).
- Ніякія змены канфігурацыі кластара немагчымы.
- Каманды кшталту
docker service update,docker stack deployбудуць вяртаць памылку.
Гэта значыць, калі з 3 мэнэджэраў 2 упалі — кластар "замарожваецца" у бягучым стане. Нічога нельга змяніць, пакуль не будзе адноўлены кворум.
Калі кворум усё ж страчаны і аднавіць мэнэджары немагчыма — ёсць аварыйная працэдура аднаўлення:
docker swarm init --force-new-clusterТОЛЬКІ ў аварыйнай сітуацыі — прымусовае аднаўленне кластара з аднаго вузла
📖 Дакументацыя: Raft кансэнсус і кворум
Далучэнне мэнэджэр-ноды
На бягучым мэнэджэры атрымоўваем токен:
docker swarm join-token managerНа новым сэрверы:
docker swarm join --token SWMTKN-1-yyy 21.127.43.17:2377Даданне лэйбла (тэга) для новай ноды
Лэйблы выкарыстоўваюцца для прывязкі сэрвісаў да пэўных нодаў праз placement constraints. Напрыклад, базы дадзеных толькі на нодах з SSD, або фронтэнд толькі на нодах у пэўным датацэнтры.
# Дадаць лэйбл
docker node update --label-add role=database host-naboo
# Дадаць некалькі лэйблаў
docker node update --label-add dc=fra --label-add disk=ssd host-alderaan
# Паглядзець лэйблы ноды
docker node inspect --pretty node-endorВыкарыстанне ў docker-compose.yml / стэку:
services:
postgres:
image: postgres:16
deploy:
placement:
constraints:
- node.labels.role == databaseВыдаленне воркер-ноды з кластара
Выдаленне воркера — просты двухкрокавы працэс.
Крок 1: Перавесці ноду ў стан drain (усе таскі будуць перанесены на іньшыя ноды, выконваць на нодзе-мэнэджары):
docker node update --availability drain worker1Пачакайце, пакуль усе кантэйнеры перамесцяцца на іньшыя ноды (паглядзець можна праз docker service ps <service-name>).
Крок 2: Выдаліць ноду з кластара:
docker swarm leaveВарыянт A: з самой ноды (перад выдаленнем з кластара)
docker node rm host-naboo
# або
docker node rm --force host-nabooВарыянт B: прымусова з мэнэджару (калі нода недаступна)
Пасля docker swarm leave нода з'явіцца ў спісе са статусам Down. Яе трэба выдаліць з рэестру кластара:
docker node rm host-naboo📖 Дакументацыя: docker node rm
Выдаленне мэнэджар-ноды з кластара
Выдаленне мэнэджару патрабуе дадатковай асцярожнасці, каб не страціць кворум.
Варыянт 1: Зніжэнне да воркера перад выдаленнем
Гэта самы бясьпечны спосаб:
docker node demote host-tatooineКрок 1: Зніжаем мэнэджара да воркера
docker node update --availability drain host-tatooine
Крок 2: Далей як звычайны воркер
docker swarm leaveКрок 3: На самой выдаляемай нодзе
docker node rm host-tatooineКрок 4: На адным зь застаўшыхся мэнэджэраў
Варыянт 2: Прамое выдаленне (калі нода недаступна)
docker node rm --force host-alderaanПрымусовае выдаленне з мэнэджару
Перад выдаленнем мэнэджару заўсёды ўпэўніцеся, што кворум будзе захаваны. Калі маеце 3 мэнэджары і выдаляеце адзін — застаецца 2, кворум 2 з 2 — усё нармальна. Калі маеце 3 мэнэджары і хочаце выдаліць 2 — кластар страціць кворум.
📖 Дакументацыя: docker node demote
Калі лепей спачатку павысіць аднаго зь воркераў да мэнэджару
Ёсць сітуацыі, калі рэплейсмент мэнэджару правільней рабіць праз "спачатку дадаць, потым выдаліць":
- Міграцыя на новы сэрвер альбо выдаленьне хаста-мэнэджару цалкам
Калі проста выдаліць стары мэнэджар і дадаць новы — на час аперацыі колькасць мэнэджараў зьмяняецца, і пры малой іх колькасці можна ненадоўга апынуцца ў рызыкоўным стане.
Правільны парадак:
docker node promote host-naboo
Крок 1: Для абранага воркеру падымаем узровень да мэнэджару
docker node lsКрок 2: Пераконваемся, што былы воркер адлюстроўваецца ў сьпісе як мэнэджар
docker node demote host-endor
docker node update --availability drain host-endor
docker node rm host-endor3. Толькі пасьля гэтага зьніжаем і выдаляем той, які зьбіраліся
- Колькасць мэнэджараў на мяжы кворуму (мінімальная). Калі маеце роўна 3 менеджары і хочаце замяніць адзін — спачатку дадайце 4-ы (хай часова колькасць парная), а потым выдаліце стары.
- Планавы перанос пры абнаўленні АС або міграцыі. Калі трэба зрабіць паслядоўную замену ўсіх нодаў (rolling replacement), не спыняючы кластар.
- Вы не ўпэўнены ў стане ноды. Калі мэнэджар паводзіць сябе дзіўна (памылкі Raft, нестабільнасць), лепей дадаць новы і толькі потым выдаліць праблемны.
Карысныя каманды для кіравання нодамі
docker node lsПаглядзець усе ноды
docker node inspect host-tatooine --prettyПадрабязная інфармацыя пра ноду
docker node ps host-nabooПаглядзець таскі на пэўнай нодзе
docker node update --availability active host-mustafarЗняць ноду з абслугоўвання (перавесці назад у Active)
docker swarm join-token worker
docker swarm join-token managerАтрымаць токены для далучэння
docker swarm join-token --rotate worker
docker swarm join-token --rotate managerРатацыя токенаў (пры змене)
Кароткае рэзюмэ
| Задача | Каманда |
|---|---|
| Ініцыялізаваць кластар | docker swarm init --advertise-addr <MANAGER_IP> |
| Далучыць воркера | docker swarm join --token <WORKER_TOKEN> <MANAGER_IP>:2377 |
| Далучыць мэнэджэра | docker swarm join --token <MANAGER_TOKEN> <MANAGER_IP>:2377 |
| Панізіць мэнэджэра да воркера | docker node demote <NODE> |
| Павысіць воркера да мэнэджэра | docker node promote <NODE> |
| Перавесці ў drain | docker node update --availability drain <NODE> |
| Выдаліць ноду | docker node rm <NODE> |
| Выйсці з кластара | docker swarm leave |
| Дадаць лэйбл | docker node update --label-add key=value <NODE> |