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.
Jos 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 PUT
и PATCH
... Jossa update
и replace
käyttää PUT
Ja 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, kubectl
on 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 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 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 apply
Voit 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 apply
Toisin 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 edit
Ja 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 patch
poistaaksesi 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: 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
tahtoapplication/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.
Lähde: will.com