Ключовим фактором для масштабування балансуючого шару навантаження HTTP є спочатку додати ще один рівень балансування навантаження нижнього рівня (IP або TCP). Цей шар можна створити повністю за допомогою програмного забезпечення з відкритим кодом, хоча ви отримаєте кращі результати, якщо у вас є сучасні маршрутизатори.
Потоки (сесії TCP) повинні бути хешировані за допомогою заголовків, таких як джерела / порти IP та порти TCP, щоб вирішити, до якого фронтеду вони йдуть. Вам також потрібен механізм, щоб переконатися, що коли передній план помирає, він перестає звикати.
Існують різні стратегії, я збираюся окреслити пару, яку я використовував у виробництві на сайтах, що обслуговують мільйони користувачів, так що ви можете отримати ідею. Занадто довго буде пояснювати все детально, але сподіваюся, що ця відповідь дасть вам достатньо інформації / покажчиків, щоб розпочати роботу. Для реалізації цих рішень вам знадобиться хтось, хто справді знає мережу.
Правда, те, що я тут описую, реалізувати набагато складніше, ніж те, що описано в інших відповідях, але це справді найсучасніший, якщо у вас є веб-сайт із високою торгівлею людьми з великими проблемами масштабованості та вимогами щодо доступності понад 99,9% . За умови, що у вас вже є інженер мережевого типу інженер на борту, налаштування та запуск (як у capex, так і opex) коштує менше, ніж прилади для балансування навантажень, і його можна масштабувати далі майже без додаткових витрат (порівняно з придбанням нового, навіть більше дорогий прилад, коли ви переростаєте поточну модель).
Перша стратегія: з брандмауером
Імовірно, у вас є пара маршрутизаторів, на яких підключені ваші Інтернет-провайдери. Ваш Інтернет-провайдер надає 2 посилання (активне / пасивне, використовуючи VRRP). На своїх маршрутизаторах ви також використовуєте VRRP, і ви спрямовуєте трафік, що йде у вашу загальнодоступну мережу, на брандмауер. Брандмауери ( FW 1
і FW 2
нижче) також є активними / пасивними, і вони фільтруватимуть трафік та відправлятимуть кожен потік на здоровий інтерфейсний сервер (ваші балансові навантаження HTTP FE 1
та FE 2
нижче).
+ -------------- + + -------------- +
| Маршрутизатор ISP A | | Маршрутизатор ISP B |
+ -------------- + + -------------- +
| |
== # ====================== # == (громадська мережа)
| |
+ --------------- + + --------------- +
| Ваш маршрутизатор A | | Ваш маршрутизатор B |
+ --------------- + + --------------- +
| |
== # ===== # ========== # ===== # == (приватна мережа RFC 1918)
| | | |
+ ------ + + ------ + + ------ + + ------ +
| FW 1 | | ЗВ 1 | | ЗВ 2 | | FW 2 |
+ ------ + + ------ + + ------ + + ------ +
Мета полягає в тому, щоб потік виглядав так:
- Інтернет-провайдер здійснює маршрутизацію трафіку до вашого IP-адреси до вашого активного маршрутизатора.
- Ваші маршрутизатори направляють трафік на VIP, який використовує адресу RFC 1918 . Цей VIP належить активному брандмауеру, як і VRRP. Якщо ви використовуєте OpenBSD для своїх брандмауерів, тоді ви можете використовувати CARP , не патентовану альтернативу VRRP / HSRP.
- Ваш брандмауер застосовує фільтр (наприклад, "дозволити лише 80 / tcp та 443 / tcp для цієї конкретної IP-адреси").
- Ваш брандмауер також діє як маршрутизатор і пересилає пакети до здорового інтерфейсу.
- Ваш інтерфейс припиняє TCP-з'єднання.
Тепер магія відбувається на кроках 4 і 5, тому давайте докладніше розберемося, що вони роблять.
Ваш брандмауер знає список фронтів ( FE 1
і FE 2
), і він вибере один із них, виходячи з певного аспекту потоку (наприклад, шляхом хешування джерела IP та порту, серед інших заголовків). Але також потрібно переконатися, що він перенаправляє трафік на здоровий інтерфейс, інакше ви будете переробляти трафік. Наприклад, якщо ви використовуєте OpenBSD, ви можете використовувати relayd
. Щоrelayd
це просто: він перевіряє всі ваші інтерфейси (наприклад, надсилаючи їм запит HTTP-зонда), і коли фронтенд здоровий, він додає його до таблиці, яку брандмауер використовує для вибору наступного скаку пакетів заданого потоку. . Якщо інтерфейс не проводить перевірки стану здоров'я, його видаляють зі столу і більше не надсилаються пакети. Під час переадресації пакету на фронтленд все брандмауер робить підміну міняючої MAC-адресою пакета таким чином, щоб він був обраний на фронтенді.
На кроці 5 пакети від користувача отримує ваш балансир завантаження (будь то лак, nginx або інше). На даний момент пакет все ще призначений для вашої загальнодоступної IP-адреси, тому вам потрібно псевдоніми ваших VIP-адрес на інтерфейсі петлі. Це називається DSR (Direct Server Return), оскільки ваші інтерфейси припиняють TCP-з'єднання, і міжмережевий екран між ними бачить тільки симплексний трафік (лише вхідні пакети). Ваш маршрутизатор буде направляти вихідні пакети безпосередньо до маршрутизаторів провайдера. Це особливо добре для HTTP-трафіку, оскільки запити, як правило, менші, ніж відповіді, іноді суттєво. Просто для того, щоб бути зрозумілим: це не є специфікою для OpenBSD і широко використовується на веб-сайтах з високою торгівлею людьми.
Отримав:
- Кінцеві користувачі безпосередньо підключаться до ваших серверів інтерфейсу, оскільки ви використовуєте DSR. Можливо, це вже було так, але якщо цього не було, потрібно переконатися, що вони забезпечені належним чином.
- Якщо ви використовуєте OpenBSD, будьте обережні, що ядро є однопоточним, тому продуктивність одного ядра CPU обмежить пропускну здатність брандмауера. Це може бути проблемою в залежності від вашого типу NIC та швидкості передачі, яку ви бачите. Існують способи вирішення цієї проблеми (докладніше про це нижче).
Друга стратегія: без брандмауера
Ця стратегія є більш ефективною, але важче налаштована, оскільки вона більше залежить від специфіки маршрутизаторів, які у вас є. Ідея полягає в тому, щоб обійти брандмауер вище і дозволити маршрутизаторам виконати всю роботу, яку брандмауер робив.
Вам знадобляться маршрутизатори, які підтримують ACL на порт L3 / L4, BGP та ECMP та маршрутизацію на основі політики (PBR). Тільки маршрутизатори високого класу підтримують ці функції, і вони часто мають додаткові ліцензійні плати за використання BGP. Зазвичай це все-таки дешевше, ніж апаратні балансири навантаження, а також набагато простіше масштабувати. Хороша річ у цих маршрутизаторах високого класу - це те, що вони мають тенденцію до лінійної швидкості (наприклад, вони завжди можуть максимізувати посилання навіть на інтерфейсах 10GbE, оскільки всі рішення, які вони приймають, зроблені апаратно ASIC).
На портах, на яких у вас є посилання на Інтернет-провайдера, застосуйте ACL, який раніше знаходився в брандмауері (наприклад, "дозволяти лише 80 / tcp та 443 / tcp для цієї конкретної IP-адреси"). Потім дозвольте кожному з ваших фронталів підтримувати сеанс BGP разом із маршрутизатором. Ви можете використовувати відмінний OpenBGPD (якщо ваші фронти на OpenBSD) або Quagga . Ваш маршрутизатор передасть трафік на здорові кордони (тому що вони підтримують свої сеанси BGP). Маршрутизатор також буде належним чином відправляти трафік за допомогою PBR.
Удосконалення
- З рішенням пара брандмауера добре, якщо ви можете синхронізувати стан TCP через брандмауері, так що коли один брандмауер виходить з ладу, все перестає плавно переходити на інший. Ви можете досягти цього за допомогою
pfsync
.
- Майте на увазі, що
pfsync
зазвичай удвічі збільшуватиметься частота пакетів ваших брандмауерів.
- HTTP - це протокол без стану, тому це не кінець світу, якщо ви скинете всі з'єднання під час відмови від брандмауера, оскільки ви не використовуєте
pfsync
.
- Якщо ви переростите один брандмауер, ви можете використовувати ECMP на своєму маршрутизаторі, щоб спрямувати трафік на більш ніж пару брандмауерів.
- Якщо ви використовуєте більше однієї пари брандмауера, ви можете також зробити їх активними / активними. Цього можна досягти, якщо брандмауери підтримують сеанс BGP з маршрутизаторами, як і потрібні фронтендам, щоб вони підтримували другу програму без брандмауерів.
Зразок relayd
конфігурації
Дивіться також HOWTO за адресою https://calomel.org/relayd.html
vip = "1.2.3.4" # Ваша загальнодоступна IP-адреса
# (можна мати більше одного, але цього не потрібно)
fe1 = "10.1.2.101"
fe2 = "10.1.2.102"
fe3 = "10.1.2.103"
fe4 = "10.1.2.104" # Ви можете мати будь-яку кількість фронтенів.
int_if = "em0"
table <fe> {$ fe1 повторити 2, $ fe2 повторити 2, $ fe3 повторити 2, $ fe4 повторити 2}
table <fallback> {127.0.0.1}
перенаправлення веб-трафіку {
слухати на $ vip порт 80
тайм-аут сесії 60
маршрут до <fe> перевірити http "/healthcheck.html" дайджест "(sha1sum Healthcheck.html)" інтерфейс $ int_if
}