Изисквания за разработване на приложение в Kubernetes

Днес планирам да говоря за това как да пишете приложения и какви са изискванията, за да работи вашето приложение добре в Kubernetes. За да нямате главоболия с приложението, за да не се налага да измисляте и изграждате „драскотини“ около него - и всичко работи така, както самият Kubernetes е предвидил.

Тази лекция е част от "Нощно училище Slurm на Kubernetes" Можете да разгледате откритите теоретични лекции на Вечерното училище в Youtube, групирани в плейлист. За тези, които предпочитат текст, а не видео, сме подготвили тази статия.

Казвам се Павел Селиванов, в момента съм водещият DevOps инженер в Mail.ru Cloud Solutions, ние правим облаци, правим kubernetes за управление и така нататък. Моите задачи сега включват помощ при разработката, пускането на тези облаци, пускането на приложенията, които пишем, и директното разработване на инструментите, които предоставяме на нашите потребители.

Изисквания за разработване на приложение в Kubernetes

Правя DevOps, мисля, че през последните, вероятно, три години. Но по принцип правя това, което DevOps прави вероятно вече около пет години. Преди това се занимавах предимно с администраторски неща. Започнах да работя с Kubernetes преди много време - сигурно са минали около четири години, откакто започнах да работя с него.

Като цяло започнах, когато Kubernetes беше версия 1.3, вероятно, а може би 1.2 - когато беше още в зародиш. Сега вече не е в начален стадий - и е очевидно, че има огромно търсене на пазара за инженери, които биха искали да могат да правят Kubernetes. И компаниите имат много голямо търсене на такива хора. Затова всъщност се появи тази лекция.

Ако говорим според плана на това, за което ще говоря, изглежда така, в скоби е написано (TL;DR) - „твърде дълго; не четете". Презентацията ми днес ще се състои от безкрайни списъци.

Изисквания за разработване на приложение в Kubernetes

Всъщност аз самият не харесвам такива презентации, когато се правят, но това е такава тема, че когато подготвях тази презентация, просто не разбрах как да организирам тази информация по различен начин.

Тъй като като цяло тази информация е „ctrl+c, ctrl+v“ от, наред с други неща, нашето Wiki в секцията DevOps, където сме написали изисквания към разработчиците: „момчета, така че да стартираме вашето приложение в Kubernetes, трябва да е така."

Ето защо презентацията се оказа толкова голям списък. съжалявам Ще се опитам да разкажа колкото се може повече, за да не е скучно, ако е възможно.

Какво ще разгледаме сега:

  • това са, първо, регистрационни файлове (дневници на приложения?), какво да правя с тях в Kubernetes, какво да правя с тях, какви трябва да бъдат;
  • какво да правим с конфигурациите в Kubernetes, кои са най-добрите и най-лошите начини за конфигуриране на приложение за Kubernetes;
  • Нека поговорим за това какво представляват проверките за достъпност като цяло, как трябва да изглеждат;
  • нека поговорим за това какво е грациозно изключване;
  • нека отново да поговорим за ресурси;
  • Нека отново се докоснем до темата за съхранение на данни;
  • и накрая ще ви кажа какъв е терминът това мистериозно родно в облак приложение. Cloudnativeness, като прилагателно към този термин.

Дневници

Предлагам да започнете с регистрационните файлове - с това къде тези регистрационни файлове трябва да бъдат поставени в Kubernetes. Сега сте стартирали приложение в Kubernetes. Според класиката преди това приложенията винаги са записвали журнали някъде във файл. Лошите приложения записаха регистрационни файлове във файл в домашната директория на програмиста, който стартира приложението. Добрите приложения записаха регистрационни файлове във файл някъде в /var/log.

Изисквания за разработване на приложение в Kubernetes

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

Когато се преместим в света на Kubernetes и стартираме същото нещо там, първото нещо, на което можете да обърнете внимание, е фактът, че хората, както са писали логове във файл, продължават да ги пишат.

Оказва се, че ако говорим за Kubernetes, правилното място за записване на логове някъде от докер контейнер е просто да ги запишете от приложението в така наречения Stdout/Stderr, тоест стандартните изходни потоци на операционната система, стандартна грешка изход. Това е най-правилният, най-простият и най-логичният начин за поставяне на логове по принцип в Docker и конкретно в Kubernetis. Защото, ако вашето приложение пише регистрационни файлове в Stdout/Stderr, тогава зависи от Docker и добавката Kubernetes да решат какво да правят с тези регистрационни файлове. Docker по подразбиране ще изгради своите специални файлове във формат JSON.

Тук възниква въпросът какво ще правите след това с тези трупи? Най-лесният начин е ясен, ние имаме способността да го направим kubectl logs и погледнете тези регистрационни файлове на тези „шушулки“. Но вероятно това не е много добър вариант - трябва да се направи нещо друго с трупите.

Засега нека поговорим едновременно, тъй като засегнахме темата за трупите, за такова нещо, как трябва да изглеждат трупите. Тоест, това не се отнася директно за Kubernetes, но когато започнем да мислим какво да правим с логовете, би било добре да помислим и за това.

Имаме нужда от някакъв инструмент, по приятелски начин, който ще вземе тези регистрационни файлове, които нашият докер поставя в своите файлове, и ще ги изпрати някъде. Като цяло обикновено стартираме някакъв агент вътре в Kubernetes под формата на DaemonSet - събирач на журнали, на който просто се казва къде се намират журналите, които Docker събира. И този събиращ агент просто ги взема, може би дори по някакъв начин ги анализира по пътя, може би ги обогатява с някаква допълнителна мета-информация и в крайна сметка ги изпраща за съхранение някъде. Там вече са възможни вариации. Най-често срещаният вероятно е Elasticsearch, където можете да съхранявате регистрационни файлове и можете удобно да ги извличате от там. След това, използвайки заявка, използвайки Kibana, например, изградете графики въз основа на тях, изградете предупреждения въз основа на тях и т.н.

Най-важната идея, искам да я повторя отново, е, че вътре в Docker, особено в Kubernetes, съхраняването на вашите регистрационни файлове във файл е много лоша идея.

Защото първо, трудно е да получите регистрационните файлове вътре в контейнера във файл. Първо трябва да влезете в контейнера, да изпълните там и след това да погледнете регистрационните файлове. Следващият момент е, че ако имате регистрационни файлове във файл, тогава контейнерите обикновено имат минималистична среда и няма помощни програми, които обикновено са необходими за нормална работа с регистрационни файлове. Заровете ги, разгледайте ги, отворете ги в текстов редактор. Следващият момент е, когато имаме регистрационни файлове във файл вътре в контейнер, ако този контейнер бъде изтрит, разбирате, логовете ще умрат заедно с него. Съответно всяко рестартиране на контейнера означава, че няма повече регистрационни файлове. Пак лош вариант.

И последната точка е, че вътре в контейнерите обикновено имате вашето приложение и това е - обикновено това е единственият работещ процес. Изобщо не се говори за някакъв процес, който би ротирал файлове с вашите логове. Веднага щом логовете започнат да се записват във файл, това означава, че, извинете, ще започнем да губим производствения сървър. Защото, първо, те са трудни за намиране, никой не ги следи, плюс никой не ги контролира - съответно файлът расте безкрайно, докато мястото на сървъра просто не свърши. Затова казвам отново, че влизането в Docker, особено в Kubernetes, във файл е лоша идея.

Следващата точка, тук искам да говоря отново за това - тъй като засягаме темата за трупите, би било добре да поговорим за това как трябва да изглеждат трупите, за да е удобно да се работи с тях. Както казах, темата не е пряко свързана с Kubernetes, но е свързана много добре с темата за DevOps. По темата за културата на развитие и приятелството между тези два различни отдела - Dev и Ops, така че на всички да им е удобно.

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

Ако вашият JSON не работи според някои критерии, никой не знае какви, тогава поне напишете журнали във формат, който може да бъде анализиран. Тук по-скоро си струва да помислите за факта, че например, ако изпълнявате куп контейнери или просто процеси с nginx и всеки има свои собствени настройки за регистриране, тогава вероятно изглежда, че ще ви бъде много неудобно да анализирайте ги. Защото за всеки нов екземпляр на nginx трябва да напишете свой собствен парсер, защото те пишат логове по различен начин. Отново вероятно си струваше да помислим дали всички тези екземпляри на nginx имат една и съща конфигурация за регистриране и записват всичките си журнали абсолютно еднакво. Същото важи за абсолютно всички приложения.

В крайна сметка искам също да налея масло в огъня, че в идеалния случай трябва да се избягват регистрационни файлове с многоредов формат. Ето нещо, ако някога сте работили със събирачи на трупи, тогава най-вероятно сте виждали какво ви обещават, че могат да работят с многоредови журнали, знаят как да ги събират и т.н. Всъщност, по мое мнение, нито един колектор днес не може да събира многоредови дневници нормално, пълно и без грешки. По човешки, за да е удобно и без грешки.

Изисквания за разработване на приложение в Kubernetes

Но проследяването на стека винаги е многоредови регистрационни файлове и как да ги избегнете. Въпросът тук е, че дневникът е запис на събитие, а stactrace всъщност не е дневник. Ако събираме регистрационни файлове и ги поставяме някъде в Elasticsearch и след това рисуваме графики от тях, съставяме някои отчети за активността на потребителите на вашия сайт, тогава, когато получите проследяване на стека, това означава, че се случва нещо неочаквано.необработена ситуация във вашето приложение. И има смисъл автоматично да се качи проследяване на стека някъде в система, която може да ги проследи.

Това е софтуер (същият Sentry), който е направен специално за работа с проследяване на стека. Той може незабавно да създава автоматизирани задачи, да ги възлага на някого, да предупреждава, когато се появят stacttraces, да групира тези stacttraces по един тип и т.н. По принцип няма много смисъл да говорим за stactraces, когато говорим за дневници, защото в крайна сметка това са различни неща с различни цели.

Конфигурация

След това говорим за конфигурация в Kubernetes: какво да правим с нея и как приложенията в Kubernetes трябва да бъдат конфигурирани. Като цяло обикновено казвам, че Docker не е за контейнери. Всеки знае, че Docker е за контейнери, дори и тези, които не са работили много с Docker. Повтарям, Docker не е за контейнери.

Docker, според мен, е за стандарти. И има стандарти за почти всичко: стандарти за изграждане на вашето приложение, стандарти за инсталиране на вашето приложение.

Изисквания за разработване на приложение в Kubernetes

И това нещо - използвахме го преди, просто стана особено популярно с появата на контейнерите - това нещо се нарича ENV (среда) променливи, тоест променливи на средата, които са във вашата операционна система. Това обикновено е идеален начин да конфигурирате вашето приложение, защото ако имате приложения в JAVA, Python, Go, Perl, не дай си Боже, и всички те могат да четат променливите за хост на базата данни, потребител на базата данни, парола за база данни, тогава е идеален. Имате приложения на четири различни езика, конфигурирани в плана на базата данни по същия начин. Няма повече различни конфигурации.

Всичко може да се конфигурира с помощта на ENV променливи. Когато говорим за Kubernetes, има страхотен начин да декларирате ENV променливи направо в Deployment. Съответно, ако говорим за секретни данни, тогава можем незабавно да избутаме секретни данни от ENV променливи (пароли към бази данни и т.н.) в тайна, да създадем таен клъстер и да посочим в ENV описанието в Deployment, че не декларираме директно стойността на тази променлива и стойността на тази променлива за паролата на базата данни ще бъдат прочетени от тайната. Това е стандартно поведение на Kubernetes. И това е най-идеалният вариант за конфигуриране на вашите приложения. Само на ниво код, отново това се отнася за разработчиците. Ако сте DevOps, можете да попитате: „Момчета, моля, научете приложението си да чете променливи на средата. И всички ще бъдем щастливи.”

Ако всички в компанията четат едни и същи променливи на средата, тогава това е страхотно. За да не стане така, че едни чакат postgres база данни, други чакат име на база данни, трети чакат нещо друго, трети чакат dbn някакъв, за да има съответно еднаквост.

Проблемът идва, когато имате толкова много променливи на средата, че просто отваряте Deployment - и има петстотин реда променливи на средата. В този случай вие просто сте надраснали променливите на околната среда - и вече няма нужда да се измъчвате. В този случай би имало смисъл да започнете да използвате конфигурации. Тоест, обучете приложението си да използва конфигурации.

Единственият въпрос е, че конфигурациите не са това, което си мислите. Config.pi не е конфигурация, която е удобна за използване. Или някаква конфигурация във ваш собствен формат, алтернативно дарена - това също не е конфигурацията, която имам предвид.

Това, за което говоря, е конфигурация в приемливи формати, тоест най-популярният стандарт е стандартът .yaml. Ясно е как се чете, чете се от хора, ясно е как се чете от приложението.

Съответно, в допълнение към YAML, можете също, например, да използвате JSON, синтактичният анализ е почти толкова удобен, колкото YAML по отношение на четене на конфигурацията на приложението от там. Забележимо по-неудобно е за хората да четат. Можете да опитате формата, a la ini. Доста е удобен за четене от човешка гледна точка, но може да е неудобно да се обработва автоматично, в смисъл, че ако някога искате да генерирате свои собствени конфигурации, ini форматът може вече да е неудобен за генериране.

Но във всеки случай, какъвто и формат да изберете, важното е, че от гледна точка на Kubernetes е много удобно. Можете да поставите цялата си конфигурация в Kubernetes, в ConfigMap. И след това вземете тази configmap и я помолете да бъде монтирана във вашия pod в някаква специфична директория, където вашето приложение ще прочете конфигурацията от тази configmap, сякаш е просто файл. Това всъщност е добре да направите, когато имате много опции за конфигурация във вашето приложение. Или това е просто някаква сложна структура, има гнездене.

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

Отново, вече говорих за това - секретната информация не е в configmap, секретната информация не е в променливите, секретната информация не е в тайните. Оттам нататък свържете тази секретна информация с дипломацията. Обикновено съхраняваме всички описания на Kubernetes обекти, внедрявания, конфигурационни карти, услуги в git. Съответно поставянето на паролата на базата данни в git, дори и да е вашият git, който имате вътрешно във фирмата, е лоша идея. Защото като минимум git помни всичко и просто премахването на пароли от там не е толкова лесно.

Преглед на здравето

Следващата точка е това нещо, наречено Здравна проверка. По принцип проверката на здравето е просто проверка дали вашето приложение работи. В същото време най-често говорим за определени уеб приложения, за които съответно от гледна точка на проверката на здравето (по-добре е да не превеждаме тук и по-нататък) това ще бъде някакъв специален URL, който те обработват като стандарт, те обикновено го правят /health.

При достъп до този URL съответно нашето приложение казва или „да, добре, всичко ми е наред, 200“ или „не, всичко не е наред с мен, около 500“. Съответно, ако нашето приложение не е http, не е уеб приложение, сега говорим за някакъв вид демон, можем да разберем как да правим проверки на здравето. Тоест не е необходимо, ако приложението не е http, значи всичко работи без проверка на здравето и това не може да стане по никакъв начин. Можете периодично да актуализирате някаква информация във файла, можете да измислите някаква специална команда за вашия демон, като, daemon status, което ще каже „да, всичко е наред, демонът работи, жив е“.

За какво е? Първото и най-очевидно нещо вероятно е защо е необходима проверка на здравето - за да се разбере, че приложението работи. Искам да кажа, просто е глупаво, когато е включено сега, изглежда, че работи, така че можете да сте сигурни, че работи. И се оказва, че приложението работи, контейнерът работи, екземплярът работи, всичко е наред - и тогава потребителите вече са прекъснали всички телефонни номера от техническата поддръжка и казват „какво си..., ти заспа, нищо не работи.

Проверката на здравето е точно такъв начин да се види от гледна точка на потребителя, че работи. Един от методите. Нека го кажем така. От гледна точка на Kubernetes, това също е начин да разберем кога стартира приложението, защото разбираме, че има разлика между това кога контейнерът е стартиран, създаден и стартиран и кога приложението е стартирано директно в този контейнер. Защото, ако вземем някакво средно java приложение и се опитаме да го стартираме в дока, след това за четиридесет секунди, или дори минута, или дори десет, то може да започне съвсем добре. В този случай можете поне да чукате на портовете му, той няма да отговори там, тоест все още не е готов да получава трафик.

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

Изисквания за разработване на приложение в Kubernetes

Това, за което говоря сега, се нарича тестове за готовност/живост в Kubernetes; съответно нашите тестове за готовност са отговорни за наличността на приложението при балансиране. Тоест, ако се правят тестове за готовност в приложението, тогава всичко е наред, клиентският трафик отива към приложението. Ако не се извършат тестове за готовност, приложението просто не участва, този конкретен екземпляр не участва в балансирането, премахва се от балансирането, клиентският трафик не тече. Съответно са необходими тестове за Liveness в Kubernetes, така че ако приложението блокира, да може да се рестартира. Ако тестът за жизнеспособност не работи за приложение, което е декларирано в Kubernetes, тогава приложението не просто се премахва от балансиране, то се рестартира.

И ето един важен момент, който бих искал да спомена: от практическа гледна точка тестът за готовност обикновено се използва по-често и е по-често необходим от теста за жизненост. Тоест, просто необмислено деклариране на тестове за готовност и жизненост, защото Kubernetes може да направи това и нека използваме всичко, което може да направи, не е много добра идея. Ще обясня защо. Тъй като точка номер две в тестването е, че би било добра идея да проверите основната услуга във вашите проверки на здравето. Това означава, че ако имате уеб приложение, което издава някаква информация, която от своя страна, естествено, трябва да вземе отнякъде. В база данни, например. Е, той записва информацията, която идва в този REST API, в същата база данни. След това, съответно, ако вашата проверка на здравето реагира просто като при контакт със slashhealth, приложението казва „200, добре, всичко е наред“ и в същото време базата данни на вашето приложение е недостъпна и приложението за проверка на здравето казва „200, добре, всичко е наред ” - Това е лоша проверка на здравето. Това не трябва да работи.

Тоест вашето приложение, когато към него дойде заявка /health, той не просто отговаря „200, добре“, той първо отива, например, в базата данни, опитва се да се свърже с нея, прави нещо много основно там, като изберете един, просто проверява дали има връзка в база данни и можете да направите заявка в базата данни. Ако всичко това е било успешно, тогава отговорът е „200, добре“. Ако не е успешно, се казва, че има грешка, базата данни е недостъпна.

Затова в тази връзка отново се връщам към тестовете Readiness/Liveness - защо най-вероятно ти трябва тест за готовност, а тест за живост е под въпрос. Защото, ако опишете проверките на здравето точно както току-що казах, тогава ще се окаже, че не е налице в частта за примерив или со всех instanceв база данни, например. Когато сте декларирали тест за готовност, нашите здравни проверки започнаха да се провалят и съответно всички приложения, от които базата данни не е достъпна, просто се изключват от балансиране и всъщност "висят" просто в занемарено състояние и чакат базите им работа.

Ако сме декларирали тест за живост, тогава си представете, нашата база данни е повредена и във вашия Kubernetes половината от всичко започва да се рестартира, защото тестът за живост е неуспешен. Това означава, че трябва да рестартирате. Това изобщо не е това, което искате, дори имах личен опит в практиката. Имахме приложение за чат, което беше написано на JS и въведено в база данни на Mongo. И проблемът беше, че в началото на моята работа с Kubernetes описахме готовността, живостта на тестовете на принципа, че Kubernetes може да го направи, така че ще го използваме. Съответно, в един момент Mongo стана малко „тъп“ и пробата започна да се проваля. Съответно, според теста за дъжд, шушулките започнаха да „убиват“.

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

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

Следователно тестовете за готовност и жизненост са различни, още повече, че теоретично можете да правите различни проверки на здравето, един тип radii, един тип liv, например, и да проверявате различни неща. По време на тестовете за готовност проверете задните си части. И при тест за жизненост, например, вие не проверявате от гледна точка, че тестът за жизненост обикновено е просто отговарящо приложение, ако изобщо може да отговори.

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

По отношение на това какво трябва да отговорите, когато имате тест, когато правите здравни прегледи. Това е просто болка. Тези, които са запознати с това, вероятно ще се смеят - но сериозно, през живота си съм виждал услуги, които отговарят на "200" в XNUMX% от случаите. Тоест кой е успешен. Но в същото време в тялото на отговора те пишат „такава и такава грешка“.

Тоест, статусът на отговор идва при вас - всичко е успешно. Но в същото време трябва да анализирате тялото, защото тялото казва „съжалявам, заявката завърши с грешка“ и това е просто реалност. Видях това в реалния живот.

И така, че някои хора да не го намират за смешно, а други да го намират за много болезнено, все пак си струва да се придържате към едно просто правило. При проверки на здравето и по принцип при работа с уеб приложения.

Ако всичко е минало добре, отговорете с двестния отговор. По принцип всеки двестатен отговор ще ви подхожда. Ако четете ragsy много добре и знаете, че някои статуси на отговор са различни от други, отговорете с подходящите: 204, 5, 10, 15, каквото и да е. Ако не е много добре, тогава просто „две нула нула“. Ако всичко върви зле и проверката на здравето не реагира, отговорете с всяка петстотна. Отново, ако разбирате как да отговорите, как различните състояния на отговор се различават един от друг. Ако не разбирате, тогава 502 е вашата опция да отговорите на здравни проверки, ако нещо се обърка.

Това е друг момент, искам да се върна малко за проверката на основните услуги. Ако започнете, например, да проверявате всички основни услуги, които стоят зад вашето приложение - всичко като цяло. Това, което получаваме от гледна точка на архитектурата на микросервизите, имаме такава концепция като „ниско свързване“ - тоест, когато вашите услуги са минимално зависими една от друга. Ако един от тях се повреди, всички останали без тази функционалност просто ще продължат да работят. Някои от функциите просто не работят. Съответно, ако свържете всички здравни проверки една с друга, тогава ще се окажете с едно нещо, което пада в инфраструктурата, и тъй като то е паднало, всички здравни проверки на всички услуги също започват да се провалят - и има повече инфраструктура като цяло за цялостна микроуслуга архитектура No. Там всичко потъмня.

Затова искам да повторя това отново, че трябва да проверите основните услуги, тези, без които вашето приложение в сто процента от случаите не може да свърши работата си. Тоест, логично е, че ако имате REST API, чрез който потребителят записва в базата данни или извлича от базата данни, тогава при липса на база данни не можете да гарантирате работа с вашите потребители.

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

След това имаме и един от болезнените проблеми при стартиране на приложения.

Всъщност това не се отнася само за Kubernetes като цяло; просто така се случи, че културата на някакво масово развитие и DevOps в частност започна да се разпространява приблизително по същото време като Kubernetes. Следователно като цяло се оказва, че трябва да затворите елегантно приложението си без Kubernetes. Дори преди Kubernetes хората правеха това, но с появата на Kubernetes започнахме да говорим за това масово.

Грациозно изключване

Като цяло, какво е Graceful Shutdown и защо е необходимо? Това е когато приложението ви се срине по някаква причина, което трябва да направите app stop - или получавате например сигнал от операционната система, вашето приложение трябва да го разбере и да направи нещо по въпроса. Най-лошият сценарий, разбира се, е, когато приложението ви получи SIGTERM и е като „SIGTERM, нека изчакаме, работим, не правим нищо“. Това е направо лош вариант.

Изисквания за разработване на приложение в Kubernetes

Почти също толкова лош вариант е, когато приложението ви получи SIGTERM и е като „те казаха segterm, това означава, че приключваме, не съм виждал, не знам никакви потребителски заявки, не знам какъв вид заявки, върху които работя в момента, казаха SIGTERM, това означава, че приключваме " Това също е лош вариант.

Кой вариант е добър? Първата точка е да се вземе предвид завършването на операциите. Добър вариант е вашият сървър все пак да вземе предвид какво прави, ако получи SIGTERM.

SIGTERM е меко изключване, той е специално проектиран, може да бъде прихванат на ниво код, може да бъде обработен, кажете, че сега, изчакайте, първо ще свършим работата, която имаме, след това ще излезем.

От гледна точка на Kubernetes, това изглежда така. Когато кажем на под, който работи в клъстера на Kubernetes, „моля, спрете, отидете си“, или се рестартираме, или се появи актуализация, когато Kubernetes пресъздаде подовете, Kubernetes изпраща точно същото съобщение SIGTERM до пода, изчаква известно време и , това е времето, което той чака, то също е конфигурирано, има такъв специален параметър в дипломите и се нарича Graceful ShutdownTimeout. Както разбирате, не напразно се нарича така и не напразно говорим за това сега.

Там можем конкретно да кажем колко дълго трябва да изчакаме между момента, в който изпратим SIGTERM на приложението, и когато разберем, че приложението изглежда е полудяло за нещо или е „заседнало“ и няма да приключи - и трябва да изпратете го SIGKILL, тоест, трудно завършете работата му. Тоест, съответно, имаме някакъв демон, който работи, той обработва операции. Разбираме, че средно нашите операции, върху които работи демонът, не продължават повече от 30 секунди наведнъж. Съответно, когато пристигне SIGTERM, разбираме, че нашият демон може да завърши най-много 30 секунди след SIGTERM. Пишем го например 45 секунди за всеки случай и казваме това SIGTERM. След това изчакваме 45 секунди. На теория през това време демонът трябва да е свършил работата си и да е приключил със себе си. Но ако внезапно не може, това означава, че най-вероятно е блокирало - вече не обработва заявките ни нормално. И за 45 секунди можете безопасно, всъщност, да го заковате.

И тук всъщност могат да се вземат предвид дори 2 аспекта. Първо, разберете, че ако сте получили заявка, сте започнали да работите с нея по някакъв начин и не сте дали отговор на потребителя, но сте получили SIGTERM, например. Има смисъл да го прецизирате и да дадете отговор на потребителя. Това е точка номер едно в това отношение. Въпрос номер две тук е, че ако пишете свое собствено приложение, като цяло изградете архитектурата по такъв начин, че да получите заявка за вашето приложение, след което започвате някаква работа, започвате да изтегляте файлове отнякъде, да изтегляте база данни и какво ли още не. Че. Като цяло, вашият потребител, вашата заявка виси половин час и чака да му отговорите - тогава най-вероятно трябва да работите върху архитектурата. Тоест, просто вземете предвид дори здравия разум, че ако вашите операции са кратки, тогава има смисъл да игнорирате SIGTERM и да го промените. Ако вашите операции са дълги, тогава няма смисъл да игнорирате SIGTERM в този случай. Има смисъл да се препроектира архитектурата, за да се избегнат толкова дълги операции. Така че потребителите да не се мотаят и да чакат. Не знам, направете някакъв уебсокет там, направете обратни кукички, които сървърът ви вече ще изпрати на клиента, нещо друго, но не принуждавайте потребителя да виси половин час и просто изчакайте сесия, докато не отговори му. Защото е непредвидимо къде може да се счупи.

Когато вашето приложение приключи, трябва да предоставите подходящ код за изход. Тоест, ако вашето приложение е било помолено да затвори, спре и то е успяло да се спре нормално, тогава не е необходимо да връщате някакъв вид изходен код 1,5,255 и т.н. Всичко, което не е нулев код, поне в Linux системите, сигурен съм в това, се счита за неуспешно. Тоест счита се, че кандидатстването ви в този случай е приключило с грешка. Съответно, по приятелски начин, ако приложението ви завърши без грешка, казвате 0 на изхода. Ако приложението ви се провали по някаква причина, вие казвате не-0 в изхода. И можете да работите с тази информация.

И последният вариант. Лошо е, когато вашият потребител изпрати заявка и виси половин час, докато я обработите. Но като цяло бих искал да кажа и за това, което обикновено си струва от страна на клиента. Няма значение дали имате мобилно приложение, front-end и т.н. Трябва да се има предвид, че като цяло сесията на потребителя може да бъде прекратена, всичко може да се случи. Заявка може да бъде изпратена, например, недостатъчно обработена и без върнат отговор. Вашият интерфейс или вашето мобилно приложение - всеки интерфейс като цяло, нека го кажем така - трябва да вземе това предвид. Ако работите с websockets, това обикновено е най-лошата болка, която някога съм имал.

Когато разработчиците на някои обикновени чатове не знаят това, се оказва, че уебсокетът може да се счупи. За тях, когато нещо се случи в проксито, ние просто променяме конфигурацията и тя прави презареждане. Естествено, всички дълготрайни сесии се разкъсват в този случай. Разработчиците идват при нас и казват: „Момчета, какво правите, чатът се развали за всички наши клиенти!“ Казваме им: „Какво правите? Вашите клиенти не могат ли да се свържат отново? Те казват: „Не, трябва сесиите да не бъдат разкъсани.“ Накратко, това всъщност са глупости. Трябва да се вземе предвид клиентската страна. Особено, както казах, при дълготрайни сесии като websockets, той може да се счупи и, незабелязано от потребителя, трябва да можете да преинсталирате такива сесии. И тогава всичко е перфектно.

Ресурсы

Всъщност, тук просто ще ви разкажа една права история. Пак от реалния живот. Най-лошото нещо, което съм чувал за ресурсите.

Ресурси в този случай, имам предвид, някакъв вид заявки, ограничения, които можете да поставите на подове във вашите Kubernetes клъстери. Най-смешното нещо, което чух от разработчик... Един от моите колеги разработчици на предишно място на работа веднъж каза: „Моето приложение няма да стартира в клъстера.“ Погледнах да видя, че не стартира, но или не се вписваше в ресурсите, или бяха поставили много малки ограничения. Накратко, приложението не може да стартира поради ресурси. Казвам: „Няма да започне поради ресурси, вие решавате колко ви трябва и задавате адекватна стойност.“ Той казва: „Какви ресурси?“ Започнах да му обяснявам, че трябва да се поставят Kubernetes, ограничения на заявките и бла, бла, бла. Човекът слуша пет минути, кимна и каза: „Дойдох тук, за да работя като разработчик, не искам да знам нищо за никакви ресурси. Дойдох тук, за да напиша код и това е." Това е тъжно. Това е много тъжна концепция от гледна точка на разработчика. Особено в съвременния свят, така да се каже, на прогресивни devops.

Защо изобщо са необходими ресурси? В Kubernetes има 2 вида ресурси. Някои се наричат ​​заявки, други се наричат ​​лимити. Под ресурси ще разбираме, че основно винаги има само две основни ограничения. Тоест, времеви ограничения на процесора и ограничения на RAM за контейнер, работещ в Kubernetes.

Ограничението поставя горна граница за това как даден ресурс може да се използва във вашето приложение. Тоест, съответно, ако кажете 1GB RAM в ограниченията, тогава вашето приложение няма да може да използва повече от 1GB RAM. И ако той внезапно поиска и се опита да направи това, тогава процес, наречен oom killer, out of memory, т.е. ще дойде и ще убие вашето приложение - тоест просто ще се рестартира. Приложенията няма да се рестартират въз основа на процесора. По отношение на процесора, ако дадено приложение се опита да използва много, повече от определеното в ограниченията, процесорът просто ще бъде строго избран. Това не води до рестартиране. Това е границата – това е горната граница.

И има молба. Заявка е как Kubernetes разбира как възлите във вашия клъстер Kubernetes се попълват с приложения. Тоест заявката е един вид ангажимент на вашето приложение. Пише какво искам да използвам: „Бих искал да запазите толкова процесор и толкова памет за мен.“ Такава проста аналогия. Ами ако имаме възел, който има, не знам, общо 8 процесора. И там пристига под, чиито заявки казват 1 CPU, което означава, че възелът има останали 7 CPU. Тоест, съответно, веднага щом 8 pods пристигнат в този възел, всеки от които има 1 CPU в своите заявки, възелът, сякаш от гледна точка на Kubernetes, е свършил CPU и повече pods със заявки не могат да бъдат стартира на този възел. Ако процесорът на всички възли свърши, тогава Kubernetes ще започне да казва, че няма подходящи възли в клъстера, за да стартирате вашите подове, защото процесорът е изчерпан.

Защо са необходими заявки и защо без заявки, мисля, че няма нужда да стартирате нищо в Kubernetes? Нека си представим една хипотетична ситуация. Стартирате приложението си без заявки, Kubernetes не знае колко от това, което имате, към какви възли можете да го изпратите. Е, той бута, бута, бута по възлите. В един момент ще започнете да получавате трафик към вашето приложение. И едно от приложенията изведнъж започва да използва ресурси до лимитите, които има според лимитите. Оказва се, че наблизо има друго приложение и то също се нуждае от ресурси. Възелът всъщност започва физически да изчерпва ресурсите си, например OP. Възелът всъщност започва физически да изчерпва ресурсите си, например памет с произволен достъп (RAM). Когато захранването на възел свърши, първо докерът ще спре да отговаря, след това кубелетът, след това операционната система. Те просто ще изпаднат в безсъзнание и ВСИЧКО определено ще спре да работи за вас. Тоест това ще доведе до блокиране на вашия възел и ще трябва да го рестартирате. Накратко, ситуацията не е много добра.

И когато имате заявки, ограниченията не са много различни, поне не много пъти повече от ограниченията или заявките, тогава можете да имате такова нормално, рационално попълване на приложения през възлите на Kubernetes клъстери. В същото време Kubernetes е приблизително наясно колко от какво къде поставя, колко от какво се използва къде. Тоест, това е просто такъв момент. Важно е да го разберете. И е важно да се контролира това да е посочено.

Съхранение на данни

Следващата ни точка е за съхранението на данни. Какво да правя с тях и като цяло какво да правя с постоянството в Kubernetes?

Мисля, че отново в нашите Вечерно училище, имаше тема за базата данни в Kubernetes. И ми се струва, че дори приблизително знам какво ви казаха вашите колеги, когато ви попитаха: „Възможно ли е да стартирате база данни в Kubernetes?“ По някаква причина ми се струва, че вашите колеги трябваше да ви кажат, че ако задавате въпроса дали е възможно да стартирате база данни в Kubernetes, тогава това е невъзможно.

Логиката тук е проста. За всеки случай, ще обясня още веднъж, ако сте наистина страхотен човек, който може да изгради доста устойчива на грешки система за разпределено мрежово съхранение, разберете как да вместите база данни в този случай, как трябва да работи облачният натив в контейнери в база данни като цяло. Най-вероятно нямате въпрос как да го стартирате. Ако имате такъв въпрос и искате да сте сигурни, че всичко се разгръща и стои правилно до смърт в производството и никога не пада, тогава това не се случва. Гарантирано ще се простреляте в крака с този подход. Така че по-добре не го правете.

Какво трябва да правим с данните, които нашето приложение би искало да съхранява, някои снимки, които потребителите качват, някои неща, които нашето приложение генерира по време на работа, при стартиране, например? Какво да правя с тях в Kubernetes?

Като цяло, в идеалния случай, да, разбира се, Kubernetes е много добре проектиран и като цяло първоначално е замислен за приложения без състояние. Тоест за онези приложения, които изобщо не съхраняват информация. Това е идеално.

Но, разбира се, идеалният вариант не винаги съществува. Какво от това? Първата и най-проста точка е да вземете някакъв S3, но не самоделен, който също не е ясно как работи, но от някой доставчик. Добър, нормален доставчик - и научете вашето приложение да използва S3. Тоест, когато вашият потребител иска да качи файл, кажете „тук, моля, качете го в S3“. Когато иска да го получи, кажете: „Ето линк към S3 обратно и го вземете от тук.“ Това е идеално.

Ако изведнъж по някаква причина тази идеална опция не е подходяща, имате приложение, което не сте написали, не разработвате или е някакво ужасно наследство, то не може да използва протокола S3, но трябва да работи с локални директории в локални папки. Вземете нещо повече или по-малко просто, разположете Kubernetes. Тоест, незабавното ограждане на Ceph за някои минимални задачи, струва ми се, е лоша идея. Защото Ceph, разбира се, е добър и модерен. Но ако наистина не разбирате какво правите, след като поставите нещо върху Ceph, можете много лесно и просто никога повече да не го извадите оттам. Защото, както знаете, Ceph съхранява данни в своя клъстер в двоична форма, а не под формата на прости файлове. Следователно, ако внезапно клъстерът Ceph се повреди, тогава има пълна и голяма вероятност никога повече да не получите данните си оттам.

Ще имаме курс по Ceph, можете запознайте се с програмата и подайте заявка.

Затова е по-добре да направите нещо просто като NFS сървър. Kubernetes може да работи с тях, можете да монтирате директория под NFS сървър - вашето приложение е точно като локална директория. В същото време, естествено, трябва да разберете, че отново трябва да направите нещо с вашия NFS, трябва да разберете, че понякога може да стане недостъпен и да обмислите въпроса какво ще направите в този случай. Може би трябва да се архивира някъде на отделна машина.

Следващата точка, за която говорих, е какво да направите, ако вашето приложение генерира някои файлове по време на работа. Например, когато се стартира, той генерира някакъв статичен файл, който се основава на някаква информация, която приложението получава само в момента на стартиране. Какъв момент. Ако няма много такива данни, тогава изобщо не е нужно да се притеснявате, просто инсталирайте това приложение за себе си и работете. Единственият въпрос тук е какво, вижте. Много често всякакви наследени системи, като WordPress и така нататък, особено с модифицирани някакви умни плъгини, умни PHP разработчици, те често знаят как да направят така, че да генерират някакъв вид файл за себе си. Съответно единият генерира един файл, вторият генерира втори файл. Те са различни. Балансирането се случва в клъстера Kubernetes на клиентите просто случайно. Съответно се оказва, че те не знаят как да работят заедно например. Единият дава една информация, другият дава на потребителя друга информация. Това е нещо, което трябва да избягвате. Тоест в Kubernetes всичко, което стартирате, е гарантирано, че може да работи в множество инстанции. Защото Kubernetes е движещо се нещо. Съответно той може да мести всичко, когато си поиска, без изобщо да пита никого. Следователно трябва да разчитате на това. Всичко, стартирано в една инстанция, рано или късно ще се провали. Колкото повече резерви имате, толкова по-добре. Но пак казвам, ако имате няколко такива файла, тогава можете да ги поставите точно под вас, те тежат малко количество. Ако има малко повече от тях, вероятно не трябва да ги натискате вътре в контейнера.

Бих посъветвал, че има такова прекрасно нещо в Kubernetes, можете да използвате обем. По-специално, има том от тип празна директория. Тоест, просто Kubernetes автоматично ще създаде директория в своите директории за услуги на сървъра, от който сте започнали. И той ще ви го даде, за да го използвате. Има само един важен момент. Тоест вашите данни няма да се съхраняват вътре в контейнера, а по-скоро на хоста, на който работите. Освен това Kubernetes може да контролира такива празни директории при нормална конфигурация и е в състояние да контролира максималния им размер и да не позволява той да бъде надвишен. Единственият момент е, че това, което сте написали в празен каталог, не се губи по време на рестартирането на pod. Тоест, ако вашата капсула падне по погрешка и се издигне отново, информацията в празния каталог няма да отиде никъде. Той може да го използва отново при ново начало - и това е добре. Ако вашата капсула напусне някъде, тогава естествено той ще си тръгне без данни. Тоест, веднага щом подът от възела, където е бил стартиран с празна директория, изчезне, празната директория се изтрива.

Какво друго е добро за празния dir? Например, може да се използва като кеш. Нека си представим, че нашето приложение генерира нещо в движение, дава го на потребителите и го прави дълго време. Затова приложението, например, го генерира и го дава на потребителите, като в същото време го съхранява някъде, така че следващия път, когато потребителят дойде за същото нещо, ще бъде по-бързо да го даде веднага генерирано. Празен dir може да бъде помолен на Kubernetes да създаде в паметта. И по този начин вашите кеш памети обикновено могат да работят със светкавична скорост - по отношение на скоростта на достъп до диска. Тоест имате празна директория в паметта, в операционната система тя се съхранява в паметта, но за вас, за потребителя вътре в pod, тя изглежда просто като локална директория. Нямате нужда от приложението, за да преподавате специално магия. Просто директно взимате и поставяте файла си в директория, но всъщност в паметта на операционната система. Това също е много удобна функция по отношение на Kubernetes.

Какви проблеми има Minio? Основният проблем на Minio е, че за да работи това нещо, трябва да работи някъде и трябва да има някаква файлова система, тоест съхранение. И тук срещаме същите проблеми като Ceph. Тоест Minio трябва да съхранява файловете си някъде. Това е просто HTTP интерфейс към вашите файлове. Освен това функционалността е очевидно по-лоша от тази на S3 на Amazon. Преди това не можеше да упълномощи правилно потребителя. Сега, доколкото знам, вече може да създава кофи с различни разрешения, но отново ми се струва, че основният проблем е, така да се каже, най-малкото основната система за съхранение.

Как Empty dir in memory влияе на ограниченията? Не засяга ограниченията по никакъв начин. Той се намира в паметта на хоста, а не в паметта на вашия контейнер. Това означава, че вашият контейнер не вижда празния dir в паметта като част от своята заета памет. Домакинът вижда това. Съответно, да, от гледна точка на kubernetes, когато започнете да използвате това, би било добре да разберете, че отделяте част от паметта си на празен dir. И съответно разберете, че паметта може да свърши не само заради приложенията, но и защото някой пише в тези празни директории.

Облачност

И последната подтема е какво представлява Cloudnative. Защо е необходимо? Cloudnativeness и така нататък.

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

Изисквания за разработване на приложение в Kubernetes

Нека просто вземем Kubernetes като пример. Вашето приложение работи в Kubernetes. Вашето приложение може винаги, или по-скоро администраторите на вашето приложение, винаги могат да създадат акаунт за услуга. Тоест акаунт за оторизация в самия Kubernetes в неговия сървър. Добавете някои права, от които се нуждаем там. И можете да получите достъп до Kubernetes от вашето приложение. Какво можете да направите по този начин? Например, от приложението получавате данни за това къде се намират другите ви приложения, други подобни екземпляри и заедно по някакъв начин се групират върху Kubernetes, ако има такава нужда.

Отново, буквално наскоро имахме случай. Имаме един контрольор, който следи опашката. И когато някои нови задачи се появят в тази опашка, тя отива в Kubernetes - и вътре в Kubernetes създава нова група. Дава на този pod някаква нова задача и в рамките на този pod, pod изпълнява задачата, изпраща отговор до самия контролер и контролерът след това прави нещо с тази информация. Например добавя база данни. Това е, отново, това е плюс на факта, че нашето приложение работи в Kubernetes. Можем да използваме самата вградена функционалност на Kubernetes, за да разширим по някакъв начин и да направим функционалността на нашето приложение по-удобна. Тоест, не крийте някаква магия за това как да стартирате приложение, как да стартирате работник. В Kubernetes просто изпращате заявка в приложението, ако приложението е написано на Python.

Същото важи и ако отидем отвъд Kubernetes. Нашият Kubernetes работи някъде - добре е, ако е в някакъв вид облак. Отново можем да използваме и дори трябва, според мен, да използваме възможностите на самия облак, където работим. От елементарните неща, които облакът ни предоставя. Балансиране, тоест можем да създадем облачни балансьори и да ги използваме. Това е пряко предимство на това, което можем да използваме. Тъй като балансирането на облака, първо, просто глупаво премахва отговорността от нас за това как работи, как е конфигурирано. Освен това е много удобно, защото обикновеният Kubernetes може да се интегрира с облаци.

Същото важи и за мащабирането. Обикновеният Kubernetes може да се интегрира с облачни доставчици. Знае как да разбере, че ако в клъстера свършат възлите, тоест пространството за възли е изчерпано, тогава трябва да добавите - самият Kubernetes ще добави нови възли към вашия клъстер и ще започне да стартира подове върху тях. Тоест, когато ви дойде натоварването, броят на огнищата започва да се увеличава. Когато възлите в клъстера се изчерпят за тези подове, Kubernetes стартира нови възли и съответно броят на подовете може да се увеличи. И е много удобно. Това е директна възможност за мащабиране на клъстера в движение. Не много бързо, в смисъл, че не е секунда, а по-скоро минута, за да добавите нови възли.

Но от моя опит, отново, това е най-готиното нещо, което съм виждал. Когато клъстерът Cloudnative се мащабира въз основа на времето от деня. Това беше бекенд услуга, която се използваше от хората в бек офиса. Тоест те идват на работа в 9 сутринта, започват да влизат в системата и съответно клъстерът Cloudnative, където всичко работи, започва да набъбва, пускайки нови подове, така че всеки, който идва на работа, да може да работи с приложението. Когато напуснат работа в 8:6 или 30:XNUMX часа, клъстерите на Kubernetes забелязват, че никой вече не използва приложението и започват да се свиват. Гарантирани са спестявания до XNUMX процента. По онова време работеше в Amazon; по това време нямаше никой в ​​Русия, който да го направи толкова добре.

Ще ви кажа направо, спестяванията са 30 процента просто защото използваме Kubernetes и се възползваме от възможностите на облака. Сега това може да се направи в Русия. Няма да правя реклама на никого, разбира се, но нека просто кажем, че има доставчици, които могат да направят това, да го предоставят направо от кутията с бутон.

Има един последен момент, към който бих искал да обърна внимание. За да може вашето приложение, вашата инфраструктура да бъде Cloudnative, има смисъл най-накрая да започнете да адаптирате подхода, наречен Infrastructure as a Code.Тоест това означава, че вашето приложение, или по-скоро вашата инфраструктура, е необходима точно по същия начин, както код Опишете вашето приложение, вашата бизнес логика под формата на код. И работете с него като код, тоест тествайте го, разгръщайте го, съхранявайте го в git, прилагайте CICD към него.

И точно това ви позволява, първо, винаги да имате контрол върху вашата инфраструктура, винаги да разбирате в какво състояние е тя. Второ, избягвайте ръчни операции, които причиняват грешки. Трето, избягвайте просто това, което се нарича текучество, когато постоянно трябва да изпълнявате едни и същи ръчни задачи. Четвърто, ви позволява да се възстановите много по-бързо в случай на повреда. В Русия всеки път, когато говоря за това, винаги има огромен брой хора, които казват: „Да, ясно е, но вие имате подходи, накратко, няма нужда да поправяте нищо“. Но е истина. Ако нещо е счупено във вашата инфраструктура, тогава от гледна точка на подхода Cloudnative и от гледна точка на инфраструктурата като код, вместо да го коригирате, да отидете на сървъра, да разберете какво е счупено и да го поправите, е по-лесно за да изтриете сървъра и да го създадете отново. И ще възстановя всичко това.

Всички тези въпроси са разгледани по-подробно в Kubernetes видео курсове: Junior, Basic, Mega. Следвайки линка можете да се запознаете с програмата и условията. Удобното е, че можете да овладеете Kubernetes, като учите от вкъщи или работите по 1-2 часа на ден.

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

Добавяне на нов коментар