Kubernetes в 2023 году является стандартом в управлении контейнерами, но иногда нужно что-то более легкое, с не столь высоким порогом вхождения.
Docker предлагает свой встроенный оркестратор — Docker Swarm.
Если описать его работу коротко, то следует отметить следующее:
- Docker Swarm объединяет Docker хосты в единый кластер и позволяет управлять их запуском и масштабированием.
- Есть два типа нод, Manager — которые могут как управлять кластером, так и запускать сами контейнеры и Worker — являющиеся своего рода исполнителями.
- При работе в кластере, помимо масштабирования происходит балансировка нагрузки, а значит повышается и отказоустойчивость нашего приложения.
Нет смысла сравнивать Kubernetes и Docker, нужно просто знать как работают оба, но если сказать совсем просто — Docker Swarm пригодится там где нужен быстрый и простой способ управлять контейнерами, не затрачивая много усилий, Kubernetes больше подойдет в задачах со сложной архитектурой, функционалом и масштабируемостью.
Перейдем к практике.
Устанавливать будем на CentOS 7.
Сначала вам необходимо установить на все виртуальные машины Docker (установка).
В нашей тестовой лабораторной работе будет 3 сервера (1 master и 2 worker ноды).
Схема следующая:
kuber-master — master
kube-node01 — worker1
kube-node02 — worker2
На мастер ноде выполняем
docker swarm init
Вы получите следующий ответ, сохраните данные в надежном месте, они нам понадобятся
Swarm initialized: current node (wh56mpocukah2oi4dba5b3kuy) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-34vtvtxxbcq9w4al42aurpyiq6rric9cv30bgb995idvppms5e-4ei04zll437bb16lko4kopgmx 10.0.8.68:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
Проверяем список доступных нод
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
wh56mpocukah2oi4dba5b3kuy * kuber-master.lan Ready Active Leader 24.0.6
Подключаем worker ноды, у вас будет свой токен и ip адрес
docker swarm join --token SWMTKN-1-34vtvtxxbcq9w4al42aurpyiq6rric9cv30bgb995idvppms5e-4ei04zll437bb16lko4kopgmx 10.0.8.68:2377
Копируем и запускаем на обе worker ноды
Если у вас появляется ошибка
Error response from daemon: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 10.0.8.68:2377: connect: no route to host"
Проверьте настройки файервола, открыт ли порт 2377. Чтобы открыть сделаем
firewall-cmd --add-port=2377/tcp --permanent
firewall-cmd --reload
Далее пробуем еще раз и получаем в консоли
This node joined a swarm as a worker.
Проверяем на мастере
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
wh56mpocukah2oi4dba5b3kuy * kuber-master.lan Ready Active Leader 24.0.6
0hwkwllvoxfd2lpw9j5fa7qdl kuber-node01.lan Ready Active 24.0.6
iwfyu36w553dq83keji7xh3pj kuber-node02.lan Ready Active 24.0.6
Деплоить будем nginx (быстро, просто и наглядно). Создаем на мастер ноде уже знакомый docker-compose.yml со следующим содержанием
version: "3.9"
services:
nginx:
image: nginx:latest
ports:
- "80:80"
deploy:
replicas: 1
placement:
constraints:
- node.role == worker
update_config:
parallelism: 1
delay: 10s
restart_policy:
condition: on-failure
На что стоит обратить внимание.
- deploy это конкретно секция для работы в docker swarm.
В этом примере мы запускаем сервис nginx, используя последний образ, пробрасываем 80 порт.
- replicas: 1 указывает, на то, что должна быть запущено только одна реплика контейнера для этой службы.
- placement: — это секция, в которой определяются ограничения на размещение сервиса.
- constraints: — это список ограничений на размещение сервиса.
- node.role == worker — это ограничение, которое говорит, что сервис должен быть развернут только на worker нодах.
- update_config определяет, как Docker Swarm должен обновлять службу:
- parallelism: 1 указывает, что Docker Swarm должен обновлять одну реплику контейнера за раз.
- delay: 10s указывает, что Docker Swarm должен ждать 10 секунд перед обновлением следующей реплики.
- restart_policy: condition: on-failure определяет, когда Docker Swarm должен перезапускать контейнер, в данном случае если в контейнере возникнет ошибка и он завершит работу
Важно отметить что Docker Swarm не перезапускает контейнеры, если они были явно остановлены пользователем.
Деплоим
docker stack deploy -c docker-compose.yml devopslife
Проверяем
docker stack services devopslife
ID NAME MODE REPLICAS IMAGE PORTS
s9qirt16uztv devopslife_nginx replicated 0/1 nginx:latest *:80->80/tcp
docker service ps s9qirt16uztv (id сервиса)
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wvh5jswsabft devopslife_nginx.1 nginx:latest kuber-node01.lan Running Running less than a second ago
Для масштабирования, есть специальная команда
docker service scale devopslife_nginx=<количество_экземпляров>
Допустим сделаем
docker service scale devopslife_nginx=2
devopslife_nginx scaled to 2
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
docker service ps s9qirt16uztv
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wvh5jswsabft devopslife_nginx.1 nginx:latest kuber-node01.lan Running Running about a minute ago
fgq6t20wrfvc devopslife_nginx.2 nginx:latest kuber-node02.lan Running Running 22 seconds ago
Выключим одну из нод (имитируем выключение сервера)
Проверим
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
wh56mpocukah2oi4dba5b3kuy * kuber-master.lan Ready Active Leader 24.0.6
0hwkwllvoxfd2lpw9j5fa7qdl kuber-node01.lan Ready Active 24.0.6
iwfyu36w553dq83keji7xh3pj kuber-node02.lan Down Active 24.0.6
Как видите одна из нод ушла в Down
docker service ps s9qirt16uztv
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wvh5jswsabft devopslife_nginx.1 nginx:latest kuber-node01.lan Running Running 3 minutes ago
x32uug6yyoaq devopslife_nginx.2 nginx:latest kuber-node01.lan Running Running less than a second ago
fgq6t20wrfvc \_ devopslife_nginx.2 nginx:latest kuber-node02.lan Shutdown Running 2 minutes ago
Теперь восстановим работу сервера
И еще раз проверим
docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
wh56mpocukah2oi4dba5b3kuy * kuber-master.lan Ready Active Leader 24.0.6
0hwkwllvoxfd2lpw9j5fa7qdl kuber-node01.lan Ready Active 24.0.6
iwfyu36w553dq83keji7xh3pj kuber-node02.lan Ready Active 24.0.6
При заходе на ip адреса по 80 порту любой из машин мы увидим приветственное окно nginx
Можно еще выполнить
docker service scale devopslife_nginx=1
посмотреть что будет и вновь сделать
docker service scale devopslife_nginx=2
Для завершения работы необходимо выполнить команду
docker service rm <service_name>
docker service rm devopslife_nginx
Для выхода из кластера выполнить на каждой ноде
docker swarm leave (для worker)
или
docker swarm leave --force (для manager)
Получаем
Node left the swarm
Таким образом мы можем использовать Docker Swarm для управления и масштабирования контейнерами.
Photo by James Wainscoat on Unsplash