В этой статье я рассмотрю, как создать кластер Docker Swarm из трёх хостов. Я буду использовать три виртуальных хоста на CentOS Stream 9. У хостов следующие ip-адреса:
Первым делом необходимо проверить что на всех хостах стоит Docker и самое главное одинаковой версии. В дальнейшем при обновлении Docker старайтесь поддерживать одну и ту же версию на всех хостах кластера. Если Docker не стоит, то устанавливаем по инструкции.
docker info
Активация Swarm
Выполняю команду docker swarm init на c-stream-9-vm4, после выполнения команды хост также станет лидером менеджеров, которые управляют кластером. Т.е. для управления кластером и создания сервисов хост, на котором вы выполняете команды должен быть менеджером кластера.
docker swarm init
Swarm initialized: current node (ojbmchzvipwmlwsssx0ctrxyq) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1t2rvntthomlpuvdsd7cxckzku6njkei32fyqrxntcmcq119p7-9xhm3uyo5t2uv1tangzn4fc5y 172.31.144.9:2377
Обратите внимание что команды также вывела ip-адрес и порт, по которому другие хосты в кластере будут обращаться к c-stream-9-vm4. Если вдруг у вас несколько ip-адресов, то можно добавить опцию --advertise-addr 192.168.1.1. Соответственно все узлы в кластере должны иметь возможность обращаться друг к другу. Вот минимальный список портов, которые должны быть открыт между хостами кластера:
Поэтому на каждом хосте я выполняю команды для настройки локального файрволла:
sudo firewall-cmd --permanent --add-port=2377/tcp
sudo firewall-cmd --permanent --add-port=7946/tcp
sudo firewall-cmd --permanent --add-port=7946/udp
sudo firewall-cmd --permanent --add-port=4789/udp
sudo firewall-cmd --reload
Добавление новых узлов в кластер
После выполнения команды docker swarm init кластер уже создан и в нём всего один хост, теперь используя вывод команды добавляем в кластер оставшиеся два хоста, по умолчанию статус у них будет worker.
docker swarm join --token SWMTKN-1-1t2rvntthomlpuvdsd7cxckzku6njkei32fyqrxntcmcq119p7-9xhm3uyo5t2uv1tangzn4fc5y 172.31.144.9:2377
This node joined a swarm as a worker.
На менеджере (c-stream-9-vm4) выполняю команду для проверки узлов в кластере:
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ojbmchzvipwmlwsssx0ctrxyq * c-stream-9-vm4 Ready Active Leader 25.0.3
sho740q9bdze4xcspm7mzv9m9 c-stream-9-vm8 Ready Active 25.0.3
m8hrgh3jdlqlzijvhjdig4lx2 c-stream-9-vm9 Ready Active 25.0.3
Из вывода видно, что сейчас только один MANAGER в кластере и если я попытаюсь выполнить ту же команду на другом узле я получу ошибку: This node is not a swarm manager.
Смена роли с Worker на Manager
Логично что иметь кластер всего с одним Manager не очень-то и безопасно, поэтому я изменю роль оставшимся двум узлам с просто Worker на Manager.
Для этого на Manager узле я выполняю:
docker node update --role manager c-stream-9-vm8
docker node update --role manager c-stream-9-vm9
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ojbmchzvipwmlwsssx0ctrxyq * c-stream-9-vm4 Ready Active Leader 25.0.3
sho740q9bdze4xcspm7mzv9m9 c-stream-9-vm8 Ready Active Reachable 28.3.3
m8hrgh3jdlqlzijvhjdig4lx2 c-stream-9-vm9 Ready Active Reachable 25.0.3
Если же вдруг еще до входа в кластер понятно, что этот хост должен быть MANAGER можно на уже имеющемся MANAGER хосте получить токен для входа в кластер уже со статусом MANAGER, и дальше добавлять новые хосты в кластер уже с ролью MANAGER.
docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1t2rvntthomlpuvdsd7cxckzku6njkei32fyqrxntcmcq119p7-26ztp5rlpq6byyvymgp447g8u 172.31.144.9:2377
Как работает выбор лидера
Swarm использует алгоритм Raft для консенсуса между менеджерами:
Создание Service
Теперь всё готов для того, чтобы я создал первый сервис в кластере. Я создам веб сервис из образа Nginx и укажу три реплики. Так как у меня три хоста в кластере, каждый хост будет размещать по одному контейнеру. В таком случае при неисправности какого-то хоста мой веб сервис будет продолжать работать.
docker service create --replicas 3 --name web -p 80:80 nginx
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
docker service ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
42iq7g9uwvqk web.1 nginx:latest c-stream-9-vm4 Running Running 28 seconds ago
8yhysu9vqh00 web.2 nginx:latest c-stream-9-vm8 Running Running 29 seconds ago
zig22fjbiaqc web.3 nginx:latest c-stream-9-vm9 Running Running 28 seconds ago
Из вывода команд видно, что при создании сервиса Docker Swarm создал по одном контейнеру на каждом хосте кластера.


Комментарии