Kubernetes Apply, Replace ja Patch -asetusten oikea vertailu

Kubernetesilla on useita vaihtoehtoja resurssien päivittämiseen: käytä, muokkaa, korjaa ja korvaa. On epäselvyyttä siitä, mitä kukin tekee ja milloin niitä käytetään. Selvitetään se.

Kubernetes Apply, Replace ja Patch -asetusten oikea vertailu

Jos etsi Googlesta lause "kubernetes soveltaa vs korvaa" sijaitsee vastaa StackOverflow:lle, mikä ei pidä paikkaansa. Kun etsitään "kubernetes apply vs patch" ensimmäinen linkki on dokumentaatio kubectl patch, joka ei sisällä vertailua apply и patch. Tässä artikkelissa tarkastellaan eri vaihtoehtoja sekä kunkin oikeanlaista käyttöä.

Kubernetes-resurssin elinkaaren aikana (palvelu, käyttöönotto, sisääntulo jne.) sinun on joskus muutettava, lisättävä tai poistettava joitain tämän resurssin ominaisuuksia. Voit esimerkiksi lisätä muistiinpanon, lisätä tai vähentää kopioiden määrää.

Kubernetes CLI

Jos työskentelet jo Kubernetes-klustereiden kanssa CLI:n kautta, olet jo perehtynyt siihen apply и edit. Tiimi apply lukee tiedostosta resurssimäärityksen ja tekee "upsertin" Kubernetes-klusteriin, ts. luo resurssin, jos sitä ei ole, ja päivittää sen, jos se on olemassa. Tiimi edit lukee resurssin API:n kautta ja kirjoittaa sitten resurssimäärittelyn paikalliseen tiedostoon, joka avataan sitten tekstieditorissa. Kun olet muokannut ja tallentanut tiedoston, kubectl lähettää tehdyt muutokset takaisin API:n kautta, joka ottaa nämä muutokset huolellisesti käyttöön resurssissa.

Kaikki eivät osaa käskyjä patch и replace. Tiimi patch antaa sinun muuttaa osaa resurssimäärityksestä ja tarjota vain muutettu osa komentorivillä. Tiimi replace toimii samoin kuin edit, mutta kaikki on tehtävä manuaalisesti: sinun on ladattava resurssimäärityksen nykyinen versio esimerkiksi käyttämällä kubectl get -o yaml, muokkaa sitä ja käytä sitten replace päivittääksesi resurssin muuttuneen määrityksen mukaisesti. Tiimi replace ei toimi, jos resurssin lukemisen ja vaihtamisen välillä on tapahtunut muutoksia.

Kubernetes API

Olet luultavasti perehtynyt menetelmiin CoreV1().Pods().Update(), replaceNamespacedService tai patch_namespaced_deployment, jos työskentelet klustereiden kanssa kautta asiakaskirjasto Kubernetes API:lle käyttämällä jotain ohjelmointikieltä. Kirjasto käsittelee näitä menetelmiä HTTP-pyyntöjen kautta käyttämällä menetelmiä PUT и PATCH... Jossa update и replace käyttää PUTJa patch, olipa se kuinka triviaalia tahansa, käyttötarkoituksia PATCH.

On syytä huomata, että kubectl toimii myös klustereiden kanssa API:n kautta. Toisin sanoen, kubectlon Go-kielen asiakaskirjaston päällä oleva kääre, joka tarjoaa suurelta osin mahdollisuuden tarjota alikomennot kompaktemmassa ja luettavammassa muodossa tavallisten API-ominaisuuksien lisäksi. Esimerkiksi, kuten olet ehkä jo huomannut, menetelmä apply ei mainittu yllä edellisessä kappaleessa. Tällä hetkellä (toukokuu 2020, noin kääntäjä) kaikki logiikka kubectl apply, eli Olemattomien resurssien luominen ja olemassa olevien päivitys toimii täysin koodipuolella kubectl. Pyrkimyksiä tehdään logiikan siirrossa apply API-puolelle, mutta se on vielä beta-vaiheessa. Kirjoitan alla tarkemmin.

Patch oletuksena

Paras käytetty patch, jos haluat päivittää resurssin. Näin molemmat asiakaskirjastot toimivat Kubernetes API:n ja kubectl (ei yllättävää, koska se on asiakaskirjaston kääre, noin kääntäjä).

Työskentele strategisesti

Kaikki joukkueet kubectl apply, edit и patch käytä menetelmää PATCH HTTP-pyynnöissä olemassa olevan resurssin päivittämiseksi. Jos perehdyt komentojen toteuttamiseen yksityiskohtaisemmin, ne kaikki käyttävät lähestymistapaa strateginen yhdistäminen paikkaus resurssien päivittämiseen, vaikka komento patch voi käyttää muita lähestymistapoja (lisätietoja alla). Strategisen yhdistämisen korjausmenetelmä yrittää saada sen oikein yhdistämällä toimitettu spesifikaatio olemassa olevaan spesifikaatioon. Tarkemmin sanottuna se yrittää yhdistää sekä objekteja että taulukoita, mikä tarkoittaa, että muutokset ovat yleensä additiivisia. Esimerkiksi komennon suorittaminen patch uudella ympäristömuuttujalla pod-säilön määrittelyssä aiheuttaa sen, että ympäristömuuttuja lisätään olemassa oleviin ympäristömuuttujiin sen sijaan, että ne korvataan. Jos haluat poistaa tämän menetelmän avulla, sinun on pakotettava parametrin arvo nollaksi toimitetussa määrityksessä. Kumpi joukkueista kubectl Onko parasta käyttää päivitykseen?

Jos luot ja hallitset resurssejasi käyttämällä kubectl apply, päivitettäessä on parempi käyttää aina kubectl applyVoit kubectl voi hallita määrityksiä ja seurata oikein pyydettyjä muutoksia sovelluksesta toiseen. Käytä aina etua apply on, että se seuraa aiemmin sovellettua spesifikaatiota, jolloin se tietää, milloin spesifikaation ominaisuudet ja taulukon elementit on eksplisiittisesti poistettu. Tämän avulla voit käyttää apply poistaa ominaisuuksia ja taulukon elementtejä, kun taas normaali strateginen yhdistäminen ei toimi. Joukkueet edit и patch älä päivitä muistiinpanoja kubectl apply käyttää muutosten seuraamiseen, joten kaikki muutokset, joita seurataan ja tehdään Kubernetes API:n kautta, mutta jotka tehdään komentojen kautta edit и patch, näkymätön myöhemmille komentoille applyToisin sanoen, apply ei poista niitä, vaikka ne eivät näy syöttömäärityksessä apply (Dokumentissa sanotaan niin edit и patch tehdä päivityksiä käytettyihin muistiinpanoihin apply, mutta käytännössä - ei).

Jos et käytä komentoa apply, voidaan käyttää mm editJa patch, valitsemalla komennon, joka parhaiten sopii tehtävään muutokseen. Kun lisäät ja muutat BOM-ominaisuuksia, molemmat lähestymistavat ovat suunnilleen samat. Kun poistetaan määrittelyominaisuuksia tai taulukon elementtejä edit käyttäytyy kuin kertakäynnistys apply, mukaan lukien sen, miltä määritys oli ennen ja jälkeen muokkauksen, jotta voit poistaa ominaisuuksia ja taulukkoelementtejä resurssista. Sinun on nimenomaisesti asetettava ominaisuuden arvoksi nolla spesifikaatioissa for patchpoistaaksesi sen resurssista. Matriisielementin poistaminen strategisen yhdistämisen korjauksella on monimutkaisempaa, koska se vaatii yhdistämiskäskyjen käyttöä. Katso muita päivitysmenetelmiä alta saadaksesi käyttökelpoisempia vaihtoehtoja.

Toteuttaa asiakaskirjastoon päivitysmenetelmiä, jotka toimivat samalla tavalla kuin yllä olevat komennot kubectl, tulee asettaa pyyntöihin content-type в application/strategic-merge-patch+json. Jos haluat poistaa ominaisuuksia spesifikaatiosta, sinun on nimenomaisesti asetettava niiden arvot nollaksi samalla tavalla kubectl patch. Jos sinun on poistettava taulukkoelementtejä, sinun tulee sisällyttää yhdistämiskäskyt päivitysmääritykseen tai käyttää erilaista lähestymistapaa päivityksiin.

Muut lähestymistavat päivityksiin

Kubernetes tukee kahta muuta päivitystapaa: JSON-yhdistyskorjaus и JSON-korjaus. JSON-yhdistyskorjaustapa käyttää osittaista Kubernetes-spesifikaatiota syötteenä ja tukee objektien yhdistämistä, joka on samanlainen kuin strategisen yhdistämisen korjausmenetelmä. Ero näiden kahden välillä on, että se tukee vain taulukon korvaamista, mukaan lukien säiliötaulukon pod-määrittelyssä. Tämä tarkoittaa, että kun käytät JSON-yhdistyskorjausta, sinun on annettava täydelliset tiedot kaikille säilöille siltä varalta, että jokin säilön ominaisuus muuttuu. Joten tämä lähestymistapa on hyödyllinen elementtien poistamiseen materiaaliluettelon taulukosta. Voit valita komentoriviltä JSON-yhdistämiskorjauksen käyttämällä kubectl patch --type=merge. Kun työskentelet Kubernetes API:n kanssa, sinun tulee käyttää pyyntömenetelmää PATCH ja asennus content-type в application/merge-patch+json.

JSON-korjauslähestymistapassa resurssin osittaisen määrittelyn sijaan käytetään resurssiin tehtävät muutokset taulukkona, jossa jokainen taulukon elementti edustaa kuvausta resurssiin tehtävästä muutoksesta. Tämä lähestymistapa on joustavampi ja tehokkaampi tapa ilmaista tehdyt muutokset, mutta sen kustannuksella, että tehdyt muutokset luetellaan erillisessä, ei-Kubernetes-muodossa, sen sijaan, että lähetettäisiin osittainen resurssimääritys. SISÄÄN kubectl voit valita JSON-korjauksen käyttämällä kubectl patch --type=json. Kubernetes API:ta käytettäessä tämä lähestymistapa toimii pyyntömenetelmällä PATCH ja asennus content-type в application/json-patch+json.

Tarvitsemme luottamusta - käytä korvaavaa

Joissakin tapauksissa sinun on varmistettava, että resurssiin ei tehdä muutoksia resurssin lukemisen ja päivityksen välillä. Toisin sanoen, sinun tulee varmistaa, että kaikki muutokset tulevat voimaan atomi-. Tässä tapauksessa sinun tulee käyttää resurssien päivittämistä replace. Jos sinulla on esimerkiksi ConfigMap, jonka laskuri on päivitetty useista lähteistä, sinun tulee olla varma, että kaksi lähdettä eivät päivitä laskuria samanaikaisesti, jolloin päivitys katoaa. Havainnollistaaksesi kuvittele tapahtumasarja lähestymistavan avulla patch:

  • A ja B saavat resurssin nykyisen tilan API:lta
  • Jokainen päivittää spesifikaation paikallisesti lisäämällä laskuria yhdellä ja lisäämällä "A" tai "B" vastaavasti "päivitetty" -merkintään.
  • Ja se päivittää resurssin hieman nopeammin
  • B päivittää resurssia

Tämän seurauksena päivitys A katoaa. Viimeinen operaatio patch voittaa, laskuria kasvatetaan yhdellä kahden sijasta, ja "päivitetty" -merkinnän arvo päättyy "B":iin eikä sisällä "A". Verrataan yllä olevaa siihen, mitä tapahtuu, kun päivitykset tehdään lähestymistapaa käyttämällä replace:

  • A ja B saavat resurssin nykyisen tilan API:lta
  • Jokainen päivittää spesifikaation paikallisesti lisäämällä laskuria yhdellä ja lisäämällä "A" tai "B" vastaavasti "päivitetty" -merkintään.
  • Ja se päivittää resurssin hieman nopeammin
  • B yrittää päivittää resurssia, mutta API hylkää päivityksen, koska resurssin versio on määrittelyssä replace ei vastaa resurssin nykyistä versiota Kubernetesissa, koska resurssin versiota on lisätty A:n korvaamistoiminnolla.

Yllä olevassa tapauksessa B:n on haettava resurssi uudelleen, tehtävä muutokset uuteen tilaan ja yritettävä uudelleen replace. Tämä aiheuttaa sen, että laskuria kasvatetaan kahdella ja "päivitetty" -merkinnän lopussa on "AB".

Yllä oleva esimerkki tarkoittaa, että suoritettaessa replace Koko resurssi korvataan kokonaan. Käytetty erittely replace, ei saa olla osittainen tai osissa kuten kohdassa apply, mutta täydellinen, mukaan lukien lisäys resourceVersion määrityksen metatietoihin. Jos et ole ottanut käyttöön resourceVersion tai antamasi versio ei ole ajan tasalla, korvaava versio hylätään. Joten paras tapa käyttää on replace – lue resurssi, päivitä se ja vaihda se välittömästi. Käyttämällä kubectl, se voi näyttää tältä:

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

On syytä huomata, että seuraavat kaksi komentoa, jotka suoritetaan peräkkäin, suoritetaan onnistuneesti, koska deployment.yaml ei sisällä omaisuutta .metadata.resourceVersion

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

Tämä näyttäisi olevan ristiriidassa edellä sanotun kanssa, ts. "lisäämällä resourceVersion määrityksen metatietoihin." Onko väärin sanoa niin? Ei, se ei ole, koska jos kubectl huomaa, että et määrittänyt resourceVersion, se lukee sen resurssista ja lisää sen määrittämääsi spesifikaatioon ja suorittaa sen vasta sitten replace. Koska tämä on mahdollisesti vaarallista, jos luotat atomisuuteen, taika toimii täysin sivussa kubectl, sinun ei pitäisi luottaa siihen, kun käytät asiakaskirjastoja, jotka toimivat API:n kanssa. Tässä tapauksessa sinun on luettava nykyinen resurssimääritys, päivitettävä se ja suoritettava sitten PUT pyyntö.

Et voi tehdä korjausta – me teemme vaihdon

Joskus sinun on tehtävä joitain muutoksia, joita API ei voi käsitellä. Näissä tapauksissa voit pakottaa resurssin korvaamisen poistamalla ja luomalla sen uudelleen. Tämä tehdään käyttämällä kubectl replace --force. Komennon suorittaminen poistaa resurssit välittömästi ja luo ne sitten uudelleen toimitetusta määrityksestä. API:ssa ei ole "pakota korvaamista" -käsittelijää, ja jotta voit tehdä sen API:n kautta, sinun on suoritettava kaksi toimintoa. Ensin sinun on poistettava resurssi asettamalla se gracePeriodSeconds nollaan (0) ja propagationPolicy "Tausta" -kohdassa ja luo sitten tämä resurssi uudelleen halutuilla määrityksillä.

Varoitus: Tämä lähestymistapa on mahdollisesti vaarallinen ja voi johtaa määrittelemättömään tilaan.

Hae palvelimen puolella

Kuten edellä mainittiin, Kubernetes-kehittäjät työskentelevät logiikan toteuttamiseksi apply ja kubectl Kubernetes API:ssa. Logiikka apply saatavilla Kubernetes 1.18:ssa kautta kubectl apply --server-side tai API:n kautta menetelmää käyttäen PATCH с content-type application/apply-patch+YAML.

Huomautus: JSON on myös kelvollinen YAML, joten voit lähettää määrityksen JSON-muodossa, vaikka content-type tahto application/apply-patch+yaml.

Sen logiikan lisäksi kubectl tulee kaikkien saataville API:n kautta, apply palvelinpuolella pitää kirjaa siitä, kuka on vastuussa määrittelyn kentistä, mikä mahdollistaa turvallisen usean pääsyn sen konfliktittomaan muokkaamiseen. Toisin sanoen, jos apply palvelinpuolella yleistyy, eri asiakkaille ilmestyy universaali suojattu resurssienhallintarajapinta, esimerkiksi kubectl, Pulumi tai Terraform, GitOps, sekä itse kirjoitetut skriptit asiakaskirjastojen avulla.

Tulokset

Toivottavasti tästä lyhyestä yleiskatsauksesta eri tavoista päivittää resursseja klustereissa oli sinulle apua. On hyvä tietää, että kyse ei ole vain soveltamisesta tai korvaamisesta, vaan resurssin päivittäminen on mahdollista käyttää, muokata, korjata tai korvata. Loppujen lopuksi jokaisella lähestymistavalla on periaatteessa oma sovellusalue. Atomimuutoksille korvaaminen on parempi vaihtoehto; muuten sinun tulee käyttää strateginen yhdistämiskorjaustiedostoa soveltamalla. Ainakin odotan sinun ymmärtävän, että et voi luottaa Googleen tai StackOerflow'an, kun haet "kubernetes soveltaa vs korvaa". Ainakin kunnes tämä artikkeli korvaa nykyisen vastauksen.

Kubernetes Apply, Replace ja Patch -asetusten oikea vertailu

Lähde: will.com

Lisää kommentti