Եռակողմ միաձուլում դեպի werf. տեղակայում Kubernetes-ում Helm-ով «ստերոիդների վրա»
Կատարվեց այն, ինչ մենք (և ոչ միայն մենք) երկար էինք սպասում. վերֆ, մեր բաց կոդով օգտակար ծրագիրը՝ հավելվածներ ստեղծելու և դրանք Kubernetes-ին առաքելու համար, այժմ աջակցում է փոփոխություններ կիրառել՝ օգտագործելով եռակողմ միաձուլման patches: Ի հավելումն սրան, հնարավոր է կիրառել առկա K3-ի ռեսուրսները Helm-ի թողարկումներում՝ առանց այդ ռեսուրսները վերակառուցելու:
Եթե դա շատ կարճ է, ապա մենք դնում ենք WERF_THREE_WAY_MERGE=enabled — մենք տեղակայում ենք «ինչպես kubectl apply«, համատեղելի է գործող Helm 2 կայանքների հետ և նույնիսկ մի փոքր ավելին:
Բայց եկեք սկսենք տեսությունից. իրականում որո՞նք են 3-ուղի միաձուլման patches, ինչպես են մարդիկ եկել դրանց ստեղծման մոտեցմանը, և ինչու են դրանք կարևոր CI/CD գործընթացներում Kubernetes-ի վրա հիմնված ենթակառուցվածքով: Եվ դրանից հետո տեսնենք, թե ինչ է 3-way-merge-ը werf-ում, ինչ ռեժիմներ են օգտագործվում լռելյայն և ինչպես կառավարել այն:
Ի՞նչ է եռակողմ միաձուլման կարկատելը:
Այսպիսով, եկեք սկսենք YAML-ի մանիֆեստներում նկարագրված ռեսուրսները Kubernetes-ում տարածելու առաջադրանքից:
Ռեսուրսների հետ աշխատելու համար Kubernetes API-ն առաջարկում է հետևյալ հիմնական գործողությունները՝ ստեղծել, կարկատել, փոխարինել և ջնջել: Ենթադրվում է, որ նրանց օգնությամբ անհրաժեշտ է կառուցել ռեսուրսների հարմար շարունակական տեղաբաշխում դեպի կլաստեր: Ինչպե՞ս:
kubectl հրամայական հրամաններ
Kubernetes-ում օբյեկտների կառավարման առաջին մոտեցումն է օգտագործել kubectl հրամայական հրամանները՝ ստեղծելու, փոփոխելու և ջնջելու այդ օբյեկտները: Պարզապես դիր:
թիմը kubectl run Դուք կարող եք գործարկել Deployment կամ Job:
kubectl run --generator=deployment/apps.v1 DEPLOYMENT_NAME --image=IMAGE
թիմը kubectl scale - փոխել կրկնօրինակների քանակը.
kubectl scale --replicas=3 deployment/mysql
եւ այլն:
Այս մոտեցումը կարող է առաջին հայացքից հարմար թվալ։ Այնուամենայնիվ, կան խնդիրներ.
Դա դժվար է ավտոմատացնել.
Ինչպես արտացոլում է կոնֆիգուրացիան Git-ում? Ինչպե՞ս վերանայել կլաստերի հետ տեղի ունեցող փոփոխությունները:
Ինչպես ապահովել վերարտադրելիություն կոնֆիգուրացիաներ վերագործարկման ժամանակ:
...
Հասկանալի է, որ այս մոտեցումը լավ չի համապատասխանում հավելվածների և ենթակառուցվածքների պահպանմանը որպես կոդ (IaC; կամ նույնիսկ GitOps որպես ավելի ժամանակակից տարբերակ՝ ձեռք բերելով ժողովրդականություն Kubernetes էկոհամակարգում): Հետևաբար, այս հրամանները հետագա զարգացում չեն ստացել kubectl-ում:
Ստեղծեք, ստացեք, փոխարինեք և ջնջեք գործողություններ
Առաջնային հետ ստեղծագործությունը դա պարզ է՝ ուղարկեք մանիֆեստը գործողությանը create kube api-ն և ռեսուրսը ստեղծվել է: Մանիֆեստի YAML ներկայացումը կարող է պահվել Git-ում և ստեղծվել հրամանի միջոցով kubectl create -f manifest.yaml.
С հեռացում նաև պարզ. փոխարինել նույնը manifest.yaml Git-ից թիմ kubectl delete -f manifest.yaml.
Գործողություն replace թույլ է տալիս ամբողջությամբ փոխարինել ռեսուրսի կոնֆիգուրացիան նորով, առանց ռեսուրսի վերստեղծման: Սա նշանակում է, որ ռեսուրսի մեջ փոփոխություն կատարելուց առաջ տրամաբանական է հարցնել գործող տարբերակը get, փոխեք այն և թարմացրեք այն գործողության հետ replace. ներկառուցված է kube apiserver լավատեսական փակում և եթե վիրահատությունից հետո get փոխվել է օբյեկտը, հետո՝ գործողությունը replace դա չի աշխատի:
Կազմաձևը Git-ում պահելու և այն փոխարինելու միջոցով թարմացնելու համար պետք է կատարեք գործողությունը get, միաձուլեք Git-ի կազմաձևը մեր ստացածի հետ և գործարկեք replace. Լռելյայնորեն, kubectl-ը թույլ է տալիս օգտագործել միայն հրամանը kubectl replace -f manifest.yamlՈրտեղ manifest.yaml — արդեն լիովին պատրաստված (մեր դեպքում՝ միաձուլված) մանիֆեստ, որը պետք է տեղադրվի։ Պարզվում է, որ օգտատերը պետք է իրականացնի միաձուլման մանիֆեստներ, և դա մանրուք չէ...
Հարկ է նաև նշել, որ թեև manifest.yaml և պահվում է Git-ում, մենք չենք կարող նախապես իմանալ՝ անհրաժեշտ է ստեղծել օբյեկտ, թե թարմացնել այն, դա պետք է արվի օգտվողի ծրագրաշարի միջոցով։
Ընդամենը: կարո՞ղ ենք շարունակական ներդրում կառուցել միայն ստեղծել, փոխարինել և ջնջել օգտագործելով՝ ապահովելով, որ ենթակառուցվածքի կազմաձևը պահվում է Git-ում կոդի և հարմար CI/CD-ի հետ միասին:
Սկզբունքորեն մենք կարող ենք... Սրա համար դուք պետք է իրականացնեք միաձուլման գործողությունը մանիֆեստներ և մի տեսակ պարտադիր, որը.
ստուգում է օբյեկտի առկայությունը կլաստերում,
իրականացնում է սկզբնական ռեսուրսների ստեղծում,
թարմացնում կամ ջնջում է այն:
Թարմացնելիս խնդրում ենք նկատի ունենալ, որ ռեսուրսը կարող է փոխվել անցյալից get և ինքնաբերաբար կարգավորել լավատեսական կողպման դեպքը. կատարել թարմացման կրկնակի փորձեր:
Այնուամենայնիվ, ինչու՞ նորից հորինել անիվը, երբ kube-apiserver-ն առաջարկում է ռեսուրսները թարմացնելու ևս մեկ միջոց՝ գործողությունը patch, որն օգտագործողին ազատում է նկարագրված որոշ խնդիրներից:
կարկատել
Այժմ մենք հասնում ենք կարկատաններին:
Patch-ները Kubernetes-ում գոյություն ունեցող օբյեկտներում փոփոխություններ կիրառելու հիմնական միջոցն են: Գործողություն patch այն աշխատում է այսպես.
kube-apiserver օգտատերը պետք է ուղարկի patch JSON ձևով և նշի օբյեկտը,
իսկ apiserver-ը ինքը կզբաղվի օբյեկտի ներկա վիճակով և կբերի այն պահանջվող ձևին:
Այս դեպքում լավատեսական կողպում չի պահանջվում: Այս գործողությունն ավելի շատ դեկլարատիվ է, քան փոխարինելը, չնայած սկզբում այն կարող է հակառակը թվալ:
Այս կերպ.
օգտագործելով վիրահատություն create մենք ստեղծում ենք օբյեկտ Git-ից մանիֆեստի համաձայն,
միջոցով delete — ջնջել, եթե օբյեկտն այլևս անհրաժեշտ չէ,
միջոցով patch — մենք փոխում ենք օբյեկտը՝ այն բերելով Git-ում նկարագրված ձևի։
Այնուամենայնիվ, դա անելու համար անհրաժեշտ է ստեղծել ճիշտ կարկատել!
Ինչպես են կարկատաններն աշխատում Helm 2-ում. երկկողմանի միաձուլում
Երբ դուք առաջին անգամ տեղադրում եք թողարկում, Helm-ը կատարում է գործողությունը create գծապատկերների ռեսուրսների համար:
Յուրաքանչյուր ռեսուրսի համար Helm թողարկումը թարմացնելիս.
հաշվի է առնում նախորդ գծապատկերի ռեսուրսի տարբերակի և ընթացիկ աղյուսակի տարբերակի միջև եղած հատվածը,
կիրառում է այս կարկատելը:
Մենք կկոչենք այս կարկատելը Երկկողմանի միաձուլման կարկատել, քանի որ դրա ստեղծման մեջ ներգրավված են 2 մանիֆեստներ.
ռեսուրսի մանիֆեստ նախորդ թողարկումից,
ռեսուրսի մանիֆեստը ընթացիկ ռեսուրսից:
Գործողությունը հեռացնելիս delete kube-ում apiserver-ը կանչվում է ռեսուրսների համար, որոնք հայտարարված էին նախորդ թողարկումում, բայց չհայտարարված ընթացիկ տարբերակում:
Երկկողմանի միաձուլման կարկատելու մոտեցումը խնդիր ունի. այն հանգեցնում է կլաստերի ռեսուրսի և Git-ի մանիֆեստի իրական վիճակի հետ համաժամանակցված չէ.
Խնդրի նկարազարդումը օրինակով
Git-ում գծապատկերը պահում է մանիֆեստը, որտեղ դաշտը image Տեղակայման հարցերը ubuntu:18.04.
Օգտագործողի միջոցով kubectl edit փոխել է այս դաշտի արժեքը ubuntu:19.04.
Helm աղյուսակը կրկին տեղակայելիս չի առաջացնում կարկատել, քանի որ դաշտը image թողարկման նախորդ տարբերակում և ընթացիկ աղյուսակում նույնն են:
Կրկին տեղակայումից հետո image մնացորդները ubuntu:19.04, չնայած աղյուսակում ասվում է ubuntu:18.04.
Մենք ստացանք ապասինխրոնացում և կորցրեցինք դեկլարատիվությունը:
Ի՞նչ է համաժամեցված ռեսուրսը:
Ընդհանուր առմամբ ամբողջական Անհնար է համապատասխանություն ստանալ վազող կլաստերի ռեսուրսի մանիֆեստի և Git-ի մանիֆեստի միջև: Քանի որ իրական մանիֆեստում կարող են լինել ծառայության անոտացիաներ/պիտակներ, լրացուցիչ բեռնարկղեր և այլ տվյալներ, որոնք որոշ կարգավորիչների կողմից դինամիկ կերպով ավելացվում և հեռացվում են ռեսուրսից: Մենք չենք կարող և չենք ցանկանում այս տվյալները պահել Git-ում: Այնուամենայնիվ, մենք ցանկանում ենք, որ դաշտերը, որոնք մենք բացահայտորեն նշել ենք Git-ում, ստանան համապատասխան արժեքներ՝ տեղադրման ժամանակ:
Այնքան ընդհանուր է ստացվում սինխրոն ռեսուրսների կանոն: ռեսուրսը տարածելիս կարող եք փոխել կամ ջնջել միայն այն դաշտերը, որոնք բացահայտորեն նշված են Git-ի մանիֆեստում (կամ նշվել են նախորդ տարբերակում և այժմ ջնջված են):
Երկկողմանի միաձուլման կարկատել
Գլխավոր միտք Երկկողմանի միաձուլման կարկատելՄենք ստեղծում ենք մի կարկատել Git-ից մանիֆեստի վերջին կիրառված տարբերակի և Git-ի մանիֆեստի թիրախային տարբերակի միջև՝ հաշվի առնելով գործող կլաստերի մանիֆեստի ընթացիկ տարբերակը: Ստացված կարկատելը պետք է համապատասխանի համաժամացված ռեսուրսի կանոնին.
նպատակային տարբերակին ավելացված նոր դաշտերը ավելացվում են կարկատի միջոցով.
Վերջին կիրառական տարբերակում նախկինում գոյություն ունեցող և թիրախային տարբերակում գոյություն չունեցող դաշտերը վերակայվում են՝ օգտագործելով կարկատելը.
Օբյեկտի ընթացիկ տարբերակի դաշտերը, որոնք տարբերվում են մանիֆեստի թիրախային տարբերակից, թարմացվում են՝ օգտագործելով կարկատելը:
Հենց այս սկզբունքով է այն ստեղծում patches kubectl apply:
մանիֆեստի վերջին կիրառված տարբերակը պահվում է հենց օբյեկտի ծանոթագրության մեջ,
թիրախ - վերցված է նշված YAML ֆայլից,
ընթացիկը վազող կլաստերից է:
Այժմ, երբ մենք դասավորեցինք տեսությունը, ժամանակն է պատմելու ձեզ, թե ինչ արեցինք werf-ում:
Փոփոխությունների կիրառում werf-ում
Նախկինում werf-ը, ինչպես Helm 2-ը, օգտագործում էր երկկողմանի միաձուլման բծեր:
Վերանորոգման կարկատել
Նոր տեսակի patches-ի անցնելու համար՝ 3-way-merge, առաջին քայլը մենք ներկայացրեցինք այսպես կոչված. վերանորոգման կարկատներ.
Տեղակայման ժամանակ օգտագործվում է ստանդարտ երկկողմանի միաձուլման կարկատել, սակայն werf-ը լրացուցիչ ստեղծում է մի կարկատել, որը կհամաժամանակացնի ռեսուրսի իրական վիճակը Git-ում գրվածի հետ (այդպիսի կարկատակը ստեղծվում է վերը նկարագրված նույն համաժամացված ռեսուրսի կանոնի միջոցով): .
Եթե տեղի է ունենում ապասինխրոնիզացիա, տեղակայման վերջում օգտատերը ստանում է ԶԳՈՒՇԱՑՈՒՄ համապատասխան հաղորդագրությամբ և կարկատում, որը պետք է կիրառվի ռեսուրսը համաժամեցված ձևի բերելու համար: Այս կարկատելը նույնպես գրանցված է հատուկ անոտացիայով werf.io/repair-patch. Ենթադրվում է, որ օգտագործողի ձեռքերը сам կկիրառի այս կարկատելը. werf-ն այն ընդհանրապես չի կիրառի:
Վերանորոգման պատչերի ստեղծումը ժամանակավոր միջոց է, որը թույլ է տալիս իրականում փորձարկել կարկատանների ստեղծումը՝ հիմնված 3-ուղի միաձուլման սկզբունքի վրա, բայց ինքնաբերաբար չկիրառել այդ կարկատանները: Այս պահին գործառնական այս ռեժիմը լռելյայն միացված է:
Եռակողմ միաձուլման կարկատել միայն նոր թողարկումների համար
1 թվականի դեկտեմբերի 2019-ից սկսվում են werf-ի բետա և ալֆա տարբերակները լռելյայն օգտագործեք ամբողջական 3-ուղիով միաձուլման patches՝ փոփոխությունները կիրառելու միայն werf-ի միջոցով թողարկված Helm-ի նոր թողարկումներում: Առկա թողարկումները կշարունակեն օգտագործել երկկողմանի միաձուլման + վերանորոգման կարկատների մոտեցումը:
Գործառնական այս ռեժիմը կարող է հստակորեն միացվել՝ կարգավորելով WERF_THREE_WAY_MERGE_MODE=onlyNewReleases հիմա.
Նշումֆունկցիան հայտնվել է werf-ում մի քանի թողարկումներում. ալֆա ալիքում այն պատրաստ է եղել տարբերակով v1.0.5-ալֆա.19, իսկ բետա ալիքում՝ հետ v1.0.4-բետա.20.
Եռակողմ միաձուլման կարկատել բոլոր թողարկումների համար
Սկսած 15 թվականի դեկտեմբերի 2019-ից, werf-ի բետա և ալֆա տարբերակները լռելյայնորեն սկսում են օգտագործել ամբողջական եռակողմ միաձուլման patches՝ բոլոր թողարկումներում փոփոխություններ կիրառելու համար:
Գործառնական այս ռեժիմը կարող է հստակորեն միացվել՝ կարգավորելով WERF_THREE_WAY_MERGE_MODE=enabled հիմա.
Ի՞նչ անել ռեսուրսների ավտոմատ մասշտաբի հետ:
Kubernetes-ում կա ավտոմասկալավորման 2 տեսակ՝ HPA (հորիզոնական) և VPA (ուղղահայաց):
Հորիզոնականը ավտոմատ կերպով ընտրում է կրկնօրինակների քանակը, ուղղահայացը՝ ռեսուրսների քանակը: Ինչպես կրկնօրինակների քանակը, այնպես էլ ռեսուրսների պահանջները նշված են ռեսուրսի մանիֆեստում (տես Ռեսուրսների մանիֆեստ): spec.replicas կամ spec.containers[].resources.limits.cpu, spec.containers[].resources.limits.memory и մյուսները).
Խնդիր. եթե օգտատերը կարգավորում է ռեսուրսը գծապատկերում այնպես, որ այն սահմանում է որոշակի արժեքներ ռեսուրսների կամ կրկնօրինակների համար, և ավտոմատ սանդղակները միացված են այս ռեսուրսի համար, ապա յուրաքանչյուր տեղակայման դեպքում werf-ը կվերակայի այդ արժեքները գծապատկերում գրվածին: .
Խնդրի երկու լուծում կա. Սկզբից ավելի լավ է խուսափել գծապատկերի մանիֆեստում ավտոմատացված արժեքների բացահայտ նշելուց: Եթե այս տարբերակը հարմար չէ ինչ-ինչ պատճառներով (օրինակ, քանի որ հարմար է սկզբնական ռեսուրսների սահմանաչափերը և կրկնօրինակների քանակը սահմանել գծապատկերում), ապա werf-ն առաջարկում է հետևյալ ծանոթագրությունները.
werf.io/set-replicas-only-on-creation=true
werf.io/set-resources-only-on-creation=true
Եթե առկա է նման ծանոթագրություն, werf-ը չի վերակայի համապատասխան արժեքները յուրաքանչյուր տեղակայման վրա, այլ կսահմանի դրանք միայն այն ժամանակ, երբ սկզբնապես ստեղծվի ռեսուրսը:
Լրացուցիչ մանրամասների համար տե՛ս ծրագրի փաստաթղթերը HPA и VPA.
Արգելեք եռակողմ միաձուլման կարկատակի օգտագործումը
Օգտագործողը ներկայումս կարող է արգելել նոր patches-ի օգտագործումը werf-ում՝ օգտագործելով շրջակա միջավայրի փոփոխական WERF_THREE_WAY_MERGE_MODE=disabled. Այնուամենայնիվ, սկսելով 1 թվականի մարտի 2020-ից այս արգելքն այլևս չի գործելու։ և հնարավոր կլինի օգտագործել միայն 3-way-merge-patches:
Վերֆում ռեսուրսների ընդունում
Եռակողմ միաձուլման patches-ներով փոփոխությունների կիրառման մեթոդի յուրացումը թույլ տվեց մեզ անմիջապես կիրառել այնպիսի առանձնահատկություն, ինչպիսին է կլաստերում առկա ռեսուրսների ընդունումը Helm-ի թողարկման մեջ:
Helm 2-ը խնդիր ունի. դուք չեք կարող ռեսուրս ավելացնել գծապատկերների մանիֆեստներին, որն արդեն գոյություն ունի կլաստերում՝ առանց այս ռեսուրսը զրոյից վերստեղծելու (տես. #6031, #3275) Մենք Werf-ին սովորեցրինք ընդունել առկա ռեսուրսները ազատման համար: Դա անելու համար անհրաժեշտ է անոտացիա տեղադրել ռեսուրսի ընթացիկ տարբերակի վրա գործող կլաստերից (օրինակ՝ օգտագործելով kubectl edit):
"werf.io/allow-adoption-by-release": RELEASE_NAME
Այժմ ռեսուրսը պետք է նկարագրվի գծապատկերում, և հաջորդ անգամ, երբ werf-ը տեղակայի համապատասխան անվանումով թողարկում, գոյություն ունեցող ռեսուրսը կընդունվի այս թողարկումում և կմնա նրա վերահսկողության տակ: Ավելին, թողարկման համար ռեսուրս ընդունելու գործընթացում werf-ը կբերի ռեսուրսի ներկայիս վիճակը գործող կլաստերից դեպի գծապատկերում նկարագրված վիճակի, օգտագործելով նույն 3-way-merge patches-ը և համաժամացված ռեսուրսի կանոնը:
Նշում: կարգավորում WERF_THREE_WAY_MERGE_MODE չի ազդում ռեսուրսների ընդունման վրա. ընդունման դեպքում միշտ օգտագործվում է 3-ուղի միաձուլման կարկատել:
Հուսով եմ, որ այս հոդվածից հետո ավելի պարզ դարձավ, թե ինչ են 3-way-merge patches-ը և ինչու են դրանք հայտնվել: Werf նախագծի մշակման գործնական տեսանկյունից դրանց իրականացումը ևս մեկ քայլ էր Helm-ի նման տեղակայման բարելավման ուղղությամբ: Այժմ դուք կարող եք մոռանալ կոնֆիգուրացիայի համաժամացման հետ կապված խնդիրների մասին, որոնք հաճախ առաջանում էին Helm 2-ն օգտագործելիս: Միևնույն ժամանակ, Helm-ի թողարկումին ավելացվեց արդեն ներբեռնված Kubernetes ռեսուրսների ընդունման նոր օգտակար գործառույթ:
Դեռևս կան որոշ խնդիրներ և մարտահրավերներ Helm-ի նման տեղակայումների հետ կապված, ինչպիսիք են Go-ի ձևանմուշների օգտագործումը, որոնց մենք կշարունակենք անդրադառնալ:
Ռեսուրսների թարմացման մեթոդների և ընդունման մասին տեղեկատվություն կարող եք գտնել նաև այստեղ այս փաստաթղթերի էջը.
Ղեկը 3
Առանձնահատուկ ուշադրության է արժանի ազատ է արձակվել հենց օրերս Helm-ի նոր հիմնական տարբերակը՝ v3, որն օգտագործում է նաև 3-way-merge-patches և ազատվում է Tiller-ից: Helm-ի նոր տարբերակը պահանջում է միգրացիան առկա տեղադրումները՝ դրանք նոր թողարկման պահեստավորման ձևաչափի փոխարկելու համար:
Werf-ը, իր հերթին, ներկայումս ազատվել է Tiller-ի օգտագործումից, անցել է 3-way-merge-միաձուլման և ավելացրել է. շատ ավելի, միևնույն ժամանակ համատեղելի է Helm 2-ի առկա տեղադրումների հետ (միգրացիոն սկրիպտներ չպետք է կատարվեն): Հետևաբար, մինչև werf-ը չանցնի Helm 3-ին, werf օգտվողները չեն կորցնում Helm 3-ի հիմնական առավելությունները Helm 2-ի նկատմամբ (werf-ն ունի նաև դրանք):
Այնուամենայնիվ, werf-ի անցումը Helm 3 կոդերի բազային անխուսափելի է և տեղի կունենա մոտ ապագայում: Ենթադրաբար սա կլինի werf 1.1 կամ werf 1.2 (այս պահին werf-ի հիմնական տարբերակը 1.0-ն է, werf տարբերակող սարքի մասին լրացուցիչ տեղեկությունների համար տե՛ս. այստեղ) Այս ընթացքում Helm 3-ը ժամանակ կունենա կայունանալու համար:
PS
Կարդացեք նաև մեր բլոգում.
Werf-ում նորարարությունների մասին մի շարք նշումներ.