Резервиране в Kubernetes: то съществува

Казвам се Сергей, от компанията ITSumma, и искам да ви разкажа как подхождаме към резервирането в Kubernetes. В последно време активно се занимавам с консултантска работа по внедряване на разнообразни devops решения за различни екипи, а в частност работя по проекти с K8s. На конференцията Uptime day 4, посветена на резервирането в сложни архитектури, представих доклад за резервирането на "кубчето", и ето свободен преразказ на него. Само предварително предупреждавам, че това не е непосредствено ръководство за действие, а по-скоро обобщение на размисли по темата.

Резервиране в Kubernetes: то съществува

В принципе мониторингът и резервирането са два основни инструмента за повишаване на устойчивостта на всеки проект. Но какво, ако кажете, че в кубера всичко се балансира само, всичко се мащабира само, и ако нещо се случи — ще се възстанови само? Тоест, при първоначално повърхностно разглеждане на темата, интернет отговаря на въпроса как всеки подхожда към резервирането на K8s с "а защо?". Много хора мислят, че кубер е магическо решение, което елиминира всички инфраструктурни проблеми и осигурява, че проектът никога няма да срине. Но… светът не е такъв, какъвто изглежда.

Как подходихме към резервирането преди? Имахме идентични платформи за хостинг — било то виртуални машини или физически сървъри, към които прилагахме три основни практики:

  1. синхронизиране на код и статични файлове
  2. синхронизиране на конфигурации
  3. репликация на бази данни

И ето го: по всяко време можем да преминем към резервната платформа, всички сме щастливи и се разотиваме.

Резервиране в Kubernetes: то съществува

Какво ни предлагат за увеличаване на постоянната наличност на нашето kubernetes приложение? Първото, за което споменава неофициалната документация, е да инсталираме множество машини и да създадем много майстори — техният брой трябва да удовлетворява условията за достигане на кворума в класира и да има активиран etcd, api, MC, scheduler на всеки от майсторите... И, изглежда, всичко е прекрасно: при излизането на няколко работни ноди или майстори от строя нашият клъстер ще се ребалансира и приложението ще продължи да работи. Отново изглежда като магия! Но често нашият клъстер е в рамките на един център за данни и това може да предизвика определени въпроси. Какво ако дойде багер и изрови кабел, удари мълния, настъпи вселенски потоп? Всичко е загубено, нашият клъстер вече не съществува. Как да подходим към резервирането, като вземем това предвид?

На първо място, трябва да имате още един клъстер в горещ резерв, т.е. клъстер, към който можете да се переключите по всяко време. От гледна точка на кубера, инфраструктурите трябва да бъдат напълно идентични. Тоест, ако имате нестандартни плъгини за работа с файловата система, кастомни решения за ingress, те трябва да бъдат напълно идентични на вашите два (или три, или десет, тук зависи от бюджета и усилията на администратора) клъстера. Наложително е да определите две набора приложения (deployment-и, statefulset-и, daemonset-и, cronjob-и и т.н.): кои от тях могат да работят в резервата постоянно, а кои е по-добре да не стартирате до непосредственото превключване.

Трябва ли нашият резервен клъстер да бъде напълно идентичен на нашия боен клъстер? Не. Ако преди, в рамките на работа с монолитни проекти, с железна инфраструктура сме поддържали практически напълно идентично обкръжение, то в рамките на кубера, смятам, че това не трябва да бъде така. Нека разгледаме защо.

Например, давайте започнем с основните компоненти на Kubernetes — deployments — те трябва да бъдат идентични. Трябва да се стартират приложения, които по всяко време могат да поемат обработката на трафика и да позволят на нашия проект да продължи да функционира. Когато говорим за конфигурационни файлове, трябва да разгледаме дали те трябва да бъдат идентични или не. Тоест, ако ние, разумните хора, не употребяваме никакви забранени вещества и не държим базата данни в K8s, то в конфигурационните карти трябва да имаме настройки за достъп до продуктивната база (процесът по резервиране на която е изграден отделно). Съответно, за осигуряване на достъп до резервния екземпляр на базата данни, трябва да имаме отделен конфигурационен файл (configmap). Точно така работим и с тайните: пароли за достъп до базата, API ключове; по всяко време може да работи или продуктивната секрет, или резервната. Тъй като вече имаме две сущности на Kubernetes, резервните версии на които не трябва да бъдат идентични с продуктивните. Следващата сущност, на която трябва да се спрем, е cronjob. Cronjob-ите на резервата по никакъв начин не трябва да бъдат идентични на набора от cronjob-и в продуктивния кластер! Ако стартираме резервен кластер и го стартираме напълно с всички включени cronjob-ове — то, например, хората ще получават по две имейла вместо един. Или синхронизацията на данни с външни източници ще се осъществява два пъти, в резултат на което започваме да се жалим, плачем, викнем и ругаем.

Резервиране в Kubernetes: то съществува

А как ни предлагат да организираме резервния клъстер хората от интернет? Вторият най-популярен отговор след "а защо?" — е използването на Kubernetes Federation.

Какво е това? Това е, да кажем, голям мета-кластер. Ако си представим архитектурата на кубера — където имаме мастер, няколко ноди — то по отношение на федерацията също имаме мастер и няколко ноди, само че всяка нода е отделен кластер. Тоест работим с тези същите същности, с тези същите примитиви, както и с единичен кубер, само че работим не с нашите физически машини, а с цели клъстери. В рамките на федерацията имаме пълна синхронизация на федеративните ресурси от родителите към потомците. Например, ако стартираме някакъв деплоймент чрез федерацията — той ще бъде деплойнат в всеки наш дъщерен кластер. Ако вземем някой configmap, секция, разпространим го през федерацията — той ще се разпространи във всички наши дъщерни клъстери; в същото време федерацията позволява да персонализираме нашите ресурси на децата. Тоест взимаме някой configmap, деплойваме го чрез федерацията и след това, ако трябва да направим корекция на конкретни клъстери, отиваме да го променим в отделния кластер и това изменение вече няма да се синхронизира никъде.

Kubernetes Federation — наскоро появил се инструмент, който не поддържа пълен набор от ресурси, предоставяни от K8s: в момента на публикуването на едно от първите версии на документацията беше описано, че се поддържат само конфигурационни карти, разгръщане под реплика-сет и ingress. Секрети не се поддържат, работата с volume също не е налична. Съществува твърде ограничен набор от функции. Особено ако обичаме да се развлекваме, — например, да предаваме свои собствени ресурси на Kubernetes чрез custom resource definition, — в федерацията не можем да ги включим. Тоест, като цяло… това е решение, което е близо до истината, но ни кара периодично да си стреляне в крака. От друга страна, федерацията позволява гъвкаво управление на нашия replicaset. Например, искаме да стартираме 10 реплики на нашето приложение, по подразбиране федерацията ще разпредели това число пропорционално между броя на кластерите. И всичко това може да се конфигурира! Тоест, можем да зададем, че на производствения кластер трябва да поддържаме 6 реплики на нашето приложение, а на резервния кластер, за икономия на ресурси или за собствено развлечение — само 4 реплики на нашето приложение. Което също е доста удобно. Но с федерацията трябва да използваме нови решения, да добавяме неща на хода, да се притесняваме да мислим малко повече...

Може ли да подходим към процеса на резервиране на Kubernetes по-просто? Какви инструменти имаме на разположение?

На първо място, винаги разполагаме с някаква ci/cd система, тоест ние ръчно не влизаме и не пишем на сървърите create/apply. Системата генерира yaml файлове за нашите контейнери.

На второ място, имаме няколко кластера, разполагаме с едно или няколко (ако сме умни) регистра, което също сме резервирали. И имаме страхотен инструмент kubectl, който може да работи с няколко кластера едновременно.

Резервиране в Kubernetes: то съществува

Така че: от моя гледна точка, най-простото и вярно решение за изграждане на резервен клъстер е примитивно паралелно разгръщане. Има някакъв pipeline в ci/cd системата; първо строим нашите контейнери, тестваме и разгръщаме приложения чрез kubectl на няколко независими клъстера. Можем да правим едновременни разгръщания на няколко клъстера. Съответно, доставката на конфигурации също решаваме на този етап. Можем предварително да определим набор от конфигурации за нашия активен клъстер, набор от конфигурации за резервния клъстер и на ниво ci/cd система да разгръщаме продукционната среда в продукционния клъстер, а резервната среда — в резервния клъстер. В сравнение с федерацията не е нужно да ходим след определянето на федеративния ресурс на всеки дочерен клъстер и нещо да преопределяме. Направихме го предварително. Какви сме добри.

Но… има… бях написал, че има „корен на всичкото зло“, но всъщност те са два. На първо място, файловата система. Има някакъв PV, или използваме външно хранилище. Ако съхраняваме файлове вътре в клъстера, то трябва да действаме по старите практики, останали от времето на физическите инфраструктури: например, синхронизираме с lsync. Или с каквото друго предпочитате лично вие. Разгръщаме всичко на други компютри и живеем.

На второ място, и всъщност дори по-важна точка на спънка — базата данни. Ако сме умни хора и не държим базата в кубера, то процесът на резервиране на данни по същата стара схема — master-slave репликация, след това превключване, репликата ще я догоним и ще живеем добре. Но ако държим нашата DB вътре в клъстера, то в принцип има много готови решения за организация на същата master-slave реплика, много решения за подигнатие на DB вътре в кубера.
За резервирането на бази данни вече са прочетени милион доклади, написани милион статии, всъщност тук не е нужно нищо ново. В общи линии, следвайте мечтите си, живейте както искате, изобретявайте си и сложни костюми, но непременно обмислете как всичко това ще резервирате.

Сега да поговорим за процеса на превключване към резервна площадка в случай на пожар. Първо, паралелно разгръщаме статeless приложения. Те не влияят на бизнес логиката на нашите приложения и проекта. Можем постоянно да имаме два набора работещи приложения, които могат да започнат да приемат трафик. Много е важно в процеса на превключване към резервна площадка да проверим дали е необходимо да се пренастройват конфигурации. Например, имаме продукционен Kubernetes клъстър, резервен Kubernetes клъстър, външна основна база данни и резервна основна база данни. Имаме четири варианта, по които тези приложения в продукция могат да взаимодействат помежду си. Може да се наложи да превключим базата данни, и така трафикът в продукционния клъстър да бъде насочен към нова база, или пък клъстърът може да се повреди — и да преминем на резервния, но продължавайки да работим с продукционната база. Третият вариант е, когато и това, и онова се повреди, и ние превключваме и двете приложения, пренастройваме нашата конфигурация, така че новите приложения да работят с новата база данни.

И всъщност, какви изводи можем да направим от всичко това?

Резервиране в Kubernetes: то съществува

Първи извод: с резерва се живее добре. Но е скъпо. Идеалът е да не се разчита само на един резерв. Идеалът е да имаме няколко резерва. Първо, резервът трябва да е най-малко в различен дата център, и второ, при различен хостинг доставчик. Често съм виждал — и в моята практика е било. Проектите не мога да спомена, но точно когато стана пожар в дата центъра… аз казвам: превключваме на резерв! А резервните сървъри бяха в същия шкаф…

Представете си, че Amazon беше блокиран в Русия (а такова нещо е ставало). И всичко — каква полза от резерв в друг Amazon? Той също е недостъпен. Затова припомням: поддържаме резерв, най-малкото в друг дата център, а за предпочитане — при друг хостър.

Втори извод: ако имате приложение в кубера, което комуникира с външни източници (което може да бъде както база данни, така и външно API), задължително го определете като услуга с външен Endpoint, за да не се налага при преминаване да деплоите 15 приложения, които достъпват същата база. Определете базата като отделна услуга и я достъпвайте, сякаш е вътре в кластера: ако базата се скапе, просто променяте IP-то на едно място и продължавате да живеете щастливо.

И накрая: обичам "кубик" и експериментите с него. Освен това обичам да споделям резултатите от тези експерименти и личния си опит. Затова записах серия уебинари за K8s, добре дошли в нашия youtube-канал за подробности.

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

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