Kubernetes havas plurajn eblojn por ĝisdatigi rimedojn: apliki, redakti, fliki kaj anstataŭigi. Estas konfuzo pri tio, kion ĉiu faras kaj kiam uzi ilin. Ni eltrovu ĝin.
se kubectl patch
, kiu ne inkluzivas komparon apply
и patch
. Ĉi tiu artikolo rigardos la malsamajn eblojn, same kiel la ĝustan uzon de ĉiu.
Dum la vivociklo de Kubernetes-rimedo (servo, deplojo, eniro, ktp.), foje vi devas ŝanĝi, aldoni aŭ forigi iujn ecojn de ĉi tiu rimedo. Ekzemple, aldonu noton, pliigu aŭ malpliigu la nombron da kopioj.
Kubernetes CLI
Se vi jam laboras kun Kubernetes-grupoj per la CLI, vi jam konas apply
и edit
. Teamo apply
legas la rimedan specifon de la dosiero kaj faras "upsert" al la Kubernetes-areto, t.e. kreas la rimedon se ĝi ne ekzistas kaj ĝisdatigas ĝin se ĝi ekzistas. Teamo edit
legas rimedon per la API, tiam skribas la rimedan specifon al loka dosiero, kiu tiam estas malfermita en tekstredaktilo. Post kiam vi redaktas kaj konservas la dosieron, kubectl
sendos la ŝanĝojn faritajn reen per la API, kiu zorge aplikos ĉi tiujn ŝanĝojn al la rimedo.
Ne ĉiuj konas la ordonojn patch
и replace
. Teamo patch
permesas vin ŝanĝi parton de rimeda specifo, provizante nur la ŝanĝitan parton sur la komandlinio. Teamo replace
funkcias same kiel edit
, sed ĉio devas esti farita permane: vi devas elŝuti la nunan version de la rimeda specifo, ekzemple, uzante kubectl get -o yaml
, redaktu ĝin, poste uzu replace
ĝisdatigi rimedon laŭ ŝanĝita specifo. Teamo replace
ne funkcios se iuj ŝanĝoj okazis inter legado kaj anstataŭigo de la rimedo.
Kubernetes API
Vi verŝajne konas la metodojn CoreV1().Pods().Update()
, replaceNamespacedService
aŭ patch_namespaced_deployment
, se vi laboras kun aretoj per PUT
и PATCH
... En kio update
и replace
uzi PUT
kaj patch
, kiom ajn bagatela ĝi estu, uzas PATCH
.
Indas rimarki tion kubectl
ankaŭ funkcias kun aretoj per API. Alivorte, kubectl
estas envolvaĵo supre de la klienta biblioteko por la lingvo Go, kiu plejparte disponigas la kapablon provizi subkomandojn en pli kompakta kaj legebla formo aldone al la normaj API-kapabloj. Ekzemple, kiel vi eble jam rimarkis, la metodo apply
ne estis menciita supre en la antaŭa paragrafo. Nuntempe (majo 2020, ĉ. tradukisto) ĉiu logiko kubectl apply
, t.e. krei neekzistantajn rimedojn kaj ĝisdatigi ekzistantajn, funkcias tute ĉe la koda flanko kubectl
. Oni klopodas apply
al la API-flanko, sed ĝi ankoraŭ estas en beta. Mi skribos pli detale sube.
Flikaĵo defaŭlte
Plej bone uzata patch
, se vi volas ĝisdatigi la rimedon. Jen kiel ambaŭ klientbibliotekoj funkcias supre de la Kubernetes API kaj kubectl
(ne surprize, ĉar ĝi estas envolvaĵo por la klienta biblioteko, ĉ. tradukisto).
Laboru strategie
Ĉiuj teamoj kubectl
apply
, edit
и patch
uzu la metodon PATCH
en HTTP-petoj ĝisdatigi ekzistantan rimedon. Se vi pli detale pliprofundigas la efektivigon de komandoj, tiam ĉiuj uzas la aliron patch
povas uzi aliajn alirojn (pli pri tio ĉi malsupre). La strategia-kunfanda flikaliro provas "ĝustigi ĝin" kunfandante la provizitan specifon kun la ekzistanta specifo. Pli specife, ĝi provas kombini kaj objektojn kaj tabelojn, kio signifas, ke la ŝanĝoj tendencas esti aldonaj. Ekzemple, ruli la komandon patch
kun nova mediovariablo en la podujo-specifo, igas tiun mediovariablon esti aldonita al la ekzistantaj mediovariabloj prefere ol anstataŭi ilin. Por forigi ĉi tiun aliron, vi devas devigi la parametran valoron nul en la provizita specifo. Kiu el la teamoj kubectl
Ĉu estas plej bone uzi por ĝisdatigo?
Se vi kreas kaj administras viajn rimedojn uzante kubectl apply
, dum ĝisdatigo estas pli bone ĉiam uzi kubectl apply
al kubectl
povis administri agordon kaj ĝuste spuri petitajn ŝanĝojn de aplikaĵo al aplikaĵo. Avantaĝo ĉiam uzu apply
estas ke ĝi konservas trakon de antaŭe aplikata specifo, permesante al ĝi scii kiam specifecoj kaj tabelelementoj estas eksplicite forigitaj. Ĉi tio permesas vin uzi apply
forigi trajtojn kaj tabelelementojn, dum normala strategia kunfandiĝo ne funkcios. Teamoj edit
и patch
ne ĝisdatigu notojn tion kubectl apply
uzas por spuri ĝiajn ŝanĝojn, do ĉiuj ŝanĝoj kiuj estas spuritaj kaj faritaj per la Kubernetes API, sed faritaj per komandoj edit
и patch
, nevidebla al postaj komandoj apply
tio estas apply
ne forigas ilin eĉ se ili ne aperas en la eniga specifo por apply
(La dokumentaro diras tion edit
и patch
fari ĝisdatigojn al la uzataj notoj apply
, sed praktike - ne).
Se vi ne uzas la komandon apply
, povas esti uzata kiel edit
, kaj patch
, elektante la komandon kiu plej konvenas al la farita ŝanĝo. Aldonante kaj ŝanĝante BOM-ecojn, ambaŭ aliroj estas proksimume la samaj. Kiam vi forigas specifajn proprietojn aŭ tabelelementojn edit
kondutas kiel unufoja lanĉo apply
, inkluzive de konservi trakon de kia estis la specifo antaŭ kaj post kiam ĝi estis redaktita, do vi povas eksplicite forigi trajtojn kaj tabelelementojn de rimedo. Vi devas eksplicite agordi la posedaĵvaloron al nulo en la specifo por patch
forigi ĝin el la rimedo. Forigi tabelelementon uzantan strategia-kunfandan flikaĵon estas pli kompleksa ĉar ĝi postulas la uzon de kunfandaj direktivoj. Vidu aliajn ĝisdatigajn alirojn sube por pli realigeblaj alternativoj.
Efektivigi ĝisdatigajn metodojn en la klienta biblioteko, kiuj kondutas simile al la supraj komandoj kubectl
, devus esti agordita en petoj content-type
в application/strategic-merge-patch+json
. Se vi volas forigi trajtojn en specifo, vi devas eksplicite agordi iliajn valorojn al nulo simile. kubectl patch
. Se vi bezonas forigi tabelelementojn, vi devus inkluzivi kunfandi direktivojn en la ĝisdatiga specifo aŭ uzi malsaman aliron al ĝisdatigoj.
Aliaj aliroj al ĝisdatigoj
Kubernetes subtenas du aliajn ĝisdatigajn alirojn: kubectl patch --type=merge
. Kiam vi laboras kun la Kubernetes API, vi devas uzi la petan metodon PATCH
kaj instalado content-type
в application/merge-patch+json
.
La JSON-flaĉa aliro, anstataŭ provizi partan specifon de rimedo, uzas provizi la ŝanĝojn, kiujn vi volas fari al la rimedo kiel tabelo, en kiu ĉiu elemento de la tabelo reprezentas priskribon de la ŝanĝo farita al la rimedo. Ĉi tiu aliro estas pli fleksebla kaj potenca maniero esprimi la ŝanĝojn faritajn, sed koste de listigi la ŝanĝojn faritajn en aparta, ne-Kubernetes-formato, prefere ol sendado de parta rimedspecifo. EN kubectl
vi povas elekti JSON-diakilon uzante kubectl patch --type=json
. Kiam vi uzas la Kubernetes API, ĉi tiu aliro funkcias per la peta metodo PATCH
kaj instalado content-type
в application/json-patch+json
.
Ni bezonas konfidon - uzu anstataŭi
En iuj kazoj, vi devas esti certa, ke neniuj ŝanĝoj estas faritaj al rimedo inter la tempo kiam la rimedo estas legita kaj kiam ĝi estas ĝisdatigita. Alivorte, vi devus certigi, ke ĉiuj ŝanĝoj estos atoma. En ĉi tiu kazo, por ĝisdatigi rimedojn vi devus uzi replace
. Ekzemple, se vi havas ConfigMap kun nombrilo kiu estas ĝisdatigita de pluraj fontoj, vi devus esti certa ke du fontoj ne ĝisdatigas la nombrilon samtempe, kaŭzante la ĝisdatigon esti perdita. Por pruvi, imagu sinsekvon de eventoj uzante la aliron patch
:
- A kaj B ricevas la nunan staton de la rimedo de la API
- Ĉiu loke ĝisdatigas la specifon pliigante la nombrilon je unu kaj ankaŭ aldonante "A" aŭ "B" respektive al la "ĝisdatigita per" noto
- Kaj ĝi ĝisdatigas la rimedon iom pli rapide
- B ĝisdatigas la rimedon
Kiel rezulto, ĝisdatigo A estas perdita. Lasta operacio patch
gajnas, la nombrilo estas pliigita je unu anstataŭe de du, kaj la valoro de la "ĝisdatigita-per" noto finiĝas kun "B" kaj ne enhavas "A". Ni komparu la supre kun kio okazas kiam ĝisdatigoj estas faritaj per la aliro replace
:
- A kaj B ricevas la nunan staton de la rimedo de la API
- Ĉiu loke ĝisdatigas la specifon pliigante la nombrilon je unu kaj ankaŭ aldonante "A" aŭ "B" respektive al la "ĝisdatigita per" noto
- Kaj ĝi ĝisdatigas la rimedon iom pli rapide
- B provas ĝisdatigi la rimedon, sed la ĝisdatigo estas malakceptita de la API ĉar la rimedversio estas en la specifo
replace
ne kongruas kun la nuna versio de la rimedo en Kubernetes ĉar la versio de la rimedo estis pliigita per la anstataŭiga operacio de A.
En la supra kazo, B devos repreni la rimedon, fari ŝanĝojn al la nova stato kaj provi denove replace
. Ĉi tio igos la nombrilon esti pliigita je du kaj la "ĝisdatigita-per" noto inkluzivi "AB" ĉe la fino.
La supra ekzemplo implicas tion dum ekzekuto replace
La tuta rimedo estas tute anstataŭigita. Specifo uzata por replace
, ne devas esti parta, aŭ en partoj kiel en apply
, sed kompleta, inkluzive de la aldono resourceVersion
en la specifmetadatumojn. Se vi ne ebligis resourceVersion
aŭ la versio kiun vi provizas ne estas aktuala, la anstataŭaĵo estos malakceptita. Do la plej bona aliro por uzi estas replace
– legu la rimedon, ĝisdatigu ĝin kaj anstataŭigu ĝin tuj. Uzanta kubectl
, ĝi povus aspekti jene:
$ kubectl get deployment my-deployment -o json
| jq '.spec.template.spec.containers[0].env[1].value = "new value"'
| kubectl replace -f -
Indas noti, ke la sekvaj du komandoj, ekzekutitaj sinsekve, efektiviĝos sukcese, ĉar deployment.yaml
ne enhavas posedaĵon .metadata.resourceVersion
$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml
Ĉi tio ŝajnus kontraŭdiri tion supre dirite, t.e. "aldonante resourceVersion
en la specifmetadatumojn." Ĉu estas malĝuste diri tion? Ne, ĝi ne estas, ĉar se kubectl
rimarkas, ke vi ne specifis resourceVersion
, ĝi legos ĝin el la rimedo kaj aldonos ĝin al la specifo, kiun vi specifis, kaj nur tiam ekzekutos ĝin replace
. Ĉar ĉi tio estas potenciale danĝera se vi fidas je atomeco, la magio funkcias tute flanke kubectl
, vi ne devus fidi je ĝi kiam vi uzas klientajn bibliotekojn, kiuj funkcias kun la API. En ĉi tiu kazo vi devos legi la nunan rimedan specifon, ĝisdatigi ĝin kaj poste ekzekuti PUT
peto.
Vi ne povas fari flikaĵon - ni anstataŭigas
Kelkfoje vi devas fari iujn ŝanĝojn, kiuj ne povas esti pritraktitaj de la API. En ĉi tiuj kazoj, vi povas devigi anstataŭigon de la rimedo forigante kaj rekreante ĝin. Ĉi tio estas farita uzante kubectl replace --force
. Ruli la komandon tuj forigas la rimedojn kaj poste rekreas ilin el la provizita specifo. Ne ekzistas "forta anstataŭigo" pritraktilo en la API, kaj por fari tion per la API, vi devas fari du operaciojn. Unue vi devas forigi la rimedon agordante por ĝi gracePeriodSeconds
al nulo (0) kaj propagationPolicy
en "Fono" kaj poste rekreu ĉi tiun rimedon kun la dezirata specifo.
Averto: Ĉi tiu aliro estas eble danĝera kaj povas konduki al nedifinita stato.
Apliku ĉe la servilo
Kiel menciite supre, Kubernetes-programistoj laboras por efektivigi la logikon apply
el kubectl
en la Kubernetes API. Logikoj apply
havebla en Kubernetes 1.18 tra kubectl apply --server-side
aŭ per la API uzante la metodon PATCH
с content-type
application/apply-patch+YAML
.
Noto: JSON ankaŭ validas YAML, do vi povas sendi la specifon kiel JSON eĉ se
content-type
estosapplication/apply-patch+yaml
.
Krom tiu logiko kubectl
iĝas havebla al ĉiuj per API, apply
sur la servilflanko, konservas trakon de kiu respondecas pri la kampoj en la specifo, tiel permesante sekuran multoblan aliron por ĝia senkonflikta redaktado. Alivorte, se apply
sur la servilo-flanko pli disvastiĝos, universala sekura administradinterfaco de rimedoj aperos por malsamaj klientoj, ekzemple, kubectl, Pulumi aŭ Terraform, GitOps, kaj ankaŭ mem-skribitaj skriptoj uzante klientajn bibliotekojn.
Rezultoj
Mi esperas, ke ĉi tiu mallonga superrigardo de malsamaj manieroj ĝisdatigi rimedojn en aretoj estis helpema al vi. Estas bone scii, ke ĝi ne estas nur apliki kontraŭ anstataŭi; estas eble ĝisdatigi rimedon uzante apliki, redakti, fliki aŭ anstataŭigi. Post ĉio, principe, ĉiu aliro havas sian propran amplekson. Por atomŝanĝoj, anstataŭigo estas preferinda; alie, vi devus uzi strategia-kunfandi flikilon per apliki. Almenaŭ, mi atendas, ke vi komprenos, ke vi ne povas fidi Guglon aŭ StackOerflow serĉante "kubernetes apply vs replace". Almenaŭ ĝis ĉi tiu artikolo anstataŭigos la nunan respondon.
fonto: www.habr.com