Як використовувати балансири навантаження ALB і NLB за допомогою управління контейнерними послугами Amazon EC2

Балансування навантаження додатків (ALB) і балансування мережевого навантаження (NLB) – це балансири навантаження другого покоління від Amazon Web Services (AWS), комерційної публічної хмарної платформи.

У цій статті ми розглянемо, як повною мірою скористатися перевагами їх нової функціональності, наприклад, маршрутизації трафіку до контейнеризованих програм Docker, що працюють у хмарі.

Ще однією з найбільш цікавих і корисних нових функцій, доступних як для балансування навантаження додатків, так і для балансування навантаження мережі, є можливість відправляти мережевий трафік в динамічні порти. Для балансувальника навантаження попереднього покоління традиційна схема портів була наступною: на кожному екземплярі використовуваної групи серверних серверів бекенда, розташованої за балансиром навантаження, була запущена ідентична копія програми, що працює на відомому статичному номері порту. При цьому завдання балансира навантаження попереднього покоління обмежувалося тільки рівномірним розподілом будь-яких отриманих запитів на один і той же номер порту між групою серверних серверів (див. малюнок 1).

Малюнок 1. Традиційна портова схема для балансирів навантаження попереднього покоління обмежувалася лише рівномірним розподілом будь-яких отриманих запитів на один і той же номер порту між групою серверів бекенда.

Однак з появою епохи контейнерних додатків Docker і початком активного використання стратегій упаковки бункерів для запуску декількох додатків на одному екземплярі Amazon EC2, спосіб організації багатьох архітектур програмного забезпечення також змінився. У цьому випадку один екземпляр Amazon EC2 може працювати з декількома контейнерами, кожному з яких випадковим чином був призначений порт (див. малюнок 2). Ці номери портів не є статичними. Контейнерам застосунків може бути присвоєно інший номер порту після їх зупинки та перезапуску.

Рисунок 2. З новим підходом до архітектури додатків один екземпляр Amazon EC2 може працювати з декількома контейнерами, кожному з яких випадковим чином присвоєно динамічний номер порту.

Як балансування навантаження застосунків, так і балансування навантаження мережі підтримують цей новий динамічний шаблон порту, використовуючи функціональність цільової групи. Цей хмарний ресурс AWS дозволяє відстежувати список портів, які отримують мережевий трафік по кожному екземпляру і, отже, надає балансувальнику навантаження можливість рівномірно розподіляти трафік по портах.

Таким чином, у наведеному вище прикладі, проілюстрованому на малюнку 11, балансатор навантаження мережі відправить 40% мережевого трафіку в перший екземпляр, в якому контейнери розміщуються на двох портах, а решта 60% мережевого трафіку буде відправлена в інший екземпляр, який має три відкриті порти.

У свою чергу, Application Load Balancer, який виконує маршрутизацію на основі HTTP на прикладному шарі мережевої моделі OSI, в такій конфігурації буде розподіляти 50% всього мережевого трафіку в одній цільовій групі, що відповідає шаблону шляху “/api/users*” між двома динамічними портами, а для іншої цільової групи з шаблоном шляху “/api/auth*”, третина мережевого трафіку буде розподілена між трьома іншими портами (див. рис. 3).

Малюнок 3. Приклад розподілу мережного трафіку балансувачем навантаження застосунків для веб-застосунку, який використовує кілька динамічних портів у різних екземплярах.

Інтеграція балансування навантаження додатків та балансира мережевого навантаження з контейнерною службою Amazon EC2

Завдяки динамічній підтримці портів ALB та NLB ідеально підходять для маршрутизації мережевого трафіку в службах управління контейнерами. Існує безшовна інтеграція між балансоутримувачами навантаження другого покоління та контейнерною службою Amazon EC2 (ECS).

ECS – це керована система оркестровки для платформи хмарних обчислень Amazon Web Services, яка використовується для розгортання та експлуатації контейнеризованих додатків Docker у кількох випадках. Він розроблений, щоб забезпечити простий спосіб підключення широкої екосистеми послуг AWS до контейнерів.

Розгортання контейнеризованого застосунку за балансом навантаження застосунку або балансатором навантаження мережі починається з самого застосунку. Візьмемо, наприклад, простий веб-додаток Node.js який підключається до порту 8081 і прослуховує весь трафік, який надходить на цей порт (див. малюнок 4). Якби цей застосунок був розгорнутий без контейнерів, він працював би в декількох випадках, і балансир навантаження буде направляти весь трафік до статичного порту 8081 на кожному екземплярі.

Малюнок 4. Приклад простого вузла.js веб-застосунок, який підключається до порту 8081 і прослуховує весь трафік, який надходить на цей порт.

Але, оскільки ми вбудовуємо цю програму в контейнер Docker, у нас є можливість використовувати функціональність Docker для зіставлення портів у контейнері з різними портами на хості, де працює контейнер. Це досягається за допомогою простої конфігурації, яка передається Docker при запуску контейнера. У контейнерній службі Amazon EC2 ми можемо використовувати ресурс під назвою Визначення завдання, щоб призначити потрібну нам конфігурацію. “Визначення завдання” – це легка версія документа метаданих, яка повідомляє службі керування контейнерами ECS, з якими параметрами запускати контейнер Docker. Приклад “Визначення завдання”, який ми можемо використовувати для запуску веб-застосунку на Node.js, описаний трохи вище, показаний на малюнку 5.

Малюнок 5: Зразок “Визначення завдання” для запуску веб-застосунку на вузлі.js “упакований” у контейнер Docker.

Як бачите, контейнерний порт вказаний як 8081. Це той самий порт, до якого прив’язаний код програми. Однак, хост-порт встановлений на нуль. Це говорить програмному забезпеченню Docker, що нам не потрібен конкретний статичний порт на хості. Замість цього Docker може використовувати випадковий динамічний порт на хості і перенаправляти трафік, який надходить на цей порт, в порт 8081 всередині контейнера.

За допомогою цієї конфігурації кілька екземплярів контейнера можна розгорнути на одному комп’ютері (див. малюнок 6).

Малюнок 6. Запустіть кілька екземплярів контейнерів на одному комп’ютері

Як ми бачимо, будь-який мережевий трафік, що надходить на порт 32768, направляється в порт 8081 в одному контейнері, і будь-який мережевий трафік, що надходить в порт 33487, направляється в порт 8081 в іншому контейнері.

Таким чином, ресурс визначення завдання з динамічною конфігурацією переадресації портів може бути використаний для запуску служб в контейнерній службі EC2 (див. малюнок 7).

Малюнок 7. Використання ресурсу визначення завдання з конфігурацією динамічного переадресації портів для запуску служб у службі контейнерів EC2

Кожна служба ECS, підключена до балансувальника навантаження, використовує функціональність Цільової групи, яка підтримує автоматичну синхронізацію під час запуску або змінення нового завдання. Цільова група надає список кожного екземпляра та всіх портів, які приймають мережевий трафік у цьому екземплярі (див. рисунок 8).

Малюнок 8. Ресурс цільової команди, який використовує кожну службу ECS, підключену до балансира навантаження, надає список кожного екземпляра та всіх портів, які приймають мережевий трафік у цьому екземплярі

Балансування навантаження застосунків або балансування навантаження мережі, підключений до цільової групи, використовуватиме цей список для вибору екземпляра та порту, до якого буде надіслано мережний трафік.

ALB або NLB використовують цільову групу, щоб вибрати екземпляр і порт, до якого буде надіслано мережний трафік.

Таким чином, весь процес маршрутизації мережевого трафіку в послугах з управління контейнерами виглядає наступним чином:

  1. Клієнтський застосунок ініціює нове підключення до балансувальника навантаження.
  2. Балансир навантаження отримує мережевий трафік і вибирає «ціль» з «Цільової групи», прикріпленої до балансувальника навантаження. Ця “Цільова група” була налаштована Amazon EC2 Контейнерна служба і включає в себе список доступних екземплярів і портів.
  3. Балансування навантаження надсилає мережний трафік до вибраного екземпляра та порту.
  4. Docker приймає мережевий трафік і перенаправляє його в налаштований порт всередині потрібного контейнера.
  5. Додаток, запущений всередині контейнера, отримує мережевий трафік через порт, до якого він прив’язаний.

Висновок

Як балансування навантаження застосунків, так і балансування навантаження мережі розроблені з нуля для сучасної парадигми динамічної конфігурації порту, яка зазвичай використовується при розгортанні сучасних контейнеризованих додатків. Вибір правильного балансувальника навантаження буде залежати від конкретних потреб вашої програми, таких як: чи є мережевий трафік HTTP чи ні, чи потрібно вам наскрізне шифрування SSL /TLS, і чи хочете ви маршрутизувати мережевий трафік на основі хоста та шляху чи ні.

Якщо ви розгортаєте контейнери Docker і використовуєте балансир навантаження для відправки їм мережевого трафіку, Amazon EC2 Container Service надає вам тісну інтеграцію як з балансатором навантаження додатків, так і з балансом навантаження мережі. Завдяки цьому ви можете легко синхронізувати балансири навантаження при запуску, оновленні та зупинці будь-якого з ваших контейнерів.