• База знань
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Стаття також доступна російською (перейти до перегляду).

Вступ

Інтегрований у 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

Використання утиліти iptables

Тут ми використали IP-адреси нод кластеру: 178.20.159.96 – адреса поточного хоста, котрий буде лідером; 178.20.157.229 – адреса хоста, котрий стане робочим нодом або ворком.

Підготовка робочого вузла

Розгорнемо систему Docker. Для цього наберемо в терміналі:

$ apt install docker.io

Інсталаця Docker

Підтвердимо виділення додаткових 293 Mb та продовжимо процес розгортання системи.

Процес інсталяції Docker

Процес інсталяції Docker

Відкриємо порти та протоколи так само, як ми зробили на першому хості:

$ iptables -N swarm
         ...
$ iptables -A swarm -j DROP

Відкриття потртів через утиліту iptables

Отже, хост – майбутній ворк, налаштовано. Тепер перейдемо до ініціалізації кластеру.

Включення swarm-режиму

Режим включається одразу ж після його ініціалізації за допомогою команди docker swarm init, котра має власний набір параметрів для можливості вказати відкриту IP-адресу управляючого вузла та / або пул IP-адрес для глобальної мережі. За замовченням Docker Swarm використовує пул адрес 10.0.0.0/8 для оверлейних мереж. Зміна пула може знадобитися у випадку наявності мережевих конфліктів. Відкрита IP-адреса повинна призначатися мережевому інтерфейсу, котрий доступний операційній системі хоста. Усі ноди кластера повинні будуть під'єднуватися до лідера саме по ній. Щоб не помилитися у визначенні IP-адреси управляючої ноди, можна скористатися наступною командою:

$ ifconfig

Використання утиліти ifconfig

Можна переконатися, що IP-адреса 178.20.159.96, котра вказана для інтерфейсу eth0, є корректною. Вкажемо саме її для нашої управляючої ноди за допомогою параметру advertise-addr:

$ docker swarm init --advertise-addr 178.20.159.96

IP для управляючої ноди

Судячи з повідомлення на виході команди, режим 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

Розгортання веб-серверу Nginx.

Згідно отриманого повідомлення на виході – «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-compose-swarm.yml

Збережемо внесені зміни та вийдемо з редактора. Для можливості скористатися технологією 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

Перегляд інформації про сервіс new_app_redis

Перевіримо функціональність сервісу із ім'ям web за допомогою браузера:

Перевірка роботи веб-проекту

Отже, сервіс працює.

Тепер ми можемо видалити стек сервісів new_app за допомогою відповідної команди:

$ docker stack rm new_app

Видалення стеку сервісів 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
navigate
go
exit
Дякуємо, що обираєте FREEhost.UA