Ulinganisho Sahihi wa Kubernetes Omba, Badilisha na Kiraka

Kubernetes ina chaguo kadhaa za kusasisha rasilimali: tuma, hariri, weka kiraka na ubadilishe. Kuna mkanganyiko juu ya kile kila mmoja hufanya na wakati wa kuzitumia. Hebu tufikirie.

Ulinganisho Sahihi wa Kubernetes Omba, Badilisha na Kiraka

Kama tafuta kwenye Google maneno "kubernetes apply vs replace" iko jibu StackOverflow, ambayo si sahihi. Wakati wa kutafuta "kubernetes apply vs kiraka" kiunga cha kwanza ni hati za kubectl patch, ambayo haijumuishi kulinganisha apply ΠΈ patch. Makala hii itaangalia chaguzi mbalimbali, pamoja na matumizi sahihi ya kila mmoja.

Wakati wa mzunguko wa maisha wa rasilimali ya Kubernetes (huduma, upelekaji, ingress, n.k.), wakati mwingine unahitaji kubadilisha, kuongeza au kuondoa baadhi ya mali ya rasilimali hii. Kwa mfano, ongeza dokezo, ongeza au punguza idadi ya nakala.

Kubernetes CLI

Ikiwa tayari unafanya kazi na makundi ya Kubernetes kupitia CLI, tayari unayafahamu apply ΠΈ edit. Timu apply inasoma uainishaji wa rasilimali kutoka kwa faili na hufanya "upsert" kwa nguzo ya Kubernetes, i.e. huunda rasilimali ikiwa haipo na kuisasisha ikiwa iko. Timu edit husoma rasilimali kupitia API, kisha huandika maelezo ya rasilimali kwa faili ya ndani, ambayo hufunguliwa kwa kihariri cha maandishi. Baada ya kuhariri na kuhifadhi faili, kubectl itatuma mabadiliko yaliyofanywa kupitia API, ambayo itatumia kwa uangalifu mabadiliko haya kwenye rasilimali.

Sio kila mtu anajua amri patch ΠΈ replace. Timu patch hukuruhusu kubadilisha sehemu ya uainishaji wa rasilimali, kutoa tu sehemu iliyobadilishwa kwenye mstari wa amri. Timu replace inafanya kazi sawa na edit, lakini kila kitu kinahitajika kufanywa kwa mikono: unahitaji kupakua toleo la sasa la uainishaji wa rasilimali, kwa mfano, kwa kutumia kubectl get -o yaml, hariri, kisha utumie replace kusasisha rasilimali kulingana na vipimo vilivyobadilishwa. Timu replace haitafanya kazi ikiwa mabadiliko yoyote yametokea kati ya kusoma na kuchukua nafasi ya rasilimali.

Kubernetes API

Labda unajua mbinu CoreV1().Pods().Update(), replaceNamespacedService au patch_namespaced_deployment, ikiwa unafanya kazi na nguzo kupitia maktaba ya mteja ya Kubernetes API kutumia lugha fulani ya programu. Maktaba hushughulikia njia hizi kupitia maombi ya HTTP kwa kutumia mbinu PUT ΠΈ PATCH... Ambayo update ΠΈ replace kutumia PUTNa patch, haijalishi ni ndogo kiasi gani, hutumia PATCH.

Ikumbukwe kwamba kubectl pia inafanya kazi na vikundi kupitia API. Kwa maneno mengine, kubectlni karatasi iliyo juu ya maktaba ya mteja kwa lugha ya Go, ambayo kwa kiasi kikubwa hutoa uwezo wa kutoa amri ndogo katika umbo fumbatio na kusomeka zaidi pamoja na uwezo wa kawaida wa API. Kwa mfano, kama unaweza kuwa tayari niliona, mbinu apply haikutajwa hapo juu katika aya iliyotangulia. Hivi sasa (Mei 2020, takriban. mfasiri) mantiki yote kubectl apply, i.e. kuunda rasilimali ambazo hazipo na kusasisha zilizopo, hufanya kazi kabisa kwa upande wa kanuni kubectl. Juhudi zinafanywa juu ya uhamisho wa mantiki apply kwa upande wa API, lakini bado iko kwenye beta. Nitaandika kwa undani zaidi hapa chini.

Bandika kwa chaguomsingi

Bora kutumika patch, ikiwa unataka kusasisha rasilimali. Hivi ndivyo maktaba zote mbili za mteja zinavyofanya kazi juu ya Kubernetes API na kubectl (haishangazi, kwani ni kanga ya maktaba ya mteja, takriban. mfasiri).

Fanya kazi kimkakati

Timu zote kubectl apply, edit ΠΈ patch tumia mbinu PATCH katika HTTP maombi ya kusasisha rasilimali iliyopo. Ukiingia katika utekelezaji wa amri kwa undani zaidi, basi zote hutumia mbinu kimkakati-unganisha viraka kusasisha rasilimali, ingawa amri patch inaweza kutumia njia zingine (zaidi juu ya hii hapa chini). Mbinu ya kuunganisha kimkakati inajaribu "kuiweka sawa" kwa kuunganisha vipimo vilivyotolewa na vipimo vilivyopo. Hasa zaidi, inajaribu kuchanganya vitu vyote na safu, ambayo inamaanisha kuwa mabadiliko huwa ya kuongeza. Kwa mfano, kuendesha amri patch na utofauti mpya wa mazingira katika vipimo vya kontena la ganda, husababisha utofauti huo wa mazingira kuongezwa kwa anuwai za mazingira zilizopo badala ya kuzibadilisha. Kuondoa kwa kutumia mbinu hii, lazima ulazimishe thamani ya parameta kubatilisha ubainisho uliotolewa. Timu zipi kubectl Je, ni bora kutumia kusasisha?

Ikiwa utaunda na kudhibiti rasilimali zako kwa kutumia kubectl apply, wakati wa kusasisha ni bora kutumia kila wakati kubectl applyKwa kubectl inaweza kudhibiti usanidi na kufuatilia vizuri mabadiliko yaliyoombwa kutoka kwa programu hadi programu. Faida tumia kila wakati apply ni kwamba hufuatilia vipimo vilivyotumika hapo awali, kuiruhusu kujua wakati sifa za kubainisha na vipengele vya safu vimeondolewa waziwazi. Hii inakuwezesha kutumia apply kuondoa mali na vitu vya safu, wakati uunganisho wa kawaida wa kimkakati hautafanya kazi. Timu edit ΠΈ patch usisasishe maelezo hayo kubectl apply hutumia kufuatilia mabadiliko yake, kwa hivyo mabadiliko yoyote ambayo yanafuatiliwa na kufanywa kupitia Kubernetes API, lakini hufanywa kupitia amri. edit ΠΈ patch, isiyoonekana kwa amri zinazofuata applyHiyo ni, apply haiziondoi hata kama hazionekani katika vipimo vya ingizo apply (Nyaraka zinasema hivyo edit ΠΈ patch fanya masasisho kwa madokezo yaliyotumika apply, lakini kwa mazoezi - hapana).

Ikiwa hutumii amri apply, inaweza kutumika kama editNa patch, kuchagua amri inayofaa zaidi mabadiliko yanayofanywa. Wakati wa kuongeza na kubadilisha mali ya BOM, njia zote mbili ni sawa. Wakati wa kufuta sifa za kubainisha au vipengele vya safu edit hufanya kama uzinduzi wa mara moja apply, ikiwa ni pamoja na kufuatilia jinsi vipimo vilivyokuwa kabla na baada ya kuhaririwa, ili uweze kuondoa kwa uwazi sifa na vipengele vya mkusanyiko kutoka kwa rasilimali. Unahitaji kuweka kwa uwazi thamani ya mali ili kubatilisha vipimo vya patchkuiondoa kutoka kwa rasilimali. Kuondoa kipengee cha safu kwa kutumia uwekaji kiambatanisho-kakati ni ngumu zaidi kwa sababu inahitaji matumizi ya maagizo ya kuunganisha. Tazama mbinu zingine za kuboresha hapa chini kwa njia mbadala zinazofaa zaidi.

Ili kutekeleza njia za kusasisha katika maktaba ya mteja ambazo zinafanya kazi sawa na amri zilizo hapo juu kubectl, inapaswa kuwekwa katika maombi content-type Π² application/strategic-merge-patch+json. Ikiwa unataka kuondoa mali katika hali maalum, unahitaji kuweka wazi maadili yao kuwa batili kwa njia sawa. kubectl patch. Ikiwa unahitaji kuondoa vipengee vya mkusanyiko, unapaswa kujumuisha maagizo ya kuunganisha katika vipimo vya sasisho au utumie mbinu tofauti ya masasisho.

Mbinu zingine za sasisho

Kubernetes inasaidia mbinu zingine mbili za sasisho: JSON unganisha kiraka ΠΈ Kiraka cha JSON. Mbinu ya kuunganisha kiraka cha JSON inachukua ubainifu wa Kubernetes kiasi kama ingizo na inasaidia kuunganisha vitu sawa na mbinu ya kuunganisha kimkakati. Tofauti kati ya hizi mbili ni kwamba inasaidia tu uingizwaji wa safu, pamoja na safu ya kontena katika vipimo vya pod. Hii inamaanisha kuwa unapotumia kiraka cha kuunganisha cha JSON, unahitaji kutoa vipimo kamili vya kontena zote endapo mali yoyote ya chombo chochote itabadilika. Kwa hivyo mbinu hii ni muhimu kwa kuondoa vitu kutoka kwa safu kwenye BOM. Kwenye mstari wa amri unaweza kuchagua kiraka cha kuunganisha JSON kwa kutumia kubectl patch --type=merge. Unapofanya kazi na Kubernetes API, unapaswa kutumia njia ya ombi PATCH na ufungaji content-type Π² application/merge-patch+json.

Mbinu ya kiraka ya JSON, badala ya kutoa maelezo kamili ya rasilimali, hutumia kutoa mabadiliko unayotaka kufanya kwenye rasilimali kama safu, ambapo kila kipengele cha mkusanyiko kinawakilisha maelezo ya mabadiliko yanayofanywa kwenye rasilimali. Mbinu hii ni njia rahisi na yenye nguvu zaidi ya kueleza mabadiliko yanayofanywa, lakini kwa gharama ya kuorodhesha mabadiliko yanayofanywa katika umbizo tofauti, lisilo la Kubernetes, badala ya kutuma ubainishaji kiasi wa rasilimali. KATIKA kubectl unaweza kuchagua kiraka cha JSON ukitumia kubectl patch --type=json. Unapotumia Kubernetes API, mbinu hii inafanya kazi kwa kutumia njia ya ombi PATCH na ufungaji content-type Π² application/json-patch+json.

Tunahitaji kujiamini - tumia nafasi

Katika baadhi ya matukio, unahitaji kuwa na uhakika kwamba hakuna mabadiliko yanayofanywa kwa rasilimali kati ya wakati rasilimali inasomwa na inaposasishwa. Kwa maneno mengine, unapaswa kuhakikisha kuwa mabadiliko yote yatakuwa atomiki. Katika kesi hii, ili kusasisha rasilimali unapaswa kutumia replace. Kwa mfano, ikiwa una ConfigMap yenye counter ambayo imesasishwa na vyanzo vingi, unapaswa kuwa na uhakika kwamba vyanzo viwili hazisasishi kaunta kwa wakati mmoja, na kusababisha sasisho kupotea. Ili kuonyesha, fikiria mlolongo wa matukio kwa kutumia mbinu patch:

  • A na B hupata hali ya sasa ya rasilimali kutoka kwa API
  • Kila moja inasasisha vipimo kwa kuongeza kihesabu kwa moja na pia kuongeza "A" au "B" mtawalia kwenye kidokezo cha "kusasishwa na"
  • Na inasasisha rasilimali haraka kidogo
  • B inasasisha rasilimali

Kwa hivyo, sasisho A linapotea. Operesheni ya mwisho patch ikishinda, kaunta inaongezwa na moja badala ya mbili, na thamani ya noti "iliyosasishwa na" inaisha na "B" na haina "A". Wacha tulinganishe yaliyo hapo juu na kile kinachotokea wakati sasisho zinafanywa kwa kutumia mbinu replace:

  • A na B hupata hali ya sasa ya rasilimali kutoka kwa API
  • Kila moja inasasisha vipimo kwa kuongeza kihesabu kwa moja na pia kuongeza "A" au "B" mtawalia kwenye kidokezo cha "kusasishwa na"
  • Na inasasisha rasilimali haraka kidogo
  • B inajaribu kusasisha rasilimali, lakini sasisho limekataliwa na API kwa sababu toleo la rasilimali liko katika vipimo. replace hailingani na toleo la sasa la rasilimali katika Kubernetes kwa sababu toleo la rasilimali liliongezwa kwa utendakazi wa kubadilisha wa A.

Katika hali iliyo hapo juu, B italazimika kuchota tena rasilimali, kufanya mabadiliko kwenye hali mpya na kujaribu tena replace. Hii itasababisha kaunta kuongezwa kwa mbili na noti ya "isasishwa na" kujumuisha "AB" mwishoni.

Mfano hapo juu unamaanisha kuwa wakati wa kutekeleza replace Rasilimali nzima imebadilishwa kabisa. Specification kutumika kwa replace, lazima isiwe sehemu, au sehemu kama ilivyo apply, lakini kamili, ikiwa ni pamoja na kuongeza resourceVersion kwenye metadata ya vipimo. Ikiwa haujawasha resourceVersion au toleo unalotoa si la sasa, uingizwaji utakataliwa. Kwa hivyo njia bora ya kutumia ni replace - soma rasilimali, usasishe na ubadilishe mara moja. Kutumia kubectl, inaweza kuonekana kama hii:

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

Inafaa kumbuka kuwa amri mbili zifuatazo, zinazotekelezwa kwa mpangilio, zitatekelezwa kwa mafanikio, kwani deployment.yaml haina mali .metadata.resourceVersion

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

Hii inaweza kuonekana kupingana na kile kilichosemwa hapo juu, i.e. "kuongeza resourceVersion kwenye metadata maalum." Je, ni makosa kusema hivyo? Hapana, sivyo, kwa sababu kama kubectl arifa ambazo hukubainisha resourceVersion, itaisoma kutoka kwa rasilimali na kuiongeza kwa hali uliyotaja, na kisha tu kutekeleza replace. Kwa sababu hii inaweza kuwa hatari ikiwa unategemea atomiki, uchawi hufanya kazi kwa upande kubectl, haupaswi kutegemea wakati wa kutumia maktaba za mteja zinazofanya kazi na API. Katika kesi hii itabidi usome uainishaji wa sasa wa rasilimali, usasishe na kisha utekeleze PUT ombi.

Huwezi kufanya kiraka - tunafanya nafasi

Wakati mwingine unahitaji kufanya mabadiliko ambayo hayawezi kushughulikiwa na API. Katika matukio haya, unaweza kulazimisha uingizwaji wa rasilimali kwa kufuta na kuunda upya. Hii inafanywa kwa kutumia kubectl replace --force. Kuendesha amri mara moja huondoa rasilimali na kisha kuziunda tena kutoka kwa vipimo vilivyotolewa. Hakuna kidhibiti cha "kubadilisha nguvu" kwenye API, na ili kufanya hivyo kupitia API, unahitaji kufanya shughuli mbili. Kwanza unahitaji kufuta rasilimali kwa kuiweka gracePeriodSeconds hadi sifuri (0) na propagationPolicy katika "Mandharinyuma" na kisha uunde upya nyenzo hii kwa vipimo unavyotaka.

Onyo: Mbinu hii inaweza kuwa hatari na inaweza kusababisha hali isiyobainishwa.

Omba kwa upande wa seva

Kama ilivyoelezwa hapo juu, watengenezaji wa Kubernetes wanafanya kazi katika kutekeleza mantiki apply ya kubectl katika Kubernetes API. Mantiki apply inapatikana katika Kubernetes 1.18 kupitia kubectl apply --server-side au kupitia API kwa kutumia njia PATCH с content-type application/apply-patch+YAML.

Kumbuka: JSON pia ni YAML halali, kwa hivyo unaweza kutuma maelezo kama JSON hata kama content-type mapenzi application/apply-patch+yaml.

Mbali na mantiki hiyo kubectl inapatikana kwa kila mtu kupitia API, apply kwa upande wa seva, hufuatilia ni nani anayehusika na uga katika vipimo, hivyo basi kuruhusu ufikiaji salama wa nyingi kwa uhariri wake usio na migogoro. Kwa maneno mengine, ikiwa apply kwa upande wa seva itaenea zaidi, kiolesura cha usimamizi wa rasilimali salama kwa wote kitaonekana kwa wateja tofauti, kwa mfano, kubectl, Pulumi au Terraform, GitOps, pamoja na hati zinazojiandika kwa kutumia maktaba za mteja.

Matokeo ya

Natumai muhtasari huu mfupi wa njia tofauti za kusasisha rasilimali katika vikundi ulikuwa muhimu kwako. Ni vyema kujua kwamba haitumiki tu dhidi ya kubadilisha; inawezekana kusasisha rasilimali kwa kutumia apply, hariri, kiraka, au badilisha. Baada ya yote, kimsingi, kila mbinu ina eneo lake la maombi. Kwa mabadiliko ya atomiki, kubadilisha kunapendekezwa; vinginevyo, unapaswa kutumia kiraka cha kuunganisha kimkakati kupitia apply. Angalau, ninatarajia uelewe kuwa huwezi kuamini Google au StackOerflow unapotafuta "kubernetes apply vs replace". Angalau hadi nakala hii ichukue nafasi ya jibu la sasa.

Ulinganisho Sahihi wa Kubernetes Omba, Badilisha na Kiraka

Chanzo: mapenzi.com

Kuongeza maoni