Kubernetes-ն ունի ռեսուրսների թարմացման մի քանի տարբերակ՝ կիրառել, խմբագրել, կարկատել և փոխարինել: Շփոթություն կա, թե ինչ է անում յուրաքանչյուրը և երբ օգտագործել դրանք: Եկեք պարզենք այն:
Եթե kubectl patch
, որը չի ներառում համեմատություն apply
и patch
. Այս հոդվածում կքննարկվեն տարբեր տարբերակները, ինչպես նաև յուրաքանչյուրի ճիշտ օգտագործումը:
Kubernetes ռեսուրսի կյանքի ցիկլի ընթացքում (ծառայություն, տեղակայում, մուտք և այլն), երբեմն անհրաժեշտ է փոխել, ավելացնել կամ հեռացնել այս ռեսուրսի որոշ հատկություններ: Օրինակ, ավելացրեք նշում, ավելացրեք կամ նվազեցրեք կրկնօրինակների քանակը:
Kubernetes CLI
Եթե դուք արդեն աշխատում եք Kubernetes կլաստերների հետ CLI-ի միջոցով, դուք արդեն ծանոթ եք apply
и edit
. Թիմ apply
կարդում է ռեսուրսի ճշգրտումը ֆայլից և «վերադարձ» է անում Kubernetes կլաստերին, այսինքն. ստեղծում է ռեսուրսը, եթե այն գոյություն չունի, և թարմացնում է այն, եթե այն գոյություն ունի: Թիմ edit
կարդում է ռեսուրսը API-ի միջոցով, այնուհետև գրում է ռեսուրսի ճշգրտումը տեղական ֆայլում, որն այնուհետև բացվում է տեքստային խմբագրիչում: Ֆայլը խմբագրելուց և պահպանելուց հետո, kubectl
Կատարված փոփոխությունները հետ կուղարկի API-ի միջոցով, որը ուշադիր կկիրառի այդ փոփոխությունները ռեսուրսի վրա:
Ոչ բոլորը գիտեն հրամանները patch
и replace
. Թիմ patch
թույլ է տալիս փոխել ռեսուրսի մասնագրերի մի մասը՝ հրամանի տողում տրամադրելով միայն փոփոխված մասը: Թիմ replace
աշխատում է նույնը, ինչ edit
, բայց ամեն ինչ պետք է արվի ձեռքով. անհրաժեշտ է ներբեռնել ռեսուրսի բնութագրերի ընթացիկ տարբերակը, օրինակ՝ օգտագործելով kubectl get -o yaml
, խմբագրեք այն, ապա օգտագործեք replace
թարմացնել ռեսուրսը ըստ փոփոխված բնութագրի: Թիմ replace
չի աշխատի, եթե որևէ փոփոխություն տեղի ունենա ռեսուրսի ընթերցման և փոխարինման միջև:
Kubernetes API
Դուք հավանաբար ծանոթ եք մեթոդներին CoreV1().Pods().Update()
, replaceNamespacedService
կամ patch_namespaced_deployment
, եթե աշխատում եք կլաստերների հետ միջոցով PUT
и PATCH
. Այսպես update
и replace
օգտագործումը PUT
Իսկ patch
, որքան էլ դա չնչին լինի, օգտագործում է PATCH
.
Պետք է նշել, որ kubectl
աշխատում է նաև կլաստերների հետ API-ի միջոցով: Այլ կերպ ասած, kubectl
Հաճախորդի գրադարանի վերևում գտնվող Go լեզվի փաթաթան է, որը հիմնականում ապահովում է ենթահրամաններ ավելի կոմպակտ և ընթեռնելի ձևով տրամադրելու հնարավորություն՝ ի լրումն ստանդարտ API-ի հնարավորությունների: Օրինակ, ինչպես արդեն նկատել եք, մեթոդը apply
վերը նշված չէր նախորդ պարբերությունում: Ներկայումս (մայիս 2020 թ., մոտ. թարգմանիչ) ամբողջ տրամաբանությունը kubectl apply
, այսինքն. ստեղծելով գոյություն չունեցող ռեսուրսներ և թարմացնելով առկա ռեսուրսները, աշխատում է ամբողջությամբ կոդի վրա kubectl
. Ջանքեր են արվում apply
դեպի API-ի կողմը, բայց այն դեռ բետա փուլում է: Ստորև ավելի մանրամասն կգրեմ.
Կարկատել լռելյայն
Լավագույն օգտագործված patch
, եթե ցանկանում եք թարմացնել ռեսուրսը: Այսպես են աշխատում երկու հաճախորդների գրադարանները Kubernetes API-ի վերևում և kubectl
(Զարմանալի չէ, քանի որ դա փաթեթավորում է հաճախորդի գրադարանի համար, մոտ. թարգմանիչ).
Աշխատեք ռազմավարական
Բոլոր թիմերը kubectl
apply
, edit
и patch
օգտագործել մեթոդը PATCH
HTTP-ում առկա ռեսուրսը թարմացնելու հարցում է պահանջում: Եթե դուք ավելի մանրամասն եք խորանում հրամանների իրականացման մեջ, ապա բոլորն էլ օգտագործում են մոտեցումը patch
կարող է օգտագործել այլ մոտեցումներ (այս մասին ավելին ստորև): Ռազմավարական միաձուլման կարկատման մոտեցումը փորձում է «հասցնել այն ճիշտ»՝ միաձուլելով տրամադրված ճշգրտումը գոյություն ունեցող ճշգրտման հետ: Ավելի կոնկրետ, այն փորձում է համատեղել և՛ առարկաները, և՛ զանգվածները, ինչը նշանակում է, որ փոփոխությունները հակված են հավելյալ լինելուն: Օրինակ՝ գործարկել հրամանը patch
պատի կոնտեյների ճշգրտման մեջ նոր միջավայրի փոփոխականի առկայության դեպքում այդ միջավայրի փոփոխականն ավելացվում է գոյություն ունեցող միջավայրի փոփոխականներին, քան դրանք վերագրանցելու: Այս մոտեցմամբ հեռացնելու համար դուք պետք է ստիպեք պարամետրի արժեքը չեղյալ համարել տրված ճշգրտման մեջ: Թիմերից որն է kubectl
Արդյո՞ք լավագույնն է օգտագործել թարմացման համար:
Եթե դուք ստեղծում և կառավարում եք ձեր ռեսուրսները՝ օգտագործելով kubectl apply
, թարմացնելիս ավելի լավ է միշտ օգտագործել kubectl apply
այնպես որ kubectl
կարող է կառավարել կոնֆիգուրացիան և ճիշտ հետևել պահանջվող փոփոխություններին հավելվածից հավելված: Առավելությունները միշտ օգտագործեք apply
այն է, որ այն հետևում է նախկինում կիրառված ճշգրտմանը, ինչը թույլ է տալիս իմանալ, երբ հստակեցման հատկությունները և զանգվածի տարրերը բացահայտորեն հեռացվում են: Սա թույլ է տալիս օգտագործել apply
հեռացնել հատկությունները և զանգվածի տարրերը, մինչդեռ սովորական ռազմավարական միաձուլումը չի աշխատի: Թիմեր edit
и patch
մի թարմացրեք նշումները, որ kubectl apply
օգտագործում է իր փոփոխությունները հետևելու համար, ուստի ցանկացած փոփոխություն, որը հետևվում և կատարվում է Kubernetes API-ի միջոցով, բայց կատարվում է հրամանների միջոցով: edit
и patch
, անտեսանելի է հետագա հրամանների համար apply
Այսինքն, apply
չի հեռացնում դրանք, նույնիսկ եթե դրանք չեն երևում մուտքագրման բնութագրերում apply
(Փաստաթղթում ասվում է edit
и patch
կատարել թարմացումներ օգտագործված նշումներում apply
, բայց գործնականում ոչ):
Եթե դուք չեք օգտագործում հրամանը apply
, կարող է օգտագործվել որպես edit
Իսկ patch
, ընտրելով կատարվող փոփոխությանը լավագույնս համապատասխանող հրամանը: BOM հատկությունները ավելացնելիս և փոխելիս երկու մոտեցումներն էլ մոտավորապես նույնն են: Տեխնիկական հատկությունները կամ զանգվածի տարրերը ջնջելիս edit
իրեն պահում է որպես մեկանգամյա մեկնարկ apply
, ներառյալ հետևելը, թե ինչպիսին է եղել ճշգրտումը մինչև դրա խմբագրումը և դրանից հետո, որպեսզի կարողանաք հստակորեն հեռացնել հատկությունները և զանգվածի տարրերը ռեսուրսից: Դուք պետք է հստակորեն սահմանեք գույքի արժեքը որպես null-ի ճշգրտման համար patch
այն ռեսուրսից հեռացնելու համար: Զանգվածի տարրը հեռացնելը, օգտագործելով ռազմավարական միաձուլման կարկատումը, ավելի բարդ է, քանի որ այն պահանջում է միաձուլման հրահանգների օգտագործում: Ավելի կենսունակ այլընտրանքների համար տե՛ս ստորև արդիականացման այլ մոտեցումներ:
Հաճախորդի գրադարանում թարմացման մեթոդներ կիրառելու համար, որոնք վարվում են վերը նշված հրամանների նման kubectl
, պետք է սահմանվի հարցումներում content-type
в application/strategic-merge-patch+json
. Եթե ցանկանում եք հեռացնել հատկությունները բնութագրում, դուք պետք է բացահայտորեն սահմանեք դրանց արժեքները որպես զրոյական նույն ձևով: kubectl patch
. Եթե Ձեզ անհրաժեշտ է հեռացնել զանգվածի տարրերը, դուք պետք է ներառեք միաձուլման հրահանգները թարմացման ճշգրտման մեջ կամ օգտագործեք թարմացումների այլ մոտեցում:
Թարմացումների այլ մոտեցումներ
Kubernetes-ն աջակցում է թարմացման երկու այլ մոտեցում. kubectl patch --type=merge
. Kubernetes API-ի հետ աշխատելիս դուք պետք է օգտագործեք հարցումների մեթոդը PATCH
և տեղադրում content-type
в application/merge-patch+json
.
JSON կարկատանի մոտեցումը, ռեսուրսի մասնակի ճշգրտում տրամադրելու փոխարեն, օգտագործում է ռեսուրսի մեջ այն փոփոխությունները, որոնք ցանկանում եք կատարել որպես զանգված, որտեղ զանգվածի յուրաքանչյուր տարր ներկայացնում է ռեսուրսի մեջ կատարվող փոփոխության նկարագրությունը: Այս մոտեցումը կատարվող փոփոխություններն արտահայտելու ավելի ճկուն և հզոր միջոց է, բայց արված փոփոխությունները առանձին, ոչ Kubernetes ձևաչափով ցուցակագրելու գնով, այլ ոչ թե ռեսուրսի մասնակի ճշգրտում ուղարկելու համար: IN kubectl
կարող եք ընտրել JSON կարկատել՝ օգտագործելով kubectl patch --type=json
. Kubernetes API-ն օգտագործելիս այս մոտեցումն աշխատում է հարցումների մեթոդով PATCH
և տեղադրում content-type
в application/json-patch+json
.
Մեզ վստահություն է պետք. օգտագործիր փոխարինիր
Որոշ դեպքերում դուք պետք է վստահ լինեք, որ ռեսուրսի մեջ որևէ փոփոխություն չի կատարվում ռեսուրսի ընթերցման և թարմացման միջև ընկած ժամանակահատվածում: Այլ կերպ ասած, դուք պետք է համոզվեք, որ բոլոր փոփոխությունները կլինեն ատոմային. Այս դեպքում ռեսուրսները թարմացնելու համար դուք պետք է օգտագործեք replace
. Օրինակ, եթե դուք ունեք ConfigMap հաշվիչով, որը թարմացվում է բազմաթիվ աղբյուրների կողմից, դուք պետք է վստահ լինեք, որ երկու աղբյուրներ միաժամանակ չեն թարմացնում հաշվիչը, ինչի հետևանքով թարմացումը կորչում է: Ցույց տալու համար պատկերացրեք իրադարձությունների հաջորդականությունը՝ օգտագործելով մոտեցումը patch
:
- A-ն և B-ն ստանում են ռեսուրսի ներկայիս վիճակը API-ից
- Յուրաքանչյուրը տեղական մակարդակում թարմացնում է սպեցիֆիկացիաները՝ մեծացնելով հաշվիչը մեկով և նաև ավելացնելով «A» կամ «B» «թարմացված» նշումին համապատասխանաբար:
- Եվ այն թարմացնում է ռեսուրսը մի փոքր ավելի արագ
- B-ն թարմացնում է ռեսուրսը
Արդյունքում, A թարմացումը կորչում է: Վերջին վիրահատությունը patch
հաղթում է, հաշվիչը երկուսի փոխարեն ավելանում է մեկով, իսկ «updated-by» նշումի արժեքը ավարտվում է «B»-ով և չի պարունակում «A»: Եկեք համեմատենք վերը նշվածը այն բանի հետ, թե ինչ է տեղի ունենում, երբ թարմացումները կատարվում են՝ օգտագործելով մոտեցումը replace
:
- A-ն և B-ն ստանում են ռեսուրսի ներկայիս վիճակը API-ից
- Յուրաքանչյուրը տեղական մակարդակում թարմացնում է սպեցիֆիկացիաները՝ մեծացնելով հաշվիչը մեկով և նաև ավելացնելով «A» կամ «B» «թարմացված» նշումին համապատասխանաբար:
- Եվ այն թարմացնում է ռեսուրսը մի փոքր ավելի արագ
- B-ն փորձում է թարմացնել ռեսուրսը, սակայն թարմացումը մերժվում է API-ի կողմից, քանի որ ռեսուրսի տարբերակը նշված է ճշգրտման մեջ
replace
չի համապատասխանում Kubernetes-ի ռեսուրսի ընթացիկ տարբերակին, քանի որ ռեսուրսի տարբերակը մեծացել է A-ի փոխարինման գործողությամբ:
Վերոնշյալ դեպքում B-ն պետք է նորից վերցնի ռեսուրսը, փոփոխություններ կատարի նոր վիճակի մեջ և նորից փորձի replace
. Դա կհանգեցնի նրան, որ հաշվիչը կավելանա երկուով, իսկ «updated-by» նշումը վերջում կներառի «AB»:
Վերոնշյալ օրինակը ենթադրում է, որ կատարելիս replace
Ամբողջ ռեսուրսը ամբողջությամբ փոխարինված է: համար օգտագործվող ճշգրտում replace
, չպետք է լինի մասնակի կամ մասամբ, ինչպես օրինակում apply
, բայց ամբողջական՝ ներառյալ հավելումը resourceVersion
ճշգրտման մետատվյալների մեջ: Եթե դուք չեք միացրել resourceVersion
կամ ձեր տրամադրած տարբերակը ընթացիկ չէ, փոխարինումը կմերժվի: Այսպիսով, օգտագործման լավագույն մոտեցումն է replace
– կարդացեք ռեսուրսը, թարմացրեք այն և անմիջապես փոխարինեք: Օգտագործելով kubectl
, այն կարող է այսպիսի տեսք ունենալ.
$ kubectl get deployment my-deployment -o json
| jq '.spec.template.spec.containers[0].env[1].value = "new value"'
| kubectl replace -f -
Հարկ է նշել, որ հաջորդաբար կատարվող հետևյալ երկու հրամանները հաջողությամբ կկատարվեն, քանի որ. deployment.yaml
գույք չի պարունակում .metadata.resourceVersion
$ kubectl create -f deployment.yaml
$ kubectl replace -f deployment.yaml
Սա կարծես թե հակասում է վերևում ասվածին, այսինքն. «ավելացնելով resourceVersion
ճշգրտման մետատվյալների մեջ»: Սխա՞լ է դա ասել: Ոչ, այդպես չէ, քանի որ եթե kubectl
ծանուցումներ, որոնք դուք չեք նշել resourceVersion
, այն կկարդա այն ռեսուրսից և կավելացնի ձեր նշած սպեցիֆիկացիայի մեջ և միայն այնուհետև կկատարի այն replace
. Քանի որ սա պոտենցիալ վտանգավոր է, եթե դուք ապավինեք ատոմականությանը, կախարդանքն ամբողջությամբ աշխատում է կողքի վրա kubectl
, դուք չպետք է ապավինեք դրա վրա API-ի հետ աշխատող հաճախորդների գրադարաններ օգտագործելիս: Այս դեպքում դուք ստիպված կլինեք կարդալ ընթացիկ ռեսուրսի ճշգրտումը, թարմացնել այն և այնուհետև կատարել PUT
խնդրանք.
Դուք չեք կարող կարկատել, մենք փոխարինում ենք
Երբեմն դուք պետք է որոշ փոփոխություններ կատարեք, որոնք հնարավոր չէ կարգավորել API-ի կողմից: Այս դեպքերում դուք կարող եք ստիպել փոխարինել ռեսուրսը` ջնջելով և նորից ստեղծելով այն: Սա արվում է օգտագործելով kubectl replace --force
. Հրամանի գործարկումն անմիջապես հեռացնում է ռեսուրսները, այնուհետև դրանք վերստեղծում է մատակարարված ճշգրտումից: API-ում «ուժի փոխարինում» մշակող չկա, և API-ի միջոցով դա անելու համար անհրաժեշտ է կատարել երկու գործողություն: Նախ անհրաժեշտ է ջնջել ռեսուրսը` սահմանելով դրա համար gracePeriodSeconds
մինչև զրո (0) և propagationPolicy
«Հետին պլանում» և այնուհետև նորից ստեղծեք այս ռեսուրսը ցանկալի ճշգրտմամբ:
Զգուշացում. Այս մոտեցումը պոտենցիալ վտանգավոր է և կարող է հանգեցնել անորոշ վիճակի:
Կիրառեք սերվերի կողմից
Ինչպես նշվեց վերևում, Kubernetes-ի մշակողները աշխատում են տրամաբանության իրականացման վրա apply
- ից kubectl
Kubernetes API-ում: Տրամաբանություններ apply
հասանելի է Kubernetes 1.18-ում միջոցով kubectl apply --server-side
կամ API-ի միջոցով՝ օգտագործելով մեթոդը PATCH
с content-type
application/apply-patch+YAML
.
Նշում. JSON-ը նաև վավեր է YAML-ի համար, այնպես որ դուք կարող եք ուղարկել ճշգրտումը որպես JSON, նույնիսկ եթե
content-type
կամքapplication/apply-patch+yaml
.
Բացի այդ տրամաբանությունից kubectl
հասանելի է դառնում բոլորի համար API-ի միջոցով, apply
սերվերի կողմից, հետևում է, թե ով է պատասխանատու ճշգրտման դաշտերի համար՝ այդպիսով թույլ տալով անվտանգ բազմակի մուտք՝ դրա առանց կոնֆլիկտների խմբագրման համար: Այլ կերպ ասած, եթե apply
սերվերի կողմից ավելի լայն տարածում կստանա, տարբեր հաճախորդների համար կհայտնվի ունիվերսալ անվտանգ ռեսուրսների կառավարման ինտերֆեյս, օրինակ՝ kubectl, Pulumi կամ Terraform, GitOps, ինչպես նաև հաճախորդի գրադարանների օգտագործմամբ ինքնուրույն գրված սցենարներ:
Արդյունքները
Հուսով եմ, որ կլաստերներում ռեսուրսները թարմացնելու տարբեր եղանակների այս կարճ ակնարկը օգտակար էր ձեզ համար: Լավ է իմանալ, որ դա ոչ միայն կիրառելն է ընդդեմ փոխարինման, այլ հնարավոր է թարմացնել ռեսուրսը կիրառելով, խմբագրելով, կարկատել կամ փոխարինել: Ի վերջո, սկզբունքորեն, յուրաքանչյուր մոտեցում ունի իր կիրառման ոլորտը: Ատոմային փոփոխությունների դեպքում փոխարինումը նախընտրելի է, հակառակ դեպքում՝ դուք պետք է օգտագործեք ռազմավարական միաձուլման կարկատել հավելվածի միջոցով: Առնվազն, ես ակնկալում եմ, որ դուք կհասկանաք, որ չեք կարող վստահել Google-ին կամ StackOerflow-ին «kubernetes դիմել ընդդեմ փոխարինել» բառը որոնելիս: Առնվազն այնքան ժամանակ, քանի դեռ այս հոդվածը չի փոխարինի ներկայիս պատասխանին:
Source: www.habr.com