Сценарії використання service mesh

Сценарії використання service mesh

Прим. перев.: автор цієї статті (Luc Perkins) — developer advocate в організації CNCF, яка є домом для таких Open Source-проектів, як Linkerd, SMI (Service Mesh Interface) та Kuma (до речі, ви теж замислювалися, чому в цьому списку немає Istio?). .). В черговий раз намагаючись принести в DevOps-спільноту краще розуміння в модний хайп під назвою "service mesh", він наводить 16 характерних можливостей, які надають подібні рішення.

Сьогодні сервісна сітка ― одна з найгарячіших тем у галузі програмної інженерії (і по праву!). Я вважаю цю технологію неймовірно перспективною і мрію стати свідком її поширення (звичайно, коли це має сенс). Проте вона досі оточена ореолом таємничості для більшості людей. При цьому навіть ті, хто добре знайомий з нею, нерідко не можуть сформулювати її плюси і що саме вона є (включаючи і вашого покірного слугу). У статті я спробую виправити ситуацію, перерахувавши різні сценарії використання "сервісних сіток"*.

* Прим. перекл.: тут і далі у статті використовуватиметься саме такий переклад («сервісна сітка») для нового терміну service mesh.

Але спершу хочу зробити кілька зауважень:

  • Я ніколи не працював із сервісними сітками і не використовував їх поза проектами, затіяними заради власної освіти. З іншого боку, саме я написав купу документації для внутрішньої service mesh компанії Twitter у 2015 році (тоді вона ще навіть не називалася «сервісною сіткою») і брав участь у розробці сайту та документації для Linkerdтак що це щось означає.
  • Мій список — зразковий та неповний. Цілком можливі невідомі мені сценарії використання, і згодом, напевно, виникнуть нові варіанти, у міру розвитку технології та зростання її популярності.
  • У той самий час далеко ще не кожна існуюча реалізація service mesh підтримує всі перелічені випадки використання. Тому мої вирази на кшталт "service mesh може ..." слід читати як "окремі, а можливо, і всі популярні реалізації service mesh можуть ...".
  • Порядок прикладів немає жодного значення.

Короткий список:

  • виявлення сервісів;
  • шифрування;
  • автентифікація та авторизація;
  • балансування навантаження;
  • circuit breaking;
  • автомасштабування;
  • канаркові розгортання;
  • синьо-зелені розгортання;
  • перевірка здоров'я;
  • load shedding;
  • дзеркальне трафіку;
  • ізоляція;
  • обмеження частоти запитів, повторні спроби та тайм-аути;
  • телеметрія;
  • аудит;
  • візуалізація.

1. Виявлення сервісів

TL;DR: Підключайтеся до інших сервісів у мережі за допомогою простих імен.

Сервіси повинні мати можливість автоматично знаходити один одного за допомогою адекватних імен ― наприклад, service.api.production, pets/staging або cassandra. Хмарні середовища відрізняються своєю еластичністю, і одним ім'ям може ховатися безліч екземплярів сервісу. Зрозуміло, що в такій ситуації фізично неможливо захардкодити всі IP-адреси.

Плюс до всього, коли один сервіс знаходить інший, він повинен мати можливість надсилати запити до цього сервісу, не побоюючись, що вони опиняться на вході у його непрацюючого екземпляра. Іншими словами, service mesh має стежити за працездатністю всіх екземплярів сервісів та підтримувати список хостів у максимально актуальному стані.

Кожна служба mesh реалізує механізм виявлення сервісів по-своєму. На даний момент найпоширенішим способом є делегування зовнішніх процесів на кшталт DNS Kubernetes. Минулого року в Twitter для цих цілей ми використовували систему імен Фінал. Крім того, технологія service mesh уможливлює появу користувальницьких механізмів іменування (хоча я ще не зустрічав жодної реалізації SM з таким функціоналом).

2. Шифрування

TL;DR: Позбавтеся незашифрованого трафіку між сервісами і нехай цей процес буде автоматизованим і масштабованим.

Приємно усвідомлювати, що зловмисники не можуть поринути у вашу внутрішню мережу. Мережеві екрани чудово справляються із цим. Але що станеться, якщо хакер все ж таки проникне всередину? Він зможе робити з внутрішньосервісним трафіком все, що забажає? Давайте сподіватися, що цього все ж таки не станеться. Для того, щоб запобігти подібному сценарію, слід реалізувати мережу з нульовою довірою (zero-trust), в якій весь трафік між сервісами зашифрований. Більшість сучасних сервісних сіток домагаються цього за допомогою взаємного TLS (Mutual TLS, mTLS). У деяких випадках mTLS працює в цілих хмарах і кластерах (думаю, і міжпланетні комунікації колись будуть влаштовані аналогічно).

Звичайно, для mTLS service mesh необов'язкова. Кожен сервіс може сам подбати про своє TLS, але це означає, що потрібно буде знайти спосіб генерувати сертифікати, розподіляти їх по хостах сервісу, включати додаток код, який завантажуватиме ці сертифікати з файлів. Так, ще не забудьте про оновлення цих сертифікатів через певні часові відтинки. Сервісні сітки автоматизують mTLS за допомогою систем типу SPIFFE, які, у свою чергу, автоматизують процес випуску та ротації сертифікатів.

3. Аутентифікація та авторизація

TL;DR: Встановлюйте, хто є ініціатором запиту, та визначайте, що їм дозволено робити ще до того, як запит досягне сервісу.

Сервіси часто хочуть знати, хто виконує запит (аутентифікація), і, використовуючи цю інформацію, вирішують, що цьому суб'єкту дозволено робити (авторизація). В даному випадку за займенником «хто» можуть ховатися:

  1. Інші послуги. Це називається «автентифікацією peer'а». Наприклад, сервіс web хоче отримати доступ до сервісу db. Сервісні сітки зазвичай вирішують подібні проблеми з допомогою mTLS: сертифікати у разі виступають у ролі необхідного ідентифікатора.
  2. Деякі користувачі-люди. Це називається «автентифікацією запиту». Наприклад, користувач haxor69 хоче придбати нову лампу Сервісні сітки надають різні механізми, наприклад, Веб-токени JSON.

    Багатьом із нас доводилося робити це у коді програми. Надходить запит, ми переглядаємо таблицю users, знаходимо користувача та порівнюємо пароль, потім перевіряємо стовпець permissions і т.д. У випадку служби mesh це відбувається ще до того, як запит досягне сервісу.

Після того, як ми встановили, від кого надійшов запит, потрібно визначити, що даному суб'єкту дозволено робити. Деякі service mesh'і дозволяють задавати базові політики (про те, хто і що може робити) у вигляді YAML-файлів або в командному рядку, тоді як інші пропонують інтеграцію з фреймворками на кшталт Відкрийте агент політики. Кінцева мета – домогтися того, щоб ваші сервіси приймали будь-які запити, сміливо припускаючи, що вони виходять із надійного джерела и дія ця дозволена.

4. Балансування навантаження

TL;DR: Розподільте навантаження за примірниками сервісу за певним шаблоном.

«Сервіс» у складі сервісної секті дуже часто складається з безлічі ідентичних екземплярів. Наприклад, сьогодні сервіс cache складається з 5 копій, а завтра їх кількість може зрости до 11. Запити, що направляються в cache, повинні розподілятися відповідно до певної мети. Наприклад, мінімізувати затримку або максимізувати можливість потрапити на працездатний екземпляр. Найчастіше використовується алгоритм кругового обслуговування (Round-robin), але існує й безліч інших - наприклад, метод зважених (Weighted) запитів (можна вибрати кращі цілі), кільцеве (кільце) хешування (використання узгодженого хешування для upstream-хостів) або метод найменшого числа запитів (перевага надається екземпляру з найменшим числом запитів).

Класичні балансувальники мають інші функції, такі як кешування HTTP і захист від DDoS, але вони не дуже актуальні для трафіку типу east-west (тобто для трафіку, поточного в межах датацентру ― прим. перекл.)(типова область застосування service mesh). Звичайно, не обов'язково використовувати service mesh для балансування навантаження, проте вона дозволяє задавати і контролювати політики балансування для кожного сервісу з централізованого шару, що управляє, тим самим усуваючи необхідність запускати і налаштовувати окремі балансувальники в мережевому стеку.

5. Розрив ланцюга (circuit breaking)

TL;DR: Зупиняйте трафік до проблемного сервісу та контролюйте збитки за найгірших сценаріїв.

Якщо з якоїсь причини сервіс не справляється з трафіком, Service Mesh надає кілька варіантів вирішення цієї проблеми (про інші буде розказано у відповідних розділах). Circuit breaking - це найжорсткіший варіант відключення сервісу від трафіку. Однак сам по собі він не має сенсу, необхідний запасний план. Може передбачатися протитиск (протитиск) на сервіси, що виконують запити (тільки не забудьте налаштувати свою service mesh для цього!), або, наприклад, фарбування статус-сторінки в червоний колір і перенаправлення користувачів на черговий варіант сторінки з «китом, що падає» («Twitter is down»).

Сервісні сітки дозволяють не тільки визначати, коли піде відключення та що за цим піде. У разі «коли» може включати будь-яку комбінацію заданих параметрів: загальна кількість запитів за певний період, кількість паралельних підключень, pending-запросы, активні повторні спроби тощо.

Ви навряд чи захочете зловживати circuit breaking'ом, але приємно усвідомлювати, що є резервний план на крайній випадок.

6. Автомасштабування

TL;DR: Збільшуйте або зменшуйте кількість екземплярів сервісу в залежності від заданих критеріїв.

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

Наприклад, Kubernetes масштабує сервіси залежно від використання pod'ами CPU та пам'яті. (див. нашу доповідь «Автомасштабування та управління ресурсами у Kubernetes" - прим. перев.)Але якщо ви вирішите проводити масштабування на основі будь-якого іншого показника (у нашому випадку - пов'язаного з трафіком), знадобиться спеціальна метрика. Керівництво на кшталт такого показує, як зробити це за допомогою Посланець, Істіо и ПрометейАле сам процес досить складний. Ми б хотілося, щоб service mesh його спростила, дозволивши просто задавати умови на кшталт «збільшити кількість екземплярів сервісу auth, якщо кількість запитів, що очікують виконання, перевищуватиме граничне значення протягом хвилини».

7. Канаркові розгортання

TL;DR: Випробуйте нові функції або версії сервісу на підмножині користувачів.

Скажімо, ви розробляєте якийсь SaaS-продукт і маєте намір викотити його нову круту версію. Ви протестували її у staging, і вона чудово відпрацювала. Але все ж таки долають певні побоювання щодо її поведінки в реальних умовах. Іншими словами, потрібно перевірити нову версію на реальних завданнях, не ризикуючи при цьому довірою користувачів. Канаркові розгортання відмінно підходять для цього. Вони дозволяють продемонструвати нову функцію деякому підмножині користувачів. Це підмножина може складатися з найлояльніших користувачів або тих, хто працює з безкоштовною версією продукту, або користувачів, які виявили бажання побути «піддослідними кроликами».

Service mesh'і реалізують це, дозволяючи вказати критерії, що визначають, хто і яку версію програми побачить, та відповідним чином маршрутизуючи трафік. При цьому самих сервісів нічого змінюється. Версія 1.0 сервісу вважає, що всі запити надходять від користувачів, які саме її і повинні побачити, а версія 1.1 те саме вважає стосовно своїх користувачів. А ви, тим часом, можете змінювати відсоток трафіку між старою та новою версією, перенаправляючи зростаючу кількість користувачів на нову, якщо вона працює стабільно і ваші «піддослідні» дають добро.

8. Синьо-зелені розгортання

TL;DR: Викочуйте нову круту функцію, але будьте готові негайно повернути все назад.

Сенс синьо-зелених розгортань у тому, щоб викотити новий «синій» сервіс, запустивши його паралельно із старим, «зеленим». Якщо все піде гладко і новий сервіс добре зарекомендує себе, то старий можна буде поступово відключити. (На жаль, колись і цей новий «синій» сервіс повторить долю «зеленого» і зникне…) Синьо-зелені розгортання відрізняються від канаркових тим, що нова функція охоплює відразу всіх користувачів (а чи не частина); сенс тут у тому, щоб мати напоготові «запасну гавань», якщо раптом щось піде не так.

Service mesh'і пропонують дуже зручний спосіб тестування «синього» сервісу та миттєвого перемикання на робочий «зелений» у разі несправностей. Не кажучи вже про те, що принагідно вони дають масу інформації (див. пункт «Телеметрія» нижче) про роботу «синього», яка допомагає зрозуміти, чи готовий той до повноцінної експлуатації.

Прим. перев.: Докладніше про різні стратегії розгортання в Kubernetes (включаючи згадані canary, blue/green та інші) можна почитати в цієї статті.

9. Перевірка здоров'я

TL;DR: Слідкуйте за тим, які екземпляри сервісів працездатні, і реагуйте на ті з них, які такими перестають.

Перевірка здоров'я (health check) допомагає прийняти рішення про те, чи готові екземпляри сервісу приймати та обробляти трафік. Наприклад, у разі HTTP-сервісів перевірка здоров'я може виглядати як GET-запит на endpoint /health. відповідь 200 OK означатиме, що екземпляр здоровий, будь-який інший – що він не готовий приймати трафік. Service mesh'і дозволяють вказувати як спосіб, яким перевірятиметься працездатність, так і частоту, з якою ця перевірка проводитиметься. Цю інформацію можна використовувати для інших цілей — наприклад, для балансування навантаження і circuit breaking'а.

Таким чином, перевірка здоров'я є не самостійним сценарієм використання, а зазвичай використовується для досягнення інших цілей. Також, залежно від результатів health check'ів, можуть знадобитися зовнішні (відносно інших цілей сервісних сіток) дії: наприклад, оновлювати сторінку стану, створювати issue на GitHub або заповнювати тикет JIRA. І service mesh пропонує зручний механізм для автоматизації всього цього.

10. Перекидання навантаження (load shedding)

TL;DR: Перенаправляйте трафік у відповідь на тимчасовий сплеск у використанні.

Якщо якийсь сервіс перевантажений трафіком, ви можете тимчасово перенаправити частину цього трафіку в інше місце (тобто «скинути», «перелити») (shed) його туди). Наприклад, у резервний сервіс чи дата-центр, чи у постійний прес topic. В результаті, сервіс продовжить обробляти частину запитів замість того, щоб впасти і припинити обробляти взагалі все. Скидання навантаження краще, ніж розрив ланцюга, але все одно небажано зловживати ним. Воно дозволяє запобігти каскадним збоям, в результаті яких падають downstream-сервіси.

11. Розпаралелювання/дзеркалювання трафіку

TL;DR: Надсилайте один запит відразу в кілька місць.

Іноді виникає потреба надіслати запит (або деяку вибірку запитів) відразу в кілька сервісів. Характерний приклад ― відправлення частини production-трафіку до staging-сервісу. Основний веб-сервер production'а надсилає запит до нижчестоящого сервісу products.production і лише до нього. А service mesh інтелектуально копіює цей запит і надсилає його на products.staging, про що веб-сервер навіть не підозрює.

Ще один пов'язаний сценарій використання сервісної сітки, який можна реалізувати поверх розпаралелювання трафіку, ― це регресійне тестування. Воно передбачає відправлення тих самих запитів різним версіям сервісу і перевірку того, чи поводяться всі версії себе однаково. Мені поки що не зустрічалася реалізація service mesh з інтегрованою системою регресійного тестування на зразок Діффіале сама ідея здається перспективною.

12. ізоляція

TL;DR: Розбивайте свою службу mesh на міні-мережі.

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

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

13. Обмеження частоти запитів, повторні спроби та тайм-аути

TL;DR: Більше не треба включати в кодову базу нагальні завдання з управління запитами.

Всі ці речі можна було б розглядати як окремі випадки використання, але я вирішив об'єднати їх через одну загальну особливість: вони переймають на себе завдання з управління життєвим циклом запитів, які зазвичай відпрацьовують бібліотеки додатків. Якщо ви розробляєте веб-сервер на Ruby on Rails (не інтегрований з service mesh), який виконує запити до backend-сервісів через gRPC, додаток повинен сам вирішувати, що робити, якщо N запитів завершаться невдачею. Також доведеться з'ясовувати, який обсяг трафіку здатні будуть обробити ці сервіси та за'hardcode'ити ці параметри за допомогою спеціальної бібліотеки. Плюс до всього, додаток повинен буде вирішувати, коли настав час здатися і дозволити запиту протухнути (по timeout). І для того, щоб змінити будь-який з наведених вище параметрів, веб-сервер доведеться зупинити, переконфігурувати і запустити заново.

Передача цих завдань сервісній сітці означає не лише те, що розробникам сервісів не потрібно буде думати про них, а й те, що їх можна буде розглядати більш глобальним чином. Якщо використовується складний ланцюжок сервісів, скажімо, A -> B -> C -> D -> E, необхідно враховувати весь життєвий цикл запиту. Якщо стоїть завдання продовжити тайм-аути в сервісі С, логічно робити це все разом, а не частинами: оновивши код сервісу і чекаючи, поки pull request буде прийнятий і CI-система розгорне оновлений сервіс.

14. Телеметрія

TL;DR: Збирайте всю необхідну (і не зовсім) інформацію від сервісів.

Телеметрія ― це загальний термін, що включає метрики, розподілене трасування і логи. Сервісні сітки пропонують механізми для збирання та обробки всіх трьох типів даних. Тут все стає трохи розпливчастим, оскільки кількість можливих варіантів надто велика. Для збору метрик є Прометей та інші інструменти, для збирання логів можна використовувати вільно, Локі, вектор та ін. (наприклад, ClickHouse з нашим loghouse для K8s - прим. перев.)для розподіленого трасування є Єгер і т.п. Кожна служба mesh може підтримувати одні інструменти і не підтримувати інші. Цікаво буде подивитись, чи зможе проект Open Telemetry забезпечити деяку конвергенцію.

У даному випадку перевага технології service mesh в тому, що sidecar-контейнери можуть, в принципі, зібрати всі перераховані вище дані зі своїх сервісів. Іншими словами, у своє розпорядження ви отримуєте єдину систему збору телеметрії, і служба mesh може обробляти всю цю інформацію різними способами. Наприклад:

  • tail'ити логи від якогось сервісу в CLI;
  • відстежувати обсяг запитів із панелі моніторингу service mesh;
  • збирати розподілені трасування та перенаправляти їх у систему на кшталт Jaeger.

Увага, суб'єктивне судження: Власне кажучи, телеметрія - це та область, сильне втручання сервісної сітки в яку небажано. Збір базової інформації та відстеження на льоту деяких «золотих метрик» на кшталт відсотка успішних запитів і затримок ― це нормально, але давайте сподіватися, що ми не станемо свідками виникнення таких Франкенштейн-стеків, які спробують замінити спеціалізовані системи, деякі з яких вже добре себе зарекомендували та добре вивчені.

15. Аудит

TL;DR: Той, хто забуває уроки історії, приречений їх повторювати.

Аудит – це мистецтво спостереження за важливими подіями в системі. У випадку service mesh це може означати відстеження того, хто робив запити до конкретних endpoint'ів певних сервісів або скільки разів за останній місяць відбувалася певна подія, яка стосується безпеки.

Зрозуміло, що аудит дуже тісно пов'язаний із телеметрією. Різниця ж полягає в тому, що телеметрія зазвичай асоціюється з такими речами, як продуктивність та технічна стрункість, тоді як аудит може мати відношення до юридичних та інших питань, що виходять за рамки строго технічної сфери (наприклад, відповідність вимогам GDPR – Загального регламенту ЄС захисту даних).

16. Візуалізація

TL;DR: Хай живе React.js ― невичерпне джерело химерних інтерфейсів.

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

Робота в сервіс-орієнтованому середовищі пов'язана з набагато сильнішим когнітивним навантаженням у порівнянні з Його Величністю Монолітом. Тому когнітивний тиск слід знижувати за будь-яку ціну. Банальний графічний інтерфейс для service mesh з можливістю натиснути кнопку і отримати потрібний результат може мати вирішальне значення для зростання популярності цієї технології.

Не були включені до списку

Спочатку я мав намір включити до списку ще кілька сценаріїв використання, але потім вирішив не робити цього. Ось вони разом із причинами мого рішення:

  • Мульти-датацентр. У моєму уявленні це не стільки сценарій використання, скільки вузька та конкретна сфера застосування сервісних сіток або деякого набору функцій на кшталт виявлення сервісів.
  • Ingress та egress. Це пов'язана область, але я обмежив себе (можливо штучно) сценарієм використання «трафік east-west». Ingress і egress заслуговують на окрему статтю.

Висновок

На цьому поки що все! Знову ж таки, цей список дуже умовний і, швидше за все, неповний. Якщо вам здається, що я щось упустив, або в чомусь помилився, звертайтеся до мене в Twitter (@lucperkins). Будь ласка, дотримуйтесь правил пристойності.

PS від перекладача

Як основу для великої ілюстрації до статті взято зображення зі статті «What is a Service Mesh (і коли use one)?»(Автор - Gregory MacKinnon). На ньому показано, як частина функціональності з додатків (зеленим кольором) перейшла до service mesh, що забезпечує взаємозв'язок між ними (блакитний колір).

Читайте також у нашому блозі:

Джерело: habr.com

Купити надійний хостинг для сайтів із захистом від DDoS, VPS VDS сервери 🔥 Купити надійний хостинг для сайтів із захистом від DDoS, VPS VDS сервери | ProHoster