werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Մայիսի 27-ին փառատոնի շրջանակներում անցկացվող DevOpsConf 2019 կոնֆերանսի գլխավոր դահլիճում RIT++ 2019 թ, որպես «Շարունակական առաքում» բաժնի մաս, տրվեց զեկույց «werf - մեր գործիքը CI/CD-ի համար Kubernetes-ում»: Խոսում է դրանց մասին խնդիրներ և մարտահրավերներ, որոնց բախվում են բոլորը Kubernetes-ում տեղակայվելիս, ինչպես նաեւ նրբերանգների մասին, որոնք կարող են անմիջապես չնկատվել։ Վերլուծելով հնարավոր լուծումները՝ մենք ցույց ենք տալիս, թե ինչպես է դա իրականացվում Open Source գործիքում վերֆ.

Շնորհանդեսից ի վեր մեր կոմունալ ծառայությունը (նախկինում հայտնի էր որպես dapp) հասել է պատմական իրադարձության. 1000 աստղ GitHub-ում — մենք հուսով ենք, որ օգտատերերի աճող համայնքը կհեշտացնի DevOps-ի շատ ինժեներների կյանքը:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Այսպիսով, եկեք ներկայացնենք զեկույցի տեսանյութը (~47 րոպե, շատ ավելի տեղեկատվական, քան հոդվածը) և դրա հիմնական քաղվածքը տեքստային տեսքով: Գնա՛

Կոդերի առաքում Kubernetes-ին

Խոսակցությունն այլևս կլինի ոչ թե werf-ի, այլ CI/CD-ի մասին Kubernetes-ում, ինչը ենթադրում է, որ մեր ծրագրաշարը փաթեթավորված է Docker կոնտեյներներում: (Ես խոսեցի այս մասին 2016 թվականի հաշվետվություն), իսկ K8-ները կօգտագործվեն արտադրության մեջ այն գործարկելու համար (այս մասին ավելին 2017 տարի).

Ինչպիսի՞ն է առաքումը Kubernetes-ում:

  • Գոյություն ունի Git շտեմարան՝ կոդով և այն կառուցելու հրահանգներով: Հավելվածը ներկառուցված է Docker պատկերի մեջ և հրապարակվում է Docker Registry-ում:
  • Նույն պահոցը պարունակում է նաև հավելվածը տեղակայելու և գործարկելու հրահանգներ: Տեղակայման փուլում այս հրահանգներն ուղարկվում են Kubernetes-ին, որը ռեեստրից ստանում է ցանկալի պատկերը և գործարկում:
  • Բացի այդ, սովորաբար կան թեստեր: Դրանցից մի քանիսը կարելի է անել պատկեր հրապարակելիս: Կարող եք նաև (հետևելով նույն հրահանգներին) հավելվածի պատճենը տեղակայել (առանձին K8s անվանատարածքում կամ առանձին կլաստերում) և այնտեղ թեստեր անցկացնել:
  • Ի վերջո, ձեզ անհրաժեշտ է CI համակարգ, որը իրադարձություններ է ստանում Git-ից (կամ կոճակի սեղմումներով) և կանչում է նշանակված բոլոր փուլերը՝ կառուցում, հրապարակում, տեղակայում, փորձարկում:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Այստեղ կան մի քանի կարևոր նշում.

  1. Որովհետև մենք ունենք անփոփոխ ենթակառուցվածք (անփոփոխ ենթակառուցվածք), հավելվածի պատկերը, որն օգտագործվում է բոլոր փուլերում (բեմադրություն, արտադրություն և այլն), պետք է լինի մեկը. Այս մասին ավելի մանրամասն ու օրինակներով խոսեցի։ այստեղ.
  2. Որովհետև մենք հետևում ենք ենթակառուցվածքին որպես կոդային մոտեցում (IaC), հավելվածի կոդը, դրա հավաքման և գործարկման հրահանգները պետք է լինեն հենց մեկ պահոցում. Այս մասին լրացուցիչ տեղեկությունների համար տե՛ս նույն զեկույցը.
  3. Առաքման շղթա (առաքում) մենք սովորաբար տեսնում ենք այսպես՝ հավելվածը հավաքվել է, փորձարկվել, թողարկվել (թողարկման փուլ) և վերջ - առաքումը տեղի է ունեցել: Բայց իրականում օգտատերը ստանում է այն, ինչ դուք հրապարակել եք, ոչ հետո, երբ դու այն հանձնեցիր արտադրությանը, և երբ նա կարողացավ գնալ այնտեղ, և այս արտադրությունը աշխատեց: Այսպիսով, ես հավատում եմ, որ առաքման շղթան ավարտվում է միայն գործառնական փուլում (վազել), ավելի ճիշտ՝ նույնիսկ այն պահին, երբ կոդը հանվել է արտադրությունից (այն փոխարինելով նորով)։

Եկեք վերադառնանք վերը նշված առաքման սխեմային Kubernetes-ում. այն հորինվել է ոչ միայն մեր կողմից, այլ բառացիորեն բոլոր նրանց կողմից, ովքեր զբաղվել են այս խնդրով: Փաստորեն, այս օրինաչափությունն այժմ կոչվում է GitOps (կարող եք ավելին կարդալ տերմինի և դրա հիմքում ընկած գաղափարների մասին այստեղ). Դիտարկենք սխեմայի փուլերը.

Բեմի կառուցում

Թվում է, որ դուք կարող եք խոսել Docker պատկերներ կառուցելու մասին 2019 թվականին, երբ բոլորը գիտեն, թե ինչպես գրել Dockerfiles և գործարկել docker build?.. Ահա այն նրբությունները, որոնց վրա կցանկանայի ուշադրություն դարձնել.

  1. Պատկերի քաշը կարևոր է, ուստի օգտագործեք բազմափուլայիննկարում թողնել միայն այն հավելվածը, որն իսկապես անհրաժեշտ է վիրահատության համար։
  2. Շերտերի քանակը պետք է նվազագույնի հասցնել՝ միավորելով շղթաները RUN- հրամաններ ըստ նշանակության.
  3. Այնուամենայնիվ, սա ավելացնում է խնդիրներ վրիպազերծում, քանի որ երբ ժողովը խափանում է, դուք պետք է գտնեք ճիշտ հրամանը այն շղթայից, որն առաջացրել է խնդիրը։
  4. Մոնտաժման արագություն կարևոր է, որովհետև մենք ցանկանում ենք արագ շրջանառել փոփոխությունները և տեսնել արդյունքները: Օրինակ, դուք չեք ցանկանում վերակառուցել կախվածությունը լեզուների գրադարաններում ամեն անգամ, երբ ստեղծեք հավելված:
  5. Հաճախ ձեզ անհրաժեշտ է մեկ Git պահոցից շատ պատկերներ, որը կարող է լուծվել Dockerfiles-ի (կամ մեկ ֆայլի մեջ անվանված փուլերի) և Bash սկրիպտի միջոցով՝ իրենց հաջորդական հավաքմամբ։

Սա այսբերգի միայն գագաթն էր, որին բախվում են բոլորը: Բայց կան այլ խնդիրներ, մասնավորապես.

  1. Հաճախ հավաքման փուլում մեզ ինչ-որ բան է պետք լեռը (օրինակ՝ քեշավորեք apt-ի նման հրամանի արդյունքը երրորդ կողմի գրացուցակում):
  2. Ուզում ենք Հղիություն կեղևով գրելու փոխարեն.
  3. Ուզում ենք կառուցել առանց Docker-ի (ինչու՞ մեզ պետք է լրացուցիչ վիրտուալ մեքենա, որտեղ մենք պետք է կարգավորենք ամեն ինչ դրա համար, երբ մենք արդեն ունենք Kubernetes կլաստեր, որտեղ մենք կարող ենք գործարկել կոնտեյներներ):
  4. Զուգահեռ հավաքում, որը կարելի է հասկանալ տարբեր կերպ՝ տարբեր հրամաններ Dockerfile-ից (եթե օգտագործվում է բազմաստիճան), նույն պահեստի մի քանի կոմիտացիաներ, մի քանի Dockerfiles։
  5. Բաշխված ժողովՄենք ցանկանում ենք հավաքել իրեր պատյանների մեջ, որոնք «անցանելի» են, քանի որ նրանց քեշը անհետանում է, ինչը նշանակում է, որ այն պետք է ինչ-որ տեղ առանձին պահվի:
  6. Ի վերջո, ես անվանեցի ցանկությունների գագաթնակետը ավտոմոգականԻդեալական կլիներ գնալ պահեստ, մուտքագրել հրաման և ստանալ պատրաստի պատկեր՝ հավաքված հասկանալով, թե ինչպես և ինչ անել ճիշտ: Սակայն ես անձամբ վստահ չեմ, որ բոլոր նրբությունները կարելի է այսպես կանխատեսել։

Եվ ահա նախագծերը.

  • moby/buildkit — Docker Inc-ի շինարար (արդեն ինտեգրված Docker-ի ընթացիկ տարբերակներում), որը փորձում է լուծել այս բոլոր խնդիրները.
  • կանիկո — Google-ի շինարար, որը թույլ է տալիս կառուցել առանց Docker-ի.
  • Buildpacks.io — CNCF-ի փորձը՝ կատարել ավտոմատ մոգություն և, մասնավորապես, հետաքրքիր լուծում՝ շերտերի վերաբաժանմամբ.
  • և մի շարք այլ կոմունալ ծառայություններ, ինչպիսիք են buildah, իսկական գործիքներ/img...

...և տեսեք, թե քանի աստղ ունեն նրանք GitHub-ում: Այսինքն՝ մի կողմից. docker build կա և կարող է ինչ-որ բան անել, բայց իրականում հարցը ամբողջությամբ լուծված չէ - Դրա ապացույցը այլընտրանքային կոլեկտորների զուգահեռ զարգացումն է, որոնցից յուրաքանչյուրը լուծում է խնդիրների մի մասը։

Համագումար վերֆում

Այսպիսով, մենք հասանք վերֆ (նախկինում հայտնի է ինչպես dapp) — Բաց կոդով օգտակար ծրագիր Flant ընկերության կողմից, որը մենք երկար տարիներ ենք պատրաստում: Ամեն ինչ սկսվեց 5 տարի առաջ Bash սկրիպտներով, որոնք օպտիմիզացրել են Dockerfiles-ի հավաքումը, և վերջին 3 տարիների ընթացքում լիարժեք զարգացում է իրականացվել մեկ նախագծի շրջանակներում՝ սեփական Git պահոցով։ (նախ Ռուբիում, իսկ հետո վերաշարադրված դեպի Go, և միևնույն ժամանակ վերանվանվել է). Հավաքման ի՞նչ հարցեր են լուծվում werf-ում:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Կապույտով ներկված խնդիրներն արդեն իրականացվել են, զուգահեռ կառուցումը կատարվել է նույն հոսթինգում, իսկ դեղինով ընդգծված խնդիրները նախատեսվում է ավարտել մինչև ամառվա վերջ։

Գրանցամատյանում հրապարակման փուլը (հրապարակում)

Մենք հավաքեցինք docker push... - ի՞նչը կարող է դժվար լինել պատկերը գրանցամատյանում վերբեռնելու հարցում: Եվ հետո հարց է առաջանում. «Ի՞նչ պիտակ դնեմ նկարի վրա»: Դա առաջանում է այն պատճառով, որ մենք ունենք Gitflow (կամ այլ Git ռազմավարություն) և Kubernetes-ը, և արդյունաբերությունը փորձում է ապահովել, որ այն, ինչ տեղի է ունենում Kubernetes-ում, հետևում է Git-ում տեղի ունեցողին: Ի վերջո, Git-ը ճշմարտության մեր միակ աղբյուրն է:

Ի՞նչն է այսքան դժվար: Ապահովել վերարտադրելիությունըGit-ում կատարվող կոմիտից, որն իր բնույթով անփոփոխ է (անփոփոխելի), Docker պատկերին, որը պետք է նույնը մնա:

Մեզ համար դա նույնպես կարևոր է որոշել ծագումը, քանի որ մենք ուզում ենք հասկանալ, թե որ commit-ից է կառուցվել Kubernetes-ով աշխատող հավելվածը (այդ դեպքում մենք կարող ենք տարբերություններ և նմանատիպ բաներ անել)։

Նշման ռազմավարություններ

Առաջինը պարզ է git tag. Մենք ունենք ռեեստր, որտեղ պատկերված է որպես 1.0. Kubernetes-ն ունի բեմ և արտադրություն, որտեղ վերբեռնված է այս պատկերը։ Git-ում մենք պարտավորություններ ենք կատարում և ինչ-որ պահի նշում ենք 2.0. Մենք այն հավաքում ենք պահոցից տրված հրահանգների համաձայն և տեղադրում ենք ռեեստրում պիտակով 2.0. Մենք այն դուրս ենք բերում բեմականացման և, եթե ամեն ինչ լավ է, ապա արտադրության համար:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Այս մոտեցման խնդիրն այն է, որ մենք նախ դրեցինք պիտակը, և միայն այնուհետև փորձարկեցինք և գլորեցինք այն: Ինչո՞ւ։ Նախ, դա ուղղակի անտրամաբանական է. մենք թողարկում ենք ծրագրաշարի մի տարբերակ, որը մենք դեռ չենք էլ փորձարկել (այլ կերպ չենք կարող անել, քանի որ ստուգելու համար մենք պետք է պիտակ դնենք): Երկրորդ, այս ճանապարհը համատեղելի չէ Gitflow-ի հետ։

Երկրորդ տարբերակը git commit + պիտակ. Վարպետ մասնաճյուղն ունի պիտակ 1.0; դրա համար գրանցամատյանում` արտադրության մեջ տեղակայված պատկեր: Բացի այդ, Kubernetes կլաստերը ունի նախադիտման և բեմադրության ուրվագծեր: Հաջորդը մենք հետևում ենք Gitflow-ին. զարգացման հիմնական ճյուղում (develop) մենք ստեղծում ենք նոր հնարավորություններ՝ արդյունքում նույնացուցիչի հետ կապված պարտավորություն #c1. Մենք հավաքում ենք այն և հրապարակում այն ​​գրանցամատյանում՝ օգտագործելով այս նույնացուցիչը (#c1) Նույն նույնացուցիչով մենք անցնում ենք նախադիտման: Մենք նույնն ենք անում պարտավորությունների դեպքում #c2 и #c3.

Երբ հասկացանք, որ բավականաչափ հատկանիշներ կան, սկսում ենք ամեն ինչ կայունացնել։ Ստեղծեք մասնաճյուղ Git-ում release_1.1 (հիմքի վրա #c3 - ից develop) Այս թողարկումը հավաքելու կարիք չկա, քանի որ... սա արվել է նախորդ քայլում: Հետևաբար, մենք պարզապես կարող ենք այն բեմադրել: Մենք ուղղում ենք սխալները #c4 և նմանապես գլորում դեպի բեմադրություն: Միևնույն ժամանակ, զարգացումը շարունակվում է develop, որտեղից պարբերաբար վերցվում են փոփոխությունները release_1.1. Ինչ-որ պահի մենք ստանում ենք commit, որը կազմվում և բեռնվում է բեմադրության մեջ, որից մենք գոհ ենք (#c25).

Այնուհետև մենք միաձուլում ենք (արագ առաջ շարժման հետ) թողարկման ճյուղը (release_1.1) վարպետության մեջ։ Մենք նոր տարբերակով պիտակ ենք դնում այս կոմմիթի վրա (1.1) Բայց այս պատկերն արդեն հավաքված է ռեեստրում, այնպես որ, որպեսզի այն նորից չհավաքվի, մենք պարզապես ավելացնում ենք երկրորդ պիտակը գոյություն ունեցող պատկերին (այժմ այն ​​ռեեստրում ունի պիտակներ #c25 и 1.1) Դրանից հետո մենք այն դուրս ենք բերում արտադրության:

Կա մի թերություն, որ միայն մեկ պատկեր է վերբեռնվում բեմադրության մեջ (#c25), իսկ արտադրության մեջ մի տեսակ տարբեր է (1.1), բայց մենք գիտենք, որ «ֆիզիկապես» դրանք նույն պատկերն են ռեեստրից:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Իրական թերությունն այն է, որ միաձուլման պարտավորությունների աջակցություն չկա, դուք պետք է արագ առաջ շարժվեք:

Մենք կարող ենք ավելի հեռուն գնալ և հնարք անել... Եկեք նայենք պարզ Dockerfile-ի օրինակին.

FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb

FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/public

Եկեք դրանից ֆայլ կառուցենք հետևյալ սկզբունքով.

  • SHA256 օգտագործված պատկերների նույնացուցիչներից (ruby:2.3 и nginx:alpine), որոնք իրենց բովանդակության ստուգաչափերն են.
  • բոլոր թիմերը (RUN, CMD և այլն);
  • SHA256 ֆայլերից, որոնք ավելացվել են:

... և վերցրեք ստուգման գումարը (կրկին SHA256) նման ֆայլից: Սա ստորագրությունը այն ամենը, ինչ սահմանում է Docker պատկերի բովանդակությունը:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Վերադառնանք դիագրամին և Պարտավորությունների փոխարեն մենք կօգտագործենք նման ստորագրություններ, այսինքն. պիտակավորել նկարները ստորագրություններով:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Այժմ, երբ անհրաժեշտ է, օրինակ, միաձուլել փոփոխությունները թողարկումից դեպի վարպետ, մենք կարող ենք իրական merge commit կատարել. այն կունենա այլ նույնացուցիչ, բայց նույն ստորագրությունը: Նույն նույնացուցիչով մենք նկարը կներկայացնենք արտադրության համար:

Թերությունն այն է, որ այժմ հնարավոր չի լինի որոշել, թե ինչպիսի պարտավորություն է դրվել արտադրության վրա. չեկային գումարներն աշխատում են միայն մեկ ուղղությամբ։ Այս խնդիրը լուծվում է մետատվյալներով լրացուցիչ շերտով - ավելի ուշ ձեզ կասեմ:

Tagging in werf

Werf-ում մենք ավելի հեռուն գնացինք և պատրաստվում ենք բաշխված կառուցում կատարել քեշով, որը չի պահվում մեկ մեքենայի վրա... Այսպիսով, մենք կառուցում ենք երկու տեսակի Docker պատկերներ, մենք դրանք անվանում ենք: փուլ и պատկեր.

Werf Git պահոցը պահում է շինարարության համար հատուկ հրահանգներ, որոնք նկարագրում են կառուցման տարբեր փուլերը (նախքան տեղադրելը, տեղադրել, նախքան Կարգավորումը, մատչ) Մենք հավաքում ենք առաջին փուլի պատկերը ստորագրությամբ, որը սահմանվում է որպես առաջին քայլերի ստուգման գումար: Հետո ավելացնում ենք սկզբնական կոդը, նոր փուլային պատկերի համար հաշվում ենք դրա ստուգման գումարը... Այս գործողությունները կրկնվում են բոլոր փուլերի համար, ինչի արդյունքում ստանում ենք փուլային պատկերների հավաքածու։ Այնուհետև մենք կազմում ենք վերջնական պատկերը, որը պարունակում է նաև մետատվյալներ իր ծագման մասին։ Եվ մենք այս պատկերը նշում ենք տարբեր ձևերով (մանրամասները՝ ավելի ուշ)։

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Ենթադրենք, դրանից հետո հայտնվում է նոր commit, որտեղ փոխվել է միայն հավելվածի կոդը։ Ի՞նչ է լինելու։ Կոդի փոփոխության համար կստեղծվի patch և կպատրաստվի նոր փուլային պատկեր։ Դրա ստորագրությունը կորոշվի որպես հին փուլի պատկերի և նոր կարկատակի ստուգման գումար: Այս պատկերից կձևավորվի նոր վերջնական պատկեր։ Նմանատիպ վարքագիծը տեղի կունենա այլ փուլերում փոփոխությունների դեպքում:

Այսպիսով, փուլային պատկերները քեշ են, որը կարելի է բաշխված պահել, և դրանից արդեն ստեղծված պատկերները վերբեռնվում են Docker Registry-ում։

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Ռեեստրի մաքրում

Մենք չենք խոսում ջնջված պիտակներից հետո կախված շերտերը ջնջելու մասին. սա ինքնին Docker Registry-ի ստանդարտ հատկանիշն է: Մենք խոսում ենք մի իրավիճակի մասին, երբ շատ Docker պիտակներ են կուտակվում, և մենք հասկանում ենք, որ դրանցից մի քանիսը մեզ այլևս պետք չեն, բայց դրանք տարածք են զբաղեցնում (և/կամ մենք վճարում ենք դրա համար)։

Որո՞նք են մաքրման ռազմավարությունները:

  1. Դուք պարզապես ոչինչ չեք կարող անել մի մաքրիր. Երբեմն իսկապես ավելի հեշտ է մի քիչ վճարել լրացուցիչ տարածքի համար, քան թեգերի հսկայական խճճվածքը քանդելը: Բայց սա աշխատում է միայն մինչև որոշակի կետ:
  2. Ամբողջական վերականգնում. Եթե ​​ջնջեք բոլոր պատկերները և վերակառուցեք միայն ընթացիկ պատկերները CI համակարգում, կարող է խնդիր առաջանալ: Եթե ​​բեռնարկղը վերագործարկվի արտադրության մեջ, դրա համար կբեռնվի նոր պատկեր, որը դեռևս չի փորձարկվել որևէ մեկի կողմից: Սա սպանում է անփոփոխ ենթակառուցվածքի գաղափարը:
  3. Կապույտ կանաչ. Մեկ ռեգիստրը սկսեց լցվել. մենք պատկերներ ենք վերբեռնում մյուսում: Նույն խնդիրը, ինչ նախորդ մեթոդով. ո՞ր պահին կարող եք մաքրել ռեեստրը, որը սկսել է լցվել:
  4. Byամանակով. Ջնջե՞լ 1 ամսից հին բոլոր պատկերները: Բայց հաստատ կլինի ծառայություն, որը մեկ ամիս չի թարմացվել...
  5. Ձեռքով որոշել, թե ինչն արդեն կարող է ջնջվել:

Գոյություն ունեն երկու իսկապես կենսունակ տարբերակ՝ չմաքրել կամ ձեռքով կապույտ-կանաչի համադրություն: Վերջին դեպքում խոսքը հետևյալի մասին է՝ երբ հասկանում ես, որ ժամանակն է մաքրել ռեեստրը, ստեղծում ես նորը և դրա վրա ավելացնում բոլոր նոր պատկերները, օրինակ, մեկ ամսվա ընթացքում։ Եվ մեկ ամիս անց, տեսեք, թե Kubernetes-ի որ պատնեշներն են դեռ օգտագործում հին ռեգիստրը, և դրանք նույնպես տեղափոխեք նոր ռեգիստր:

Ինչի ենք հասել վերֆ? Մենք հավաքում ենք.

  1. Git գլուխ. բոլոր պիտակները, բոլոր ճյուղերը - ենթադրելով, որ մեզ անհրաժեշտ է այն ամենը, ինչ պիտակված է Git-ում նկարներում (և եթե ոչ, ապա մենք պետք է ջնջենք այն հենց Git-ում);
  2. բոլոր պատիճները, որոնք ներկայումս մղվում են Kubernetes;
  3. հին ReplicaSets-ը (այն ինչ վերջերս է թողարկվել), և մենք նաև նախատեսում ենք սկանավորել Helm-ի թողարկումները և այնտեղ ընտրել վերջին պատկերները:

... և այս հավաքածուից կազմեք սպիտակ ցուցակ՝ պատկերների ցանկ, որոնք մենք չենք ջնջի: Մենք մաքրում ենք մնացած ամեն ինչ, որից հետո գտնում ենք որբ բեմական պատկերներ և դրանք նույնպես ջնջում։

Տեղակայման փուլ

Հուսալի դեկլարատիվություն

Առաջին կետը, որի վրա ես կցանկանայի ուշադրություն հրավիրել տեղակայման ժամանակ, ռեսուրսների թարմացված կազմաձևման տարածումն է, որը հայտարարված է հռչակագրով: YAML-ի բնօրինակ փաստաթուղթը, որը նկարագրում է Kubernetes-ի ռեսուրսները, միշտ շատ տարբեր է կլաստերում իրականում գործող արդյունքից: Քանի որ Kubernetes-ը ավելացնում է կազմաձևին.

  1. նույնացուցիչներ;
  2. ծառայության տեղեկատվություն;
  3. շատ լռելյայն արժեքներ;
  4. բաժին ընթացիկ կարգավիճակով;
  5. փոփոխություններ, որոնք կատարվել են որպես ընդունելության վեբ-կապիկի մի մաս.
  6. տարբեր կարգավորիչների (և ժամանակացույցի) աշխատանքի արդյունքը:

Հետևաբար, երբ հայտնվում է նոր ռեսուրսի կոնֆիգուրացիա (նոր), մենք չենք կարող պարզապես վերցնել և վերագրանցել ընթացիկ, «կենդանի» կոնֆիգուրացիան դրա հետ (ապրել) Դա անելու համար մենք ստիպված կլինենք համեմատել նոր վերջին կիրառված կոնֆիգուրացիայով (վերջին անգամ կիրառվել է) և գլորել վրա ապրել ստացել է կարկատել։

Այս մոտեցումը կոչվում է Երկկողմանի միաձուլում. Այն օգտագործվում է, օրինակ, Հելմում:

Կա նաեւ Երկկողմանի միաձուլում, որը տարբերվում է նրանով.

  • համեմատելով վերջին անգամ կիրառվել է и նոր, մենք նայում ենք, թե ինչ է ջնջվել;
  • համեմատելով նոր и ապրել, մենք նայում ենք, թե ինչ է ավելացվել կամ փոխվել;
  • ամփոփված կարկատելը կիրառվում է ապրել.

Մենք տեղակայում ենք 1000+ հավելվածներ Helm-ի հետ, ուստի իրականում ապրում ենք երկկողմանի միաձուլմամբ: Այնուամենայնիվ, այն ունի մի շարք խնդիրներ, որոնք մենք լուծել ենք մեր կարկատանների միջոցով, որոնք օգնում են Հելմին նորմալ աշխատել։

Իրական թողարկման կարգավիճակ

Այն բանից հետո, երբ մեր CI համակարգը կստեղծի նոր կոնֆիգուրացիա Kubernetes-ի համար՝ հիմնված հաջորդ իրադարձության վրա, այն փոխանցում է օգտագործման համար: (դիմել) դեպի կլաստեր - օգտագործելով Helm կամ kubectl apply. Այնուհետև տեղի է ունենում արդեն նկարագրված N-way միաձուլումը, որին Kubernetes API-ն հավանություն է տալիս CI համակարգին, և դա իր օգտագործողին:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Այնուամենայնիվ, կա մի հսկայական խնդիր. ի վերջո հաջող կիրառումը չի նշանակում հաջող թողարկում. Եթե ​​Kubernetes-ը հասկանա, թե ինչ փոփոխություններ է պետք կիրառել և կիրառի այն, մենք դեռ չգիտենք, թե ինչ արդյունք կունենա: Օրինակ՝ ֆրոնդային հատվածում պատիճների թարմացումն ու վերագործարկումը կարող է հաջող լինել, բայց ոչ հետին մասում, և մենք կստանանք գործող հավելվածի պատկերների տարբեր տարբերակներ:

Ամեն ինչ ճիշտ անելու համար այս սխեման պահանջում է լրացուցիչ հղում՝ հատուկ հետագծող, որը կարգավիճակի մասին տեղեկատվություն կստանա Kubernetes API-ից և կփոխանցի այն իրերի իրական վիճակի հետագա վերլուծության համար: Մենք ստեղծեցինք բաց կոդով գրադարան Go-ում - cubedog (տես դրա հայտարարությունը այստեղ), որը լուծում է այս խնդիրը և ներկառուցված է werf-ի մեջ։

Այս որոնիչի վարքագիծը werf մակարդակում կազմաձևված է ծանոթագրությունների միջոցով, որոնք տեղադրված են Deployments կամ StatefulSets-ում: Հիմնական նշում - fail-mode - հասկանում է հետևյալ իմաստները.

  • IgnoreAndContinueDeployProcess — մենք անտեսում ենք այս բաղադրիչի գործարկման խնդիրները և շարունակում ենք տեղակայումը.
  • FailWholeDeployProcessImmediately — այս բաղադրիչի սխալը դադարեցնում է տեղակայման գործընթացը.
  • HopeUntilEndOfDeployProcess — Հուսով ենք, որ այս բաղադրիչը կաշխատի մինչև տեղակայման ավարտը։

Օրինակ, ռեսուրսների և անոտացիայի արժեքների այս համադրությունը fail-mode:

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Երբ մենք առաջին անգամ տեղակայում ենք, տվյալների բազան (MongoDB) կարող է դեռ պատրաստ չլինել. տեղակայումները ձախողվելու են: Բայց դուք կարող եք սպասել այն պահին, երբ այն սկսվի, և տեղակայումը դեռ տեղի կունենա:

Werf-ում կա ևս երկու ծանոթագրություն kubedog-ի համար.

  • failures-allowed-per-replica - յուրաքանչյուր կրկնօրինակի համար թույլատրելի անկումների քանակը.
  • show-logs-until — կարգավորում է այն պահը, երբ werf-ը ցուցադրում է (stdout-ում) տեղեկամատյանները բոլոր գլորված պատյաններից: Լռելյայն է PodIsReady (անտեսել այն հաղորդագրությունները, որոնք մենք, հավանաբար, չենք ուզում, երբ երթևեկությունը սկսվում է պատիճ), բայց արժեքները նույնպես վավեր են. ControllerIsReady и EndOfDeploy.

Էլ ի՞նչ ենք ուզում տեղակայումից:

Բացի արդեն նկարագրված երկու կետերից, մենք կցանկանայինք.

  • տեսնելու համար գերաններ - և միայն անհրաժեշտները, և ոչ ամեն ինչ անընդմեջ.
  • ուղու առաջընթացը, քանի որ եթե աշխատանքը մի քանի րոպե «լուռ» կախված է, ապա կարևոր է հասկանալ, թե ինչ է կատարվում այնտեղ.
  • ունեն ավտոմատ հետադարձ այն դեպքում, երբ ինչ-որ բան սխալ է տեղի ունեցել (և, հետևաբար, կարևոր է իմանալ տեղակայման իրական կարգավիճակը): Տարածումը պետք է լինի ատոմային. կա՛մ այն ​​անցնում է մինչև վերջ, կա՛մ ամեն ինչ վերադառնում է իր նախկին վիճակին:

Արդյունքները

Մեզ համար՝ որպես ընկերություն, առաքման տարբեր փուլերում (կառուցել, հրապարակել, տեղակայել) նկարագրված բոլոր նրբերանգներն իրականացնելու համար բավական է CI համակարգը և կոմունալ ծրագիրը։ վերֆ.

Եզրակացության փոխարեն.

werf - մեր գործիքը CI / CD-ի համար Kubernetes-ում (ակնարկ և վիդեո զեկույց)

Werf-ի օգնությամբ մենք լավ առաջընթաց ենք գրանցել DevOps-ի ինժեներների համար մեծ թվով խնդիրներ լուծելու հարցում և ուրախ կլինենք, եթե ավելի լայն համայնքը գոնե փորձի այս օգտակար ծրագիրը գործողության մեջ: Միասին ավելի հեշտ կլինի լավ արդյունքի հասնել։

Տեսանյութեր և սլայդներ

Տեսանյութ ներկայացումից (~47 րոպե).

Զեկույցի ներկայացում.

PS

Այլ հաղորդումներ Kubernetes-ի մասին մեր բլոգում.

Source: www.habr.com

Добавить комментарий