Правилна споредба на Kubernetes Примени, замени и закрпи

Kubernetes има неколку опции за ажурирање на ресурсите: примени, уреди, закрпи и замени. Постои конфузија околу тоа што прави секој од нив и кога да ги користи. Ајде да го сфатиме.

Правилна споредба на Kubernetes Примени, замени и закрпи

Ако пребарување на Google се наоѓа фразата „kubernetes применуваат vs замени“. одговорете на StackOverflow, што не е точно. При пребарувањето „kubernetes application vs patch“ првата врска е документацијата за kubectl patch, што не вклучува споредба apply и patch. Оваа статија ќе ги разгледа различните опции, како и правилната употреба на секоја од нив.

За време на животниот циклус на ресурсот на Kubernetes (услуга, распоредување, влез итн.), понекогаш треба да промените, додадете или отстраните некои својства на овој ресурс. На пример, додадете белешка, зголемете или намалете го бројот на реплики.

Kubernetes CLI

Ако веќе работите со кластерите на Kubernetes преку CLI, веќе сте запознаени apply и edit. Тим apply ја чита спецификацијата на ресурсите од датотеката и прави „upsert“ во кластерот Kubernetes, т.е. го создава ресурсот доколку не постои и го ажурира доколку постои. Тим edit чита ресурс преку API, а потоа ја запишува спецификацијата на ресурсите во локална датотека, која потоа се отвора во текстуален уредувач. Откако ќе ја уредите и зачувате датотеката, kubectl ќе ги испрати промените направени назад преку API, кој внимателно ќе ги примени овие промени на ресурсот.

Не сите ги знаат командите patch и replace. Тим patch ви овозможува да промените дел од спецификацијата на ресурсите, обезбедувајќи го само променетиот дел на командната линија. Тим replace работи исто како edit, но сè треба да се направи рачно: треба да ја преземете тековната верзија на спецификацијата на ресурсите, на пример, користејќи kubectl get -o yaml, уредете го, па употребете replace за ажурирање на ресурс според изменета спецификација. Тим replace нема да работи ако се случат какви било промени помеѓу читањето и заменувањето на ресурсот.

Kubernetes API

Веројатно сте запознаени со методите CoreV1().Pods().Update(), replaceNamespacedService или patch_namespaced_deployment, ако работите со кластери преку клиентска библиотека за Kubernetes API користејќи некој програмски јазик. Библиотеката се справува со овие методи преку HTTP барања користејќи ги методите PUT и PATCH... При што update и replace употреба PUTИ patch, колку и да е тривијално, користи PATCH.

Треба да се напомене дека kubectl работи и со кластери преку API. Со други зборови, kubectlе обвивка на врвот на библиотеката на клиентите за јазикот Go, кој во голема мера обезбедува можност за обезбедување на подкоманди во покомпактна и почитлива форма покрај стандардните API способности. На пример, како што веќе сте забележале, методот apply не беше споменато погоре во претходниот став. Во моментов (мај 2020 г., прибл. преведувач) целата логика kubectl apply, т.е. создавање непостоечки ресурси и ажурирање на постојните, работи целосно на страната на кодот kubectl. Се прават напори на логички трансфер apply на страната на API, но сè уште е во бета верзија. Подолу ќе напишам подетално.

Закрпи стандардно

Најдобро се користи patch, ако сакате да го ажурирате ресурсот. Вака работат двете библиотеки на клиенти на врвот на Kubernetes API и kubectl (не е изненадувачки, бидејќи тоа е обвивка за библиотеката на клиентите, прибл. преведувач).

Работете стратешки

Сите тимови kubectl apply, edit и patch користете го методот PATCH во HTTP бара ажурирање на постоечки ресурс. Ако истражувате подетално во спроведувањето на командите, тогаш сите го користат пристапот стратегиско-спојување крпење за ажурирање на ресурсите, иако командата patch може да користи други пристапи (повеќе за ова подолу). Пристапот за поправање на стратегиско спојување се обидува да го „добие правилно“ со спојување на испорачаната спецификација со постоечката спецификација. Поконкретно, се обидува да ги комбинира и објектите и низите, што значи дека промените имаат тенденција да бидат адитивни. На пример, извршување на командата patch со нова променлива на животната средина во спецификацијата на контејнерот на pod, предизвикува таа променлива на животната средина да се додаде на постојните променливи на животната средина наместо да ги презапише. За да го отстраните користејќи го овој пристап, мора да ја присилите вредноста на параметарот да биде нула во дадената спецификација. Кој од тимовите kubectl Дали е најдобро да се користи за ажурирање?

Ако креирате и управувате со вашите ресурси користејќи kubectl apply, при ажурирање е подобро секогаш да се користи kubectl applyтака што kubectl може да управува со конфигурацијата и правилно да ги следи бараните промени од апликација до апликација. Предност секогаш користете apply е тоа што ја следи претходно применетата спецификација, овозможувајќи му да знае кога својствата на спецификацијата и елементите на низата се експлицитно отстранети. Ова ви овозможува да користите apply да се отстранат својствата и елементите на низата, додека нормалното стратегиско спојување нема да работи. Тимови edit и patch не ажурирајте белешки дека kubectl apply користи за следење на неговите промени, така што сите промени што се следат и направени преку Kubernetes API, но направени преку команди edit и patch, невидлив за следните команди applyШто е, apply не ги отстранува дури и ако не се појавуваат во влезната спецификација за apply (Документацијата го кажува тоа edit и patch направете ажурирања на користените белешки apply, но во пракса - не).

Ако не ја користите командата apply, може да се користи како editИ patch, избирајќи ја командата што најмногу одговара на промената што се прави. При додавање и менување на својствата на BOM, двата пристапи се приближно исти. При бришење на својствата на спецификацијата или елементите на низата edit се однесува како еднократно лансирање apply, вклучувајќи следење на тоа каква била спецификацијата пред и по нејзиното уредување, за да можете експлицитно да ги отстраните својствата и елементите на низата од ресурсот. Треба експлицитно да ја поставите вредноста на имотот како нула во спецификацијата за patchда го отстраните од ресурсот. Отстранувањето на елемент од низа со користење на стратешко-спојување е покомплексно бидејќи бара употреба на директиви за спојување. Погледнете ги другите пристапи за надградба подолу за поодржливи алтернативи.

Да се ​​имплементираат методи за ажурирање во библиотеката на клиентите кои се однесуваат слично на командите погоре kubectl, треба да се постави во барањата content-type в application/strategic-merge-patch+json. Ако сакате да ги отстраните својствата во спецификација, треба експлицитно да ги поставите нивните вредности како нула на сличен начин kubectl patch. Ако треба да ги отстраните елементите на низата, треба да вклучите директиви за спојување во спецификацијата за ажурирање или да користите различен пристап кон ажурирањата.

Други пристапи за ажурирања

Kubernetes поддржува два други пристапи за ажурирање: Закрпа за спојување на JSON и JSON лепенка. Пристапот на закрпи за спојување JSON зема делумна спецификација на Kubernetes како влез и поддржува спојување на објекти слични на пристапот за поправање со стратешко спојување. Разликата помеѓу двете е тоа што поддржува само замена на низи, вклучувајќи ја и низата на контејнери во спецификацијата на подлогата. Ова значи дека кога користите закрпа за спојување на JSON, треба да обезбедите целосни спецификации за сите контејнери во случај да се промени било кое својство на кој било контејнер. Значи, овој пристап е корисен за отстранување на елементи од низа во BOM. На командната линија можете да изберете JSON merge patch со користење kubectl patch --type=merge. Кога работите со Kubernetes API, треба да го користите методот на барање PATCH и инсталација content-type в application/merge-patch+json.

Пристапот за закрпи JSON, наместо да обезбедува делумна спецификација на ресурсот, користи обезбедување на промените што сакате да ги направите на ресурсот како низа, во која секој елемент од низата претставува опис на промената што се прави на ресурсот. Овој пристап е пофлексибилен и помоќен начин за изразување на промените што се прават, но по цена да се наведат промените направени во посебен, не-Kubernetes формат, наместо да се испраќа делумна спецификација на ресурсите. ВО kubectl можете да изберете JSON лепенка користејќи kubectl patch --type=json. Кога се користи Kubernetes API, овој пристап работи со методот на барање PATCH и инсталација content-type в application/json-patch+json.

Потребна ни е доверба - користете заменете

Во некои случаи, треба да бидете сигурни дека не се прават промени на некој ресурс помеѓу времето кога ресурсот се чита и кога се ажурира. Со други зборови, треба да бидете сигурни дека сите промени ќе бидат атомски. Во овој случај, за ажурирање на ресурсите што треба да ги користите replace. На пример, ако имате ConfigMap со бројач што се ажурира од повеќе извори, треба да бидете сигурни дека два извора не го ажурираат бројачот истовремено, што предизвикува ажурирањето да се изгуби. За да покажете, замислете секвенца на настани користејќи го пристапот patch:

  • А и Б ја добиваат моменталната состојба на ресурсот од API
  • Секој од нив локално ја ажурира спецификацијата со зголемување на бројачот за еден и исто така додавање на „A“ или „B“, соодветно на белешката „updated-by“
  • И малку побрзо го ажурира ресурсот
  • Б го ажурира ресурсот

Како резултат на тоа, ажурирањето А е изгубено. Последна операција patch победи, бројачот се зголемува за еден наместо за два, а вредноста на белешката „updated-by“ завршува со „B“ и не содржи „A“. Ајде да го споредиме горенаведеното со она што се случува кога ажурирањата се вршат со користење на пристапот replace:

  • А и Б ја добиваат моменталната состојба на ресурсот од API
  • Секој од нив локално ја ажурира спецификацијата со зголемување на бројачот за еден и исто така додавање на „A“ или „B“, соодветно на белешката „updated-by“
  • И малку побрзо го ажурира ресурсот
  • Б се обидува да го ажурира ресурсот, но ажурирањето е одбиено од API бидејќи верзијата на ресурсите е во спецификацијата replace не се совпаѓа со тековната верзија на ресурсот во Кубернетес бидејќи верзијата на ресурсот беше зголемена со операцијата за замена на А.

Во горенаведениот случај, B ќе мора повторно да го преземе ресурсот, да направи промени во новата состојба и да се обиде повторно replace. Ова ќе предизвика бројачот да се зголеми за два и белешката „updated-by“ да го вклучи „AB“ на крајот.

Горенаведениот пример имплицира дека при извршувањето replace Целиот ресурс е целосно заменет. Спецификација што се користи за replace, не смее да биде делумно, или во делови како во apply, но комплетен, вклучувајќи го и додатокот resourceVersion во метаподатоците на спецификацијата. Ако не сте овозможиле resourceVersion или верзијата што ја давате не е актуелна, замената ќе биде одбиена. Така, најдобриот пристап за употреба е replace – прочитајте го ресурсот, ажурирајте го и заменете го веднаш. Користење на kubectl, може да изгледа вака:

$ kubectl get deployment my-deployment -o json 
    | jq '.spec.template.spec.containers[0].env[1].value = "new value"' 
    | kubectl replace -f -

Вреди да се напомене дека следните две команди, извршени последователно, ќе се извршат успешно, бидејќи deployment.yaml не содржи имот .metadata.resourceVersion

$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml

Се чини дека ова е во спротивност со она што беше кажано погоре, т.е. “, додавајќи resourceVersion во метаподатоците за спецификацијата." Дали е погрешно да се каже тоа? Не, не е, затоа што ако kubectl известувања што не сте ги навеле resourceVersion, ќе го прочита од ресурсот и ќе го додаде во спецификацијата што ја наведовте и дури потоа ќе ја изврши replace. Бидејќи ова е потенцијално опасно ако се потпрете на атомичноста, магијата работи целосно на страна kubectl, не треба да се потпирате на него кога користите библиотеки на клиенти кои работат со API. Во овој случај, ќе треба да ја прочитате тековната спецификација на ресурсите, да ја ажурирате и потоа да ја извршите PUT барање.

Не можете да направите лепенка - правиме замена

Понекогаш треба да направите некои промени со кои API не може да се справи. Во овие случаи, можете да присилите замена на ресурсот со бришење и повторно создавање. Ова се прави со користење kubectl replace --force. Извршувањето на командата веднаш ги отстранува ресурсите и потоа ги пресоздава од испорачаната спецификација. Во API нема управувач за „force replace“, а за да го направите тоа преку API, треба да извршите две операции. Прво треба да го избришете ресурсот со поставување за него gracePeriodSeconds до нула (0) и propagationPolicy во „Позадина“ и потоа повторно креирајте го овој ресурс со саканата спецификација.

Предупредување: Овој пристап е потенцијално опасен и може да доведе до недефинирана состојба.

Примени на страната на серверот

Како што споменавме погоре, развивачите на Kubernetes работат на спроведување на логиката apply на kubectl во Kubernetes API. Логики apply достапно во Kubernetes 1.18 преку kubectl apply --server-side или преку API користејќи го методот PATCH с content-type application/apply-patch+YAML.

Забелешка: JSON е исто така валиден YAML, така што можете да ја испратите спецификацијата како JSON дури и ако content-type ќе application/apply-patch+yaml.

Покрај таа логика kubectl станува достапен за секого преку API, apply на страната на серверот, следи кој е одговорен за полињата во спецификацијата, со што овозможува безбеден повеќекратен пристап за негово уредување без конфликти. Со други зборови, ако apply на страната на серверот ќе стане пошироко распространет, ќе се појави универзален безбеден интерфејс за управување со ресурси за различни клиенти, на пример, kubectl, Pulumi или Terraform, GitOps, како и самонапишани скрипти кои користат библиотеки на клиенти.

Резултатите од

Се надевам дека овој краток преглед на различни начини за ажурирање на ресурсите во кластерите беше корисен за вас. Добро е да се знае дека не е само примена наспроти замена, можно е да се ажурира ресурс со примена, уредување, закрпи или замена. На крајот на краиштата, во принцип, секој пристап има своја област на примена. За атомски промени, се претпочита замена, во спротивно, треба да користите закрпа за стратегиско спојување преку апликација; Во најмала рака, очекувам да разберете дека не можете да му верувате на Google или StackOerflow кога пребарувате за „kubernetes применуваат против замени“. Барем додека овој напис не го замени сегашниот одговор.

Правилна споредба на Kubernetes Примени, замени и закрпи

Извор: www.habr.com

Додадете коментар