Статья также доступна на украинском (перейти к просмотру).
Оглавление
- Основные концепции и определения
- Инициализация кластера Docker Engines в swarm-режиме
- Запуск, развертывание и управление сервисами в пределах кластера
- Итоги
Интегрированный в Docker Engine инструментарий или Swarmkit для управления кластером является средством реализации уровня оркестрирования задач Docker. Он позволяет выстраивать и управлять кластерами любой конфигурации и размера, балансируя при этом нагрузку на кластер в автоматическом режиме. Механизм Docker Swarm позволяет запускать сервисы Docker Compose в разветвленном кластере, а не только в локальной среде. Рассмотрим его более подробно и продемонстрируем работу с ним в реальной программной среде.
Основные концепции и определения
Начиная с версии 1.12, стало доступно использование Docker Engine в режиме Swarm, позволяющего организовать масштабируемую сеть Docker-узлов, каждый из которых может выполнять функции управляющего узла, рабочего или то и другое. В отличие от автономных контейнеров, которые могут управляться любым Docker-даемоном, сервисами кластера могут управлять только узлы со статусом Manager. Таких узлов может быть несколько в пределах кластера, но среди них выбирается только один лидер (Leader), который и принимает все главные решения по распределению задач между рабочими узлами и балансировке нагрузки.
Система Docker в режиме Swarm имеет внутреннюю службу DNS, которая в автоматическом режиме назначает каждому сервису аккаунт DNS. Это позволяет узлу со статусом Leader использовать возможности указанной службы для внутренней балансировки нагрузки для распределения запросов между сервисами в пределах кластера.
Технология использует декларативную модель управления кластерами, при которой заранее описывается желаемое состояние конфигурации различных сервисов стека приложения, после чего сформированная конфигурация поддерживается системой в автоматическом режиме, согласуя реальное состояние конфигурации и заявленное.
Для каждого сервиса можно в любое время произвести масштабирование путем изменения количества задач в файле определения конфигурации сервисов. Система автоматически «уберет» лишние реплики или запустит новые.
Доступна возможность указать оверлейную сеть для сервисов. Управляющий узел автоматически назначит адрес контейнерам при обновлении или инициализации системы.
Повышенный уровень безопасности установлен по умолчанию здесь за счет применения к каждому из узлов взаимной аутентификации и TLS-шифрования.
Определим основные термины, которые потребуются для дальнейшего рассмотрения и использования Docker в режиме Swarm.
- Узел;
- Сервис;
- Задание;
- Реплика.
Узел (нода) – это экземпляр Docker Engine, входящий в кластер. Один или несколько узлов можно запустить как на локальной физической машине или облаковом сервисе, так и на нескольких компьютерах, что обычно и делается. Для их развертывания необходимо отправить определение сервиса на узел, имеющий статус Manager.
Сервис является определением задач, которые должны запускаться на рабочих или управляющих нодах. Он может иметь любую конфигурацию и количество реплик. Могут запускаться в двух режимах: репликации, когда задачи распределяются между узлами в соответствии с планировками и/или нагрузками; глобальной сети, когда одна задача сервиса запускается на каждом доступном узле кластера.
Задача является самой маленькой единицей планирования кластера. Оно включает в себя контейнер и внутренние команды для него. Распределяются по узлам в соответствии с количеством реплик, заданным в конфигурации сервиса. Оно может производиться только на узле, которому предназначено.
Реплика – это количество дубликатов определенного контейнера для запуска на узлах кластера.
Инициализация кластера Docker Engines в swarm-режиме
Нами будет создана кластерная сеть, включающая один управляющий узел и один рабочий. Операционные системы (ОС) узлов идентичны – это ОС Ubuntu 20.04. Имя каждого из хостов также совпадает и имеет значение dedicated. Пользователь – root.
Существует два способа создания кластера – подключиться к уже существующему или создать новый на основе управляющего узла с определенным IP-адресом. Такой адрес должен быть статическим, чтобы все рабочие узлы могли взаимодействовать с лидером. Само собой, на каждой машине должна быть развернута Docker Engine. Кроме того, для беспрепятственного обмена информацией между всеми участниками необходимо на каждом хосте открыть некоторые порты и протоколы. Для этой цели мы настроим соответствующим образом брандмауэры Linux и только затем активируем режим Swarm и создадим кластер.
Подготовка управляющего узла
На текущей машине нами ранее уже разрабатывался проект по Docker Compose, результаты работы которого представлены в предыдущей статье, то есть здесь уже функционирует система Docker Engine и поэтому нет необходимости ее устанавливать. Остается только настроить брандмауэр. Откроем наиболее значимые порты и протоколы, что необходимо для взаимодействия между узлами и сетями.
Для указанной цели воспользуемся утилитой iptables, являющейся стандартным интерфейсом управления работой брандмауэра для ядер Linux. Введем в терминале следующие команды:
$ iptables -N swarm $ iptables -A INPUT -p tcp --dport 2376 -j swarm $ iptables -A INPUT -p tcp --dport 2377 -j swarm $ iptables -A INPUT -p udp --dport 4789 -j swarm $ iptables -A INPUT -p udp --dport 7946 -j swarm $ iptables -A INPUT -p tcp --dport 7946 -j swarm $ iptables -A swarm -s 178.20.159.96 -j ACCEPT $ iptables -A swarm -s 178.20.157.229 -j ACCEPT $ iptables -A swarm -j DROP
Здесь мы использовали IP-адреса нод кластера: 178.20.159.96 – адрес текущего хоста, который будет лидером; 178.20.157.229 – адрес хоста, который станет рабочим нодом или ворком.
Подготовка рабочего узла
Развернем систему Docker. Для этого наберем в терминале:
$ apt install docker.io
Подтвердим выделение дополнительных 293 Mb и продолжим процесс развертывания системы.
Откроем порты и протоколы так же, как мы сделали на первом хосте:
$ iptables -N swarm ... $ iptables -A swarm -j DROP
Итак, хост – будущий ворк, настроен. Теперь перейдем к инициализации кластера.
Включение swarm-режима
Режим включается сразу же после его инициализации с помощью команды docker swarm init, которая имеет собственный набор параметров для возможности указать открытый IP-адрес управляющего узла и/или пул IP-адресов для глобальной сети. По умолчанию Docker Swarm использует пул адресов 10.0.0.0/8 для оверлейных сетей. Смена пула может потребоваться при наличии сетевых конфликтов. Открытый IP-адрес должен назначаться сетевому интерфейсу, доступному операционной системе хоста. Все ноды кластера должны будут подключаться к лидеру именно по ней. Чтобы не ошибиться в определении IP-адреса управляющей ноды, можно воспользоваться следующей командой:
$ ifconfig
Можно убедиться, что IP-адрес 178.20.159.96, указанный для интерфейса eth0, является корректным. Укажем именно ее для нашей управляющей ноды с помощью параметра advertise-addr:
$ docker swarm init --advertise-addr 178.20.159.96
Судя по сообщению на выходе команды, режим Swarm активирован и указанный хост получил статус Manager, то есть стал управляющим узлом. Кроме того, мы получили команду и токен для добавления к кластеру рабочей ноды:
docker swarm join --token SWMTKN-1-1qtzfzt0hsu84aydx6c9s8wscq7b4le8y7tnkiqufjbtht6xci-dpp945n10z7sdze5oa4dftm9e 178.20.159.96:2377
Команда должна быть исполнена на выбранном хосте.
В результате выполнения команды docker swarm init произошло следующее:
- Включение режима Swarm на текущем узле;
- Назначение ему статуса ведущего узла – лидера кластера;
- Присвоение ему имени хоста;
- Настройка диспетчера для прослушивания активного сетевого интерфейса на 2377 порта;
- Перевод текущего узла в режим доступности для получения задач от планировщика;
- Запуск внутреннего распределенного хранилища данных для Docker-машин – участников кластера;
- Создание подписанного корневого сертификата для кластера;
- Сгенерированный токен для подключения к сети других участников;
- Создана оверлейная сеть с именем ingress для публикации внешних портов;
- Созданный IP-адрес и маска под сетями для кластера.
Проверим список нодов в нашем Swarm-кластере:
$ docker node ls
Как видим, наш узел получил статус Leader – самый высокий статус среди всех управляющих узлов. Это связано с тем, что он пока является единственным управляющим узлом в сети.
Расширение кластера
Мы уже выяснили, что для возможности расширения кластера необходимо получить токены, отдельно для рабочих и управляющих нод. Добавим рабочую ноду к нашему кластеру, воспользовавшись полученной командой. Для этого перейдем на хост с IP-адресом 178.20.157.229 и наберем в терминале:
$ docker swarm join --token SWMTKN-1-1qtzfzt0hsu84aydx6c9s8wscq7b4le8y7tnkiqufjbtht6xci-dpp945n10z7sdze5oa4dftm9e 178.20.159.96:2377
В результате, на выходе получили сообщение: «This node joined a swarm as a worker». Это означает, что нода подключена к сети в качестве рабочей.
Попробуем вывести список узлов кластера, как мы это делали раньше на управляющей ноде:
$ docker node ls
Нам это не удалось, поскольку, как указано в выведенном сообщении: «Рабочие узлы нельзя использовать для просмотра или изменения состояния кластера, а только имеющие статус Manager». Следовательно, нам остается вернуться к управляющей ноде или изменить статус текущей рабочей. И это по всей вероятности, поскольку технология допускает наличие нескольких управляющих нод, хотя активной будет только одна из них.
Процедура изменения статуса следующая. Сначала необходимо вывести узел из кластера, а уже потом подключиться к этому же или другому кластеру с нужным статусом. Необходимые для этого токены можно получить на любом управляющем узле. Продемонстрируем это на практике.
Сначала получим токен для «менеджера» на управляющем узле:
$ docker swarm join-token manager
Для получения токена для рабочей ноды команда будет выглядеть следующим образом:
$ docker swarm join-token --quiet worker
Здесь мы воспользовались параметром quiet worker для возможности вывода только токена без команды.
Теперь вернемся к рабочей ноде и выведем ее из нашей сети:
$ docker swarm leave
Получили сообщение: «Нод вышел из сети».
Теперь воспользуемся токеном для «менеджера». Введем ответную команду:
$ docker swarm join --token SWMTKN-1-1qtzfzt0hsu84aydx6c9s8wscq7b4le8y7tnkiqufjbtht6xci-12ipx4ktep1bol9v2y1hics0d 178.20.159.96:2377
Судя по сообщению на выходе, наш текущий узел получил статус управляющего. Теперь снова попробуем ввести команду для просмотра списка узлов кластера:
$ docker node ls
И нам это удалось. Узел получил один из управляющих статусов под названием Reachable. И это нас вполне устраивает. Теперь мы можем из этой машины делать любые запросы в систему. В то же время, она может выполнять функции рабочей ноды, позволяя запуск рабочих сервисов на своих мощностях. Но при желании мы можем этого избежать, запретив выполнение «рабочих» функций. Это можно сделать с помощью следующей команды:
$ docker node update --availability drain <ім`я хоста>
В этом случае узел из статуса Active переходит в статус Drain и все рабочие сервисы перестают на нем запускаться.
Возвратим текущему узлу статус worker и перейдем к стадии запуска сервисов.
Запуск, развертывание и управление сервисами в пределах кластера
Запуск сервисов можно производить отдельно в ручном режиме, а также запускать стеки сервисов с использованием технологии Docker Stack, обеспечивающей интеграцию Docker Swarm и Docker Compose. В этом случае контейнеры сервисов, описанных в Docker Compose, запускаются на всех физических нодах кластера. Рассмотрим поочередно работу с сервисами в каждом режиме. Обращаем внимание, что в режиме Swarm основным средством для управления сервисами является команда docker service.
Ручное управление отдельными сервисами
Запустим одну копию сервиса с именем web, предусматривающий развертывание веб-сервера Nginx из соответствующего шаблона. Для этого введем на управляющем узле следующую команду:
$ docker service create --replicas 1 --name web nginx:alpine
Согласно полученному сообщению на выходе – «verify: Service converged», сервис запущен успешно.
Просмотрим список запущенных сервисов в кластере:
$ docker service ls
Сервис запустился на базе одного контейнера. Просмотрим информацию об узле, на котором был запущен контейнер:
$ docker service ps web
По всей видимости, в столбце Node выведено название узла – «dedicated». Напомним, что в нашем кластере есть два узла с указанным именем, что несколько усложняет задачу определения имени конкретного хоста.
Для получения более подробной информации о созданном сервисе воспользуемся следующей командой:
$ docker service inspect web
Теперь мы получили более полную информацию о программном окружении запущенного сервиса.
В одной из предыдущих статей мы создавали веб-страницу на текущем хосте и поэтому проверить, работает ли запущенный нами веб-сервер. Для этого введем в адресной строчке браузера его адрес:
Как можно убедиться, что веб-сервер nginx успешно работает, поскольку мы можем просматривать содержимое веб-страниц.
Теперь попробуем реализовать самый простой вариант масштабирования сервиса. Для этого увеличим количество реплик для уже запущенного процесса с именем web. Введем в терминале:
$ docker service scale web=2
В результате мы получили сообщение о запуске уже двух задач. Просмотрим обновленный список задач сервиса с помощью соответствующей команды:
$ docker service ps web
Итак, действительно запущены две задачи с именами web.1 и web.2. Выясним, какой из них запущен на текущем (управляющем) хосте, а какой на хосте со статусом worker.
Перейдем на рабочий узел и введем в терминале:
$ docker ps
Мы получили информацию о id контейнере, порте и имени задачи – web.2. то означает, что на управляющем узле запущена задача с именем web.1. Но, если бы мы запретили выполнять ему «рабочие» функции, то обе задачи выполнялись бы на едином рабочем узле.
Мы можем удалить запущенный сервис из кластера. Введем ответную команду на управляющей ноде:
$ docker service rm web
Снова просмотрим список сервисов:
$ docker service ls
Он пуст. Это означает, что задачи уже не выполняются на машинах.
Режим Swarm service stacks
Запустим стек сервисов, предварительно опишем в файле docker-compose-swarm.yml. Будут запущены сразу два сервиса – web и redis, каждый из которых будет иметь свою конфигурацию. Введем в терминале:
$ nano docker-compose-swarm.yml
Вставим в файл следующий код:
version: '3.7' services: web: deploy: replicas: 1 image: nginx:alpine ports: - "8080:8080" redis: deploy: replicas: 1 image: redis:latest
Сохраним внесенные изменения и выйдем из редактора. Для возможности воспользоваться технологией Docker Stack используем соответствующую команду для создания, запуска и развертывания стека сервисов, в котором именем new_app назван весь стек сервисов:
$ docker stack deploy --compose-file docker-compose-swarm.yml new_app
По результатам ее выполнения была создана сеть связи с именем new_app_default и два сервиса – new_app_redis и new_app_web.
Убедимся в наличии стека сервисов с именем new_app с помощью команды:
$ docker stack ls
Итак, в определенном стеке запущено два сервиса. Просмотрим список задач в стеке:
$ docker stack ps new_app
Просмотрим информацию о нодах, на которых запущены сервисы стека new_app:
$ docker stack services new_app
Просмотрим данные о сервисе new_app_redis:
$ docker service ps new_app_redis
Проверим функциональность сервиса с именем web с помощью браузера:
Итак, сервис работает.
Теперь мы можем удалить стек сервисов new_app с помощью соответствующей команды:
$ docker stack rm new_app
Стек услуг успешно удален.
Итоги
Мы рассмотрели основные концепции очередного плагина для Docker Engine под названием Swarm, позволяющего управлять разветвленными кластерами Docker-узлов. Еще больший выигрыш получается от сочетания механизмов Swarm и Compose, позволяющих управлять стеками сервисов в пределах всего кластера. Этот гибридный механизм получил название Docker Stacks, работа с которым также была нами продемонстрирована.
Планируете использовать Docker? Можем для Вас предложить облачный сервер с Docker в Украине или в Польше. Автоматическая установка Debian 12 вместе с Docker Hub через несколько минут после выбора шаблона, ежедневные бекапы, круглосуточная служба поддержки.
Подписывайтесь на наш телеграм-канал https://t.me/freehostua, чтобы быть в курсе новых полезных материалов.
Смотрите наш канал Youtube на https://www.youtube.com/freehostua.
Мы в чем-то ошиблись, или что-то пропустили?
Напишите об этом в комментариях на сайте и в телеграм-канале. Мы с удовольствием ответим и обсудим Ваши замечания и предложения.
Дата: 28.07.2023 Автор: Евгений
|
|
Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:
comments powered by Disqus