Сценарии на използване на service mesh

Сценарии на използване на service mesh

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

Днес service mesh ― една от най-горещите теми в областта на софтуерното инженерство (и с право!). Считам, че тази технология е невероятно обещаваща и мечтая да бъда свидетел на нейното широко разпространение (разбира се, когато е смислено). Все пак, тя все още е обвита в ореол на мистерия за повечето хора. В същото време дори тези, които добре се запознават с нея, често имат трудности да формулират нейните предимства и какво точно представлява (включително и вашия любезен слуга). В статията ще се опитам да поправя ситуацията, изброявайки различни сценарии на употреба на „сервизните мрежи“*.

* Бележка на преводача: тук и по-надолу в статията ще се използва именно този превод („сервизна мрежа“) за все още новия термин service mesh.

Но преди всичко искам да направя няколко бележки:

  • Никога не съм работил с сервизни мрежи и не съм ги използвал извън проекти, предприети за собственото ми образование. От друга страна, именно аз съм написал куп документация за вътрешната service mesh на компанията Twitter през 2015 г. (тогава тя дори не се наричаше „сервизна мрежа“) и участвах в разработването на сайта и документацията за Linkerd, така че това нещо означава нещо.
  • Моят списък е ориентировъчен и непълен. Възможно са неизвестни ми сценарии на употреба, и с течение на времето със сигурност ще възникнат нови варианти, с развитието на технологията и нарастващата и популярност.
  • В същото време далеч не всяка съществуваща реализация на service mesh поддържа всички изброени случаи на употреба. Затова моите изрази като „service mesh може…“ трябва да се четат като „отделни, а може би и всички популярни реализации на service mesh могат…”.
  • Порядъкът на примерите няма никакво значение.

Кратък списък:

  • откритие на услуги;
  • шифроване;
  • аутентификация и авторизация;
  • разпределение на натоварването;
  • прекъсване на веригата;
  • автоматично скалиране;
  • канарен деплоймент;
  • синьо-зелени деплойменти;
  • контрол на здравето;
  • отпускане на натоварването;
  • зеркално пренасочване на трафика;
  • изолация;
  • ограничение на частотата на запитите, повторни опити и таймаути;
  • телеметрия;
  • одит;
  • визуализация.

1. Откриване на услуги

TL;DR: Свържете се с други услуги в мрежата чрез простички имена.

Услугите трябва да могат да "намират" една друга автоматично чрез адекватни имена, напр. service.api.production, pets/staging или cassandra. Облачните среди се отличават с тяхната еластичност, и зад едно име може да стоят множество екземпляри на услугата. Ясно е, че в такава ситуация е физически невъзможно да се хардкодят всички IP адреси.

Освен това, когато една услуга намира друга, тя трябва да може да изпраща запитвания до тази услуга, без да се притеснява, че те ще попаднат на входа на нейния неработещ екземпляр. С други думи, service mesh трябва да следи за работоспособността на всички екземпляри на услугите и да поддържа списък с хостове актуален.

Всяка service mesh реализира механизъм за откриване на услуги по свой начин. В момента най-разпространеното решение е делегирането на външни процеси като DNS в Kubernetes. В миналото в Twitter за тези цели използвахме система с имена Finagle. Освен това, технологията 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 Web Tokens.

    Много от нас са правили това в кода на приложението. Приходи заявка, преглеждаме таблицата users, намираме потребителя и сравняваме паролата, след което проверяваме колоната permissions и т.н. В случая с услугата мрежа това се случва още преди заявката да достигне услугата.

След като установим откъде е дошла заявката, трябва да определим какво на конкретния субект е разрешено да прави. Някои услуги мрежи позволяват задаване на базисни политики (относно това кой и какво може да прави) под формата на YAML файлове или в командния ред, докато други предлагат интеграция с рамки като Open Policy Agent. Крайната цел е да накарате вашите услуги да приемат всякакви заявки, смело предполагайки, че те идват от надежден източник и това действие е разрешено.

4. Балансиране на натоварването

TL;DR: Разпределяйте натоварването сред инстанции на услугата по определен шаблон.

Сервисът в състава на сервисна секта често се състои от множество идентични екземпляри. Например, днес сервисът cache се състои от 5 копия, а утре техният брой може да нарасне до 11. Запитванията, насочващи се към cache, трябва да се разпределят в съответствие с определена цел. Например, за минимизиране на забавянето или максимизиране на вероятността да се попадне на работещ екземпляр. Най-често се използва алгоритмът за рунд Робин (Round-robin), но съществуват и много други — например, методът на теглените (weighted) запитвания (възможно е да се изберат предпочитани цели), пръстеновидно (ring) хеширане (използване на консистентно хеширане за upstream хостове) или методът на най-малкото число запитвания (предпочитание се дава на екземпляра с най-малко запитвания). Класическите балансировачи имат и други функции, като HTTP кеширане и защита от DDoS, но те не са особено актуални за трафика тип east-west (т.е. за трафика в рамките на датацентъра ― прим. прев.). (типична област на приложение на service mesh). Разбира се, не е задължително да се използва service mesh за балансировка на натоварването, но тя позволява задаване и контрол на политиките за балансировка за всеки сервис от централизиран управляващ слой, като по този начин елиминира необходимостта от стартиране и настройка на отделни балансировачи в мрежовия стек.

5. Прекъсване на веригата (circuit breaking)

TL;DR: Спирайте трафика към проблемния сервис и контролирайте вредите при най-лошите сценарии.

Ако поради някаква причина сервисът не се справя с трафика, service mesh предоставя няколко решения на този проблем (за други ще бъде говорено в съответните раздели). Circuit breaking е най-крайният вариант за отключване на сервиза от трафика. Но сам по себе си той няма смисъл — необходим е резервен план. Може да се предвиди противодавление

backpressure (към сервизите, които извършват запитвания (само не забравяйте да настроите своята service mesh за това!), или, например, оцветяване на статус страницата в червено и пренасочване на потребителите към друг вариант на страницата с „падащ кит“ („Twitter is down“).) Service mesh позволява не само да се определя,

кога ще последва отключването и ще последва изключване и какво Следва това. В този случай „кога“ може да включва всяка комбинация от зададени параметри: общият брой заявки за определен период, броя на паралелните връзки, изчакващи заявки, активни повторни опити и т.н.

Малко вероятно е да искате да злоупотребявате с circuit breaking, но е приятно да знаете, че имате резервен план в случай на нужда.

6. Автомасштабиране

TL;DR: Увеличавайте или намалявайте броя на инстанциите на услугата в зависимост от зададени критерии.

Service mesh-овете не са планировчици, затова те не осъществяват масштабиране сами. Въпреки това, те могат да предоставят информация, на базата на която планировчиците ще вземат решения. Тъй като service mesh-овете имат достъп до целия трафик между услугите, те разполагат с обширна информация за това, което се случва: кои услуги имат проблеми, кои са слабо натоварени (заделените ресурси за тях се изразходват напразно) и т.н.

Например, Kubernetes мащабира услугите в зависимост от използването на CPU и памет от pod-овете (вж. нашия доклад „Автоматично мащабиране и управление на ресурсите в Kubernetes» — забележка на преводача.), но ако решите да правите мащабиране на базата на друг показател (в нашия случай - свързан с трафика), ще е необходима специална метрика. Ръководство като това показва как да го направите с помощта на Envoy, Istio и Prometheus, но самият процес е доста сложен. Бихме искали service mesh да го опрости, позволявайки просто задаване на условия като „увеличи броя на инстанциите на услугата auth, ако броят на изчакващите заявки надвиши зададен праг за минута“.

7. Канарски разгръщания

TL;DR: Тествайте нови функции или версии на услугата на подгрупа от потребители.

Представете си, че разработвате SaaS продукт и планирате да пуснете новата му версия. Вие я тествате в staging и тя работи отлично. Въпреки това обаче имате определени притеснения относно поведението ѝ в реални условия. С други думи, трябва да тествате новата версия с реални задачи без да рискувате доверието на потребителите. Канарените разгръщания са отличен начин за това. Те ви позволяват да демонстрирате нова функция на избрана подгрупа от потребители. Тази подгрупа може да включва най-лоялните потребители, тези, които използват безплатната версия на продукта, или потребители, които са изразили желание да бъдат „опитни зайчета“.

Service mesh-овете реализират това, позволявайки да зададете критерии, които определят кой и коя версия на приложението ще види, и съответно маршрутизирайки трафика. За самите услуги не се променя нищо. Версия 1.0 на услугата счита, че всички заявки идват от потребители, които трябва да я видят, а версия 1.1 мисли същото за своите потребители. А вие, междувременно, можете да променяте процента на трафика между старото и новото издание, пренасочвайки нарастващия брой потребители към новото, ако то работи стабилно и вашите „опитни“ дават добро.

8. Сини-зелени разгръщания

TL;DR: Пускайте нова готина функция, но бъдете готови да я върнете обратно незабавно.

Същността на сините-зелени разгръщания е да пуснете нов „син“ сервис, стартирайки го паралелно със стария „зелен“. Ако всичко върви гладко и новият сервис се представя добре, старият ще може да бъде постепенно изключен. (За съжаление, някога и този нов „син“ сервис ще повтори съдбата на „зеления“ и ще изчезне…) Сините-зелени разгръщания се различават от канарените по това, че новата функция обхваща веднага всички потребители (а не част); същността тук е да имате под ръка „резервно летище“, ако нещо се обърка.

Сервисните мрежи предлагат много удобен начин за тестване на "синия" сервис и мигновено превключване на работещия "зелен" в случай на проблеми. Да не говорим, че те предоставят маса информация (вижте раздела "Телеметрия" по-долу) за работата на "синия", която помага да се разбере дали той е готов за пълно експлоатация.

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

9. Проверка на здравето

TL;DR: Наблюдавайте кои инстанции на сервисите са работоспособни и реагирайте на тези, които спират да бъдат такива.

Проверка на здравето (health check) помага да се вземе решение за това дали инстанциите на сервиза могат да приемат и обработват трафик. Например, в случай на HTTP-сервизи проверката на здравето може да изглежда като GET-запитване на endpoint /health. Отговор 200 OK ще означава, че инстанцията е здрава, всеки друг отговор ― че не е готова да приема трафик. Сервисните мрежи позволяват да се укаже както начинът, по който ще се проверява работоспособността, така и честотата, с която тази проверка ще се извършва. Тази информация може да се използва за други цели — например, за балансировка на натоварването и circuit breaking.

По този начин, проверката на здравето не е самостоятелен сценарий на използване, а обикновено се използва за постигане на други цели. Също така, в зависимост от резултатите от health check-овете, могат да се изискват външни действия (относно другите цели на сервисните мрежи): например обновяване на страницата на състоянието, създаване на issue в GitHub или попълване на тикет в JIRA. И сервисната мрежа предлага удобен механизъм за автоматизация на всичко това.

10. Пренасочване на натоварването (load shedding)

TL;DR: Пренасочвайте трафика в отговор на временно увеличение на използването.

Ако някой сервиз е натоварен от трафик, можете временно да пренасочите част от този трафик на друго място (тоест да "сбросите", "преливате" (shed) го там). Например, към резервен сервиз или дата център, или към постоянен Pulsar темата. В резултат на това услугата ще продължи да обработва част от заявките, вместо да спре и да спре напълно обработката. Нулирането на натоварването е по-добро от разкъсването на веригата, но все пак е нежелателно да се злоупотребява с него. То позволява да се предотвратят каскадни повреди, поради които се сриват downstream услуги.

11. Паралелна обработка/озеркаляване на трафика

TL;DR: Изпращайте едно запитване наведнъж на няколко места.

Понякога възниква необходимост да се изпрати заявка (или набор от заявки) наведнъж на няколко услуги. Характерен пример е изпращането на част от продукционния трафик към staging услугата. Основният уеб сървър на продукцията изпраща заявка към подчинената услуга products.production и само към нея. А service mesh интелигентно копира тази заявка и я изпраща на products.staging, за което уеб сървърът дори не подозира.

Още един свързан сценарий за използване на service mesh, който може да бъде реализиран над паралелната обработка на трафика, е регресионното тестване. То предвижда изпращането на същите заявки до различни версии на услугата и проверката дали всички версии се държат по един и същи начин. Все още не съм срещал реализация на service mesh с вградена система за регресионно тестване, подобна на Diffy, но самата идея изглежда обещаваща.

12. Изолация

TL;DR: Разделяйте вашата service mesh на мини мрежи.

Също известна като сегментация, изолацията е изкуството да се разделя service mesh на логически отделени сегменти, които не знаят нищо един за друг. Изолацията е малко подобна на създаването на виртуални частни мрежи. Основната разлика е, че все пак можете да се възползвате от всички предимства на service mesh (като откритие на услуги), но с допълнителна безопасност. Например, ако нападател успее да проникне в услуга в една от подсетите, той няма да може да види какви услуги са активни в другите подсети или да прихване техния трафик.

Освен това, предимствата могат да бъдат и организационни. Може да искате да разделите услугите на подсети в зависимост от структурата на компанията и да освободите разработчиците от когнитивната тежест, произтичаща от необходимостта да имат предвид цялата service mesh.

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

TL;DR: Вече не е нужно да включвате належащи задачи за управление на заявките в кодовата база.

Всички тези неща могат да бъдат разглеждани като отделни случаи на употреба, но реших да ги обединя заради една обща черта: те поемат задачи по управлението на жизнения цикъл на заявките, които обикновено се изпълняват от библиотеките на приложенията. Ако разработвате уеб сървър на Ruby on Rails (не интегриран с service mesh), който извършва заявки към бекенд услугите през gRPC, приложението ще трябва само да реши какво да прави, ако N заявки се провалят. Също така, ще трябва да се установи какъв обем трафик могат да обработват тези услуги и да "hardcode" тези параметри с помощта на специална библиотека. В допълнение, приложението ще трябва да решава, кога е време да се предаде и да позволи на заявката да изтече (по timeout). И за да се промени някой от изброените по-горе параметри, уеб сървърът ще трябва да се спре, да се преконфигурира и да се стартира отново.

Предаването на тези задачи на service mesh означава не само, че разработчиците на услугите няма да трябва да мислят за тях, но и че ще могат да се разглеждат по-глобално. Ако се използва сложна верига от услуги, например A → B → C → D → E, е необходимо да се вземе предвид целият жизнен цикъл на заявката. Ако целта е да се удължат тайм-аутите в услуга C, би било логично да се направи всичко наведнъж, а не поотделно: обновявайки кода на услугата и чакайки, докато pull request бъде приет и CI системата разгръща обновената услуга.

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

TL;DR: Събирайте цялата необходима (и не толкова необходима) информация от услугите.

Телеметрията е общ термин, който обхваща метрики, разпределено проследяване и логове. Сервисните мрежи предлагат механизми за събиране и обработка на всичките три типа данни. Тук нещата стават малко неясни, тъй като броят на възможните варианти е твърде голям. За събиране на метрики има Prometheus и други инструменти, за събиране на логове можете да използвате fluentd, Loki, Vector и др. (например, ClickHouse с нашия loghouse за K8s — бел. ред.), за разпределено проследяване има Jaeger и т.н. Всяка service mesh може да поддържа едни инструменти и да не поддържа други. Интересно ще бъде да видим, дали проектът Open Telemetry може да осигури известна конвергенция.

В този случай предимството на технологията service mesh е, че sidecar контейнери могат да събират всички изброени данни от своите услуги. С други думи, получавате единна система за събиране на телеметрия и service mesh може да обработва цялата тази информация по различни начини. Например:

  • да следите логовете от определена услуга в 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). Моля, спазвайте правилата на приличието.

P.S. от преводача

За основа на заглавната илюстрация на статията е използвано изображение от статията „What is a Service Mesh (and when to use one)?“ (автор — Gregory MacKinnon). На него е показано как част от функционалността на приложенията (в зелено) се е прехвърлила към service mesh, осигуряваща взаимовръзки между тях (в синьо).

Прочетете също в нашия блог:

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster