Кубернетес има неколико опција за ажурирање ресурса: примени, уреди, закрпи и замени. Постоји конфузија око тога шта сваки од њих ради и када да их користи. Хајде да то схватимо.
Ако kubectl patch
, што не укључује поређење apply
и patch
. Овај чланак ће размотрити различите опције, као и правилну употребу сваке од њих.
Током животног циклуса Кубернетес ресурса (услуга, примена, улаз, итд.), понекад морате да промените, додате или уклоните нека својства овог ресурса. На пример, додајте белешку, повећајте или смањите број реплика.
Кубернетес ЦЛИ
Ако већ радите са Кубернетес кластерима преко ЦЛИ, већ сте упознати apply
и edit
. Тим apply
чита спецификацију ресурса из датотеке и прави "упсерт" у Кубернетес кластер, тј. креира ресурс ако не постоји и ажурира га ако постоји. Тим edit
чита ресурс преко АПИ-ја, а затим уписује спецификацију ресурса у локалну датотеку, која се затим отвара у уређивачу текста. Након што уредите и сачувате датотеку, kubectl
ће послати промене направљене назад преко АПИ-ја, који ће пажљиво применити ове промене на ресурс.
Не знају сви команде patch
и replace
. Тим patch
омогућава вам да промените део спецификације ресурса, пружајући само промењени део на командној линији. Тим replace
ради исто као edit
, али све треба да се уради ручно: потребно је да преузмете тренутну верзију спецификације ресурса, на пример, користећи kubectl get -o yaml
, уредите га, а затим користите replace
да ажурирате ресурс према измењеној спецификацији. Тим replace
неће радити ако је дошло до било каквих промена између читања и замене ресурса.
Кубернетес АПИ
Вероватно сте упознати са методама CoreV1().Pods().Update()
, replaceNamespacedService
или patch_namespaced_deployment
, ако радите са кластерима преко PUT
и PATCH
... У чему update
и replace
употреба PUT
И patch
, ма колико то било тривијално, користи PATCH
.
Треба напоменути да kubectl
такође ради са кластерима преко АПИ-ја. Другим речима, kubectl
је омот на врху клијентске библиотеке за језик Го, који у великој мери пружа могућност пружања подкоманди у компактнијем и читљивијем облику поред стандардних АПИ могућности. На пример, као што сте можда већ приметили, метод apply
није поменуто у претходном ставу. Тренутно (мај 2020. прибл. преводилац) сва логика kubectl apply
, тј. креирање непостојећих ресурса и ажурирање постојећих, ради у потпуности на страни кода kubectl
. Улажу се напори apply
на страну АПИ-ја, али је још увек у бета верзији. У наставку ћу писати детаљније.
Закрпа подразумевано
Најбоље се користи patch
, ако желите да ажурирате ресурс. Овако обе клијентске библиотеке раде на врху Кубернетес АПИ-ја и kubectl
(није изненађујуће, пошто је то омот за клијентску библиотеку, прибл. преводилац).
Радите стратешки
Сви тимови kubectl
apply
, edit
и patch
користите метод PATCH
у ХТТП захтевима за ажурирање постојећег ресурса. Ако се детаљније задубите у имплементацију команди, онда сви користе приступ patch
може користити друге приступе (више о томе у наставку). Приступ стратешког спајања закрпа покушава да се „исправи како треба“ спајањем испоручене спецификације са постојећом спецификацијом. Тачније, покушава да комбинује и објекте и низове, што значи да промене имају тенденцију да буду адитивне. На пример, покретање команде patch
са новом променљивом окружења у спецификацији контејнера под, доводи до тога да се та променљива окружења дода постојећим променљивим окружења уместо да их преписује. Да бисте уклонили користећи овај приступ, морате присилити вредност параметра на нулл у датој спецификацији. Који од тимова kubectl
Да ли је најбоље користити за ажурирање?
Ако креирате и управљате својим ресурсима користећи kubectl apply
, при ажурирању је боље увек користити kubectl apply
, чтоби kubectl
могао да управља конфигурацијом и правилно прати тражене промене од апликације до апликације. Предност увек користите apply
је да прати претходно примењену спецификацију, омогућавајући јој да зна када су својства спецификације и елементи низа експлицитно уклоњени. Ово вам омогућава да користите apply
да уклони својства и елементе низа, док нормално стратешко спајање неће функционисати. Тимови edit
и patch
не ажурирајте белешке које kubectl apply
користи за праћење његових промена, тако да све промене које се прате и праве преко Кубернетес АПИ-ја, али су направљене преко команди edit
и patch
, невидљив за наредне команде apply
То је, apply
не уклања их чак и ако се не појављују у улазној спецификацији за apply
(То каже документација edit
и patch
извршите ажурирање коришћених белешки apply
, али у пракси - не).
Ако не користите команду apply
, може се користити као edit
И patch
, бирајући команду која најбоље одговара промени која се врши. Када се додају и мењају својства саставнице, оба приступа су отприлике иста. Приликом брисања својстава спецификације или елемената низа edit
понаша се као једнократно лансирање apply
, укључујући праћење тога каква је спецификација била пре и након што је уређена, тако да можете експлицитно уклонити својства и елементе низа из ресурса. Морате експлицитно да подесите вредност својства на нулл у спецификацији за patch
да га уклоните са ресурса. Уклањање елемента низа коришћењем закрпа стратешког спајања је сложеније јер захтева употребу директива спајања. Погледајте друге приступе надоградњи у наставку за одрживије алтернативе.
Да имплементирате методе ажурирања у библиотеци клијента које се понашају слично горњим командама kubectl
, треба поставити у захтевима content-type
в application/strategic-merge-patch+json
. Ако желите да уклоните својства у спецификацији, морате експлицитно да подесите њихове вредности на нулл на сличан начин kubectl patch
. Ако треба да уклоните елементе низа, требало би да укључите директиве спајања у спецификацију ажурирања или користите другачији приступ ажурирањима.
Други приступи ажурирању
Кубернетес подржава још два приступа ажурирању: kubectl patch --type=merge
. Када радите са Кубернетес АПИ-јем, требало би да користите метод захтева PATCH
и уградњу content-type
в application/merge-patch+json
.
Приступ ЈСОН закрпе, уместо да пружа делимичну спецификацију ресурса, користи пружање промена које желите да унесете у ресурс као низ, у коме сваки елемент низа представља опис промене која се врши на ресурсу. Овај приступ је флексибилнији и моћнији начин да се изразе промене које се праве, али по цену навођења измена које се праве у засебном, не-Кубернетес формату, уместо слања делимичне спецификације ресурса. ИН kubectl
можете изабрати ЈСОН закрпу користећи kubectl patch --type=json
. Када користите Кубернетес АПИ, овај приступ функционише користећи метод захтева PATCH
и уградњу content-type
в application/json-patch+json
.
Треба нам самопоуздање - користите замени
У неким случајевима, морате да будете сигурни да нема промена на ресурсу између времена читања и ажурирања. Другим речима, требало би да будете сигурни да ће све промене бити атомски. У овом случају, за ажурирање ресурса треба да користите replace
. На пример, ако имате ЦонфигМап са бројачем који се ажурира из више извора, требало би да будете сигурни да два извора не ажурирају бројач у исто време, што доводи до губитка ажурирања. Да бисте демонстрирали, замислите низ догађаја користећи приступ patch
:
- А и Б добијају тренутно стање ресурса из АПИ-ја
- Сваки локално ажурира спецификацију повећањем бројача за један и додавањем „А“ или „Б“ респективно у напомену „ажурирано од стране“
- И ажурира ресурс мало брже
- Б ажурира ресурс
Као резултат тога, ажурирање А је изгубљено. Последња операција patch
победа, бројач се повећава за један уместо за два, а вредност напомене „ажурирано од стране“ завршава се са „Б“ и не садржи „А“. Хајде да упоредимо горе наведено са оним што се дешава када се ажурирања врше коришћењем приступа replace
:
- А и Б добијају тренутно стање ресурса из АПИ-ја
- Сваки локално ажурира спецификацију повећањем бројача за један и додавањем „А“ или „Б“ респективно у напомену „ажурирано од стране“
- И ажурира ресурс мало брже
- Б покушава да ажурира ресурс, али АПИ одбија ажурирање јер је верзија ресурса у спецификацији
replace
не подудара се са тренутном верзијом ресурса у Кубернетес-у јер је верзија ресурса повећана А-овом операцијом замене.
У горњем случају, Б ће морати поново да преузме ресурс, изврши промене у новом стању и покуша поново replace
. Ово ће довести до тога да се бројач повећа за два и да напомена „ажурирано од стране“ укључи „АБ“ на крају.
Горњи пример имплицира да приликом извршавања 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
, не бисте се требали ослањати на њега када користите клијентске библиотеке које раде са АПИ-јем. У овом случају ћете морати да прочитате тренутну спецификацију ресурса, да је ажурирате и затим извршите PUT
захтев.
Не можете да урадите закрпу - ми вршимо замену
Понекад морате да направите неке измене које АПИ не може да обради. У овим случајевима, можете присилити замену ресурса тако што ћете га избрисати и поново креирати. Ово се ради помоћу kubectl replace --force
. Извођење команде одмах уклања ресурсе, а затим их поново креира из испоручене спецификације. У АПИ-ју не постоји руковалац „присилне замене“, а да бисте то урадили преко АПИ-ја, потребно је да извршите две операције. Прво морате да избришете ресурс тако што ћете га поставити gracePeriodSeconds
на нулу (0) и propagationPolicy
у „Позадина“, а затим поново креирајте овај ресурс са жељеном спецификацијом.
Упозорење: Овај приступ је потенцијално опасан и може довести до недефинисаног стања.
Примените на страни сервера
Као што је горе поменуто, Кубернетес програмери раде на имплементацији логике apply
од kubectl
у Кубернетес АПИ-ју. Логика apply
доступно у Кубернетес 1.18 преко kubectl apply --server-side
или преко АПИ-ја користећи метод PATCH
с content-type
application/apply-patch+YAML
.
Напомена: ЈСОН је такође важећи ИАМЛ, тако да можете послати спецификацију као ЈСОН чак и ако
content-type
вољаapplication/apply-patch+yaml
.
Поред те логике kubectl
постаје доступан свима преко АПИ-ја, apply
на страни сервера, прати ко је одговоран за поља у спецификацији, омогућавајући тако сигуран вишеструки приступ за његово уређивање без сукоба. Другим речима, ако apply
на страни сервера ће постати све распрострањенији, појавиће се универзални безбедни интерфејс за управљање ресурсима за различите клијенте, на пример, кубецтл, Пулуми или Терраформ, ГитОпс, као и самостално писане скрипте које користе клијентске библиотеке.
Резултати
Надам се да вам је овај кратак преглед различитих начина ажурирања ресурса у кластерима био од помоћи. Добро је знати да није само примена насупрот замене, могуће је ажурирати ресурс помоћу примене, измене, закрпе или замене. На крају крајева, у принципу, сваки приступ има своју област примене. За атомске промене, замена је пожељнија, у супротном, требало би да користите закрпу стратешког спајања путем апликације. У најмању руку, очекујем да схватите да не можете да верујете Гоогле-у или СтацкОерфлов-у када тражите „кубернетес примена вс замена“. Барем док овај чланак не замени тренутни одговор.
Извор: ввв.хабр.цом