Kubernetes'i rakenduse, asendamise ja plaastri nõuetekohane võrdlus

Kubernetesil on ressursside värskendamiseks mitu võimalust: rakendada, redigeerida, parandada ja asendada. Tekib segadus, mida igaüks teeb ja millal neid kasutada. Selgitame välja.

Kubernetes'i rakenduse, asendamise ja plaastri nõuetekohane võrdlus

kui otsi Google'ist fraas "kubernetes kohaldada vs asendada" asub vastake StackOverflow'le, mis pole õige. Otsides "kubernetes rakendus vs plaaster" esimene link on dokumentatsioon kubectl patch, mis ei sisalda võrdlust apply и patch. Selles artiklis vaadeldakse erinevaid võimalusi ja igaühe õiget kasutamist.

Kubernetese ressursi elutsükli jooksul (teenus, juurutamine, sisenemine jne) peate mõnikord selle ressursi atribuute muutma, lisama või eemaldama. Näiteks lisage märge, suurendage või vähendage koopiate arvu.

Kubernetes CLI

Kui töötate juba CLI kaudu Kubernetese klastritega, olete sellega juba tuttav apply и edit. Meeskond apply loeb failist ressursi spetsifikatsiooni ja teeb Kubernetese klastrisse "upsert", st. loob ressursi, kui seda pole, ja värskendab seda, kui see on olemas. Meeskond edit loeb API kaudu ressurssi, seejärel kirjutab ressursi spetsifikatsiooni kohalikku faili, mis seejärel avatakse tekstiredaktoris. Pärast faili redigeerimist ja salvestamist kubectl saadab tehtud muudatused tagasi API kaudu, mis rakendab need muudatused ressursile hoolikalt.

Kõik ei tea käske patch и replace. Meeskond patch võimaldab muuta osa ressursi spetsifikatsioonist, pakkudes käsureal ainult muudetud osa. Meeskond replace töötab samamoodi nagu edit, kuid kõike tuleb teha käsitsi: peate alla laadima ressursi spetsifikatsiooni praeguse versiooni, näiteks kasutades kubectl get -o yaml, muutke seda ja seejärel kasutage replace ressursi värskendamiseks vastavalt muudetud spetsifikatsioonile. Meeskond replace ei tööta, kui ressursi lugemise ja asendamise vahel toimus muudatusi.

Kubernetes API

Tõenäoliselt olete meetoditega tuttav CoreV1().Pods().Update(), replaceNamespacedService või patch_namespaced_deployment, kui töötate klastritega läbi Kubernetes API klienditeek kasutades mõnda programmeerimiskeelt. Teek käsitleb neid meetodeid HTTP-päringute kaudu, kasutades meetodeid PUT и PATCH... Kusjuures update и replace kasutamine PUTJa patch, ükskõik kui triviaalne see ka poleks, kasutab PATCH.

Tuleb märkida, et kubectl töötab ka klastritega API kaudu. Teisisõnu, kubectlon Go keele klienditeegi peal olev ümbris, mis võimaldab lisaks standardsetele API võimalustele pakkuda ka alamkäske kompaktsemal ja loetavamal kujul. Näiteks, nagu olete juba märganud, meetod apply ei olnud eelmises lõigus mainitud. Praegu (mai 2020, u. tõlkija) kogu loogika kubectl apply, st. olematute ressursside loomine ja olemasolevate uuendamine, töötab täielikult koodi poolel kubectl. Tehakse jõupingutusi loogika ülekande kohta apply API poolele, kuid see on endiselt beetaversioonis. Kirjutan allpool täpsemalt.

Vaikimisi plaaster

Parim kasutatud patch, kui soovite ressurssi värskendada. Nii töötavad mõlemad klienditeegid Kubernetes API peal ja kubectl (pole üllatav, kuna see on klienditeegi ümbris, u. tõlkija).

Töötage strateegiliselt

Kõik meeskonnad kubectl apply, edit и patch kasuta meetodit PATCH HTTP-päringutes olemasoleva ressursi värskendamiseks. Kui käskude juurutamisse lähemalt süveneda, siis kõik need kasutavad lähenemist strateegiline-liitmine lappimine ressursside värskendamiseks, kuigi käsk patch võib kasutada muid lähenemisviise (sellest lähemalt allpool). Strateegilise ühendamise lappimise lähenemisviis püüab "asja õigesti teha", ühendades kaasasoleva spetsifikatsiooni olemasoleva spetsifikatsiooniga. Täpsemalt üritab see kombineerida nii objekte kui ka massiive, mis tähendab, et muudatused kipuvad olema aditiivsed. Näiteks käsu käivitamine patch uue keskkonnamuutuja kasutamisel pod-konteineri spetsifikatsioonis lisatakse see keskkonnamuutuja olemasolevatele keskkonnamuutujatele, mitte ei kirjuta need üle. Selle lähenemisviisi abil eemaldamiseks peate sundima parameetri väärtuse nulliks esitatud spetsifikatsioonis. Milline meeskondadest kubectl Kas seda on kõige parem kasutada värskendamiseks?

Kui loote ja haldate oma ressursse kasutades kubectl apply, värskendamisel on parem alati kasutada kubectl applyKuni kubectl saaks hallata konfiguratsiooni ja õigesti jälgida taotletud muudatusi rakendusest rakendusse. Kasuta alati eelist apply on see, et see jälgib varem rakendatud spetsifikatsiooni, võimaldades tal teada, millal spetsifikatsiooni omadused ja massiivi elemendid on selgesõnaliselt eemaldatud. See võimaldab teil kasutada apply atribuutide ja massiivi elementide eemaldamiseks, samas kui tavaline strateegiline liitmine ei toimi. Meeskonnad edit и patch ära uuenda märgib, et kubectl apply kasutab oma muudatuste jälgimiseks, nii et kõik muudatused, mida jälgitakse ja tehakse Kubernetes API kaudu, kuid tehakse käskude kaudu edit и patch, mis on järgnevate käskude jaoks nähtamatu applySee tähendab, et apply ei eemalda neid isegi siis, kui neid sisendi spetsifikatsioonis ei kuvata apply (Dokumentatsioon ütleb seda edit и patch värskendage kasutatud märkmeid apply, kuid praktikas - ei).

Kui te käsku ei kasuta apply, saab kasutada kui editJa patch, valides tehtavale muudatusele kõige paremini sobiva käsu. BOM-i atribuutide lisamisel ja muutmisel on mõlemad lähenemisviisid ligikaudu samad. Spetsifikatsiooni omaduste või massiivi elementide kustutamisel edit käitub nagu ühekordne käivitamine apply, sealhulgas jälgida, milline oli spetsifikatsioon enne ja pärast redigeerimist, et saaksite ressursist atribuute ja massiivi elemente selgesõnaliselt eemaldada. Peate spetsifikatsioonis atribuudi väärtuseks määrama selgesõnaliselt null patchet see ressursist eemaldada. Massiivi elemendi eemaldamine strateegilise liitmise paikamise abil on keerulisem, kuna see nõuab liitmisjuhiste kasutamist. Elujõulisemate alternatiivide saamiseks vaadake allpool teisi versiooniuuendusviise.

Rakendada klienditeegi värskendusmeetodeid, mis käituvad sarnaselt ülaltoodud käskudega kubectl, tuleks taotlustes määrata content-type в application/strategic-merge-patch+json. Kui soovite spetsifikatsioonist atribuute eemaldada, peate nende väärtused sarnasel viisil määrama nulliks kubectl patch. Kui teil on vaja massiivi elemente eemaldada, peaksite värskenduse spetsifikatsiooni kaasama liitmisjuhised või kasutama värskendustele teistsugust lähenemist.

Muud lähenemisviisid värskendustele

Kubernetes toetab kahte muud värskendusviisi: JSON-i liitmisplaaster и JSON plaaster. JSON-i liitmispaiga lähenemisviis kasutab sisendiks osalist Kubernetesi spetsifikatsiooni ja toetab objektide liitmist, mis on sarnased strateegilise liitmise paigaloleku lähenemisviisiga. Erinevus nende kahe vahel seisneb selles, et see toetab ainult massiivi asendamist, sealhulgas konteineri massiivi podi spetsifikatsioonis. See tähendab, et JSON-i liitmispaiga kasutamisel peate esitama kõigi konteinerite täielikud spetsifikatsioonid juhuks, kui konteineri mis tahes atribuut muutub. Nii et see lähenemine on kasulik elementide eemaldamiseks BOM-i massiivist. Käsurea abil saate valida JSON-i liitmispaiga kubectl patch --type=merge. Kubernetes API-ga töötades peaksite kasutama päringumeetodit PATCH ja paigaldus content-type в application/merge-patch+json.

Ressursi osalise spetsifikatsiooni asemel JSON-i paiga lähenemisviis kasutab ressursis tehtavate muudatuste esitamist massiivina, milles iga massiivi element kujutab endast ressursis tehtavate muudatuste kirjeldust. See lähenemisviis on paindlikum ja võimsam viis tehtavate muudatuste väljendamiseks, kuid selle hinnaga, et muudatused loetletakse eraldi, mitte-Kubernetese vormingus, selle asemel et saata osaline ressursi spetsifikatsioon. IN kubectl saate valida JSON-i plaastri kasutades kubectl patch --type=json. Kubernetes API kasutamisel töötab see lähenemine päringumeetodil PATCH ja paigaldus content-type в application/json-patch+json.

Vajame kindlustunnet – kasutage asendamist

Mõnel juhul peate olema kindel, et ressursis ei tehta muudatusi ressursi lugemise ja värskendamise vahel. Teisisõnu peaksite veenduma, et kõik muudatused tehakse aatomiline. Sel juhul peaksite ressursside värskendamiseks kasutama replace. Näiteks kui teil on ConfigMap loenduriga, mida värskendab mitu allikat, peaksite olema kindel, et kaks allikat ei värskenda loendurit korraga, mis põhjustab värskenduse kadumise. Demonstreerimiseks kujutage seda lähenemisviisi kasutades ette sündmuste jada patch:

  • A ja B saavad API-st ressursi hetkeseisu
  • Igaüks neist värskendab spetsifikatsiooni kohapeal, suurendades loendurit ühe võrra ja lisades märkusele "uuendatud" vastavalt "A" või "B"
  • Ja see värskendab ressurssi veidi kiiremini
  • B värskendab ressurssi

Selle tulemusena kaob värskendus A. Viimane operatsioon patch võidab, loendurit suurendatakse kahe asemel ühe võrra ja märkuse "updated-by" väärtus lõpeb tähega "B" ega sisalda "A"-d. Võrdleme ülaltoodut sellega, mis juhtub, kui värskendusi tehakse selle lähenemisviisi abil replace:

  • A ja B saavad API-st ressursi hetkeseisu
  • Igaüks neist värskendab spetsifikatsiooni kohapeal, suurendades loendurit ühe võrra ja lisades märkusele "uuendatud" vastavalt "A" või "B"
  • Ja see värskendab ressurssi veidi kiiremini
  • B üritab ressurssi värskendada, kuid API lükkab värskenduse tagasi, kuna ressursi versioon on spetsifikatsioonis replace ei ühti Kubernetese ressursi praeguse versiooniga, kuna ressursi versiooni suurendas A asendusoperatsioon.

Ülaltoodud juhul peab B ressursi uuesti hankima, uude olekut muutma ja uuesti proovima replace. See suurendab loendurit kahe võrra ja märkuse "updated-by" lõppu lisatakse "AB".

Ülaltoodud näide viitab sellele, et käivitamisel replace Kogu ressurss asendatakse täielikult. Kasutatud spetsifikatsioon replace, ei tohi olla osaline ega osade kaupa nagu näidatud apply, kuid täielik, sealhulgas täiendus resourceVersion spetsifikatsiooni metaandmetesse. Kui te pole seda lubanud resourceVersion või teie esitatud versioon ei ole ajakohane, lükatakse asendus tagasi. Seega on parim kasutusviis replace – lugege ressurssi, värskendage seda ja asendage see kohe. Kasutades kubectl, võib see välja näha selline:

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

Väärib märkimist, et kaks järgmist järjestikku käivitatavat käsku käivituvad edukalt, kuna deployment.yaml ei sisalda vara .metadata.resourceVersion

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

See oleks justkui vastuolus eelpool öelduga, s.t. "lisades resourceVersion spetsifikatsiooni metaandmetesse." Kas nii öelda on vale? Ei, ei ole, sest kui kubectl märkab, et te ei täpsustanud resourceVersion, loeb see selle ressursist ja lisab selle teie määratud spetsifikatsioonile ning alles seejärel käivitab selle replace. Kuna see on potentsiaalselt ohtlik, kui tuginete aatomilisusele, töötab maagia täielikult küljelt kubectl, ei tohiks te API-ga töötavate klienditeekide kasutamisel sellele tugineda. Sel juhul peate lugema praeguse ressursi spetsifikatsiooni, värskendama seda ja seejärel käivitama PUT nõuda.

Te ei saa plaastrit teha – me asendame

Mõnikord peate tegema muudatusi, mida API ei saa hallata. Sellistel juhtudel saate ressursi sundida asendama, kustutades ja luues selle uuesti. Seda tehakse kasutades kubectl replace --force. Käsu käivitamine eemaldab kohe ressursid ja loob need siis kaasasolevast spetsifikatsioonist uuesti. API-s pole "sundi asendamise" töötlejat ja selleks API kaudu peate tegema kaks toimingut. Kõigepealt peate selle ressursi kustutama, määrates selle gracePeriodSeconds nullini (0) ja propagationPolicy jaotises „Taust” ja seejärel looge see ressurss soovitud spetsifikatsiooniga uuesti.

Hoiatus: see lähenemine on potentsiaalselt ohtlik ja võib viia määratlemata olekuni.

Taotlege serveri poolel

Nagu eespool mainitud, töötavad Kubernetese arendajad selle loogika rakendamise kallal apply kohta kubectl Kubernetes API-s. Loogika apply saadaval Kubernetes 1.18 kaudu kubectl apply --server-side või API kaudu, kasutades meetodit PATCH с content-type application/apply-patch+YAML.

Märkus. JSON on ka kehtiv YAML, nii et saate spetsifikatsiooni JSON-ina saata isegi siis, kui content-type tahe application/apply-patch+yaml.

Peale selle loogika kubectl muutub API kaudu kõigile kättesaadavaks, apply serveri poolel jälgib, kes vastutab spetsifikatsioonis väljade eest, võimaldades seega turvalist mitmekordset juurdepääsu selle konfliktivabaks redigeerimiseks. Teisisõnu, kui apply serveri poolel hakkab laiemalt levima, ilmub erinevatele klientidele universaalne turvaline ressursihaldusliides, näiteks kubectl, Pulumi või Terraform, GitOps, aga ka klienditeeke kasutades isekirjutatud skriptid.

Tulemused

Loodan, et see lühike ülevaade erinevatest viisidest ressursside värskendamiseks klastrites oli teile kasulik. Hea on teada, et see ei ole lihtsalt rakendamine versus asendamine; ressurssi on võimalik värskendada, kasutades rakendust, redigeerimist, paikamist või asendamist. Lõppude lõpuks on igal lähenemisviisil põhimõtteliselt oma rakendusvaldkond. Aatomimuutuste jaoks on eelistatav asendamine, vastasel juhul peaksite kasutama strateegilise ühendamise plaastrit rakenduse kaudu. Vähemalt eeldan, et mõistate, et te ei saa Google'it ega StackOerflow'i usaldada, kui otsite "kubernetes'i rakendamine vs asendamine". Vähemalt seni, kuni see artikkel praeguse vastuse asendab.

Kubernetes'i rakenduse, asendamise ja plaastri nõuetekohane võrdlus

Allikas: www.habr.com

Lisa kommentaar