Docker-պատկերների դինամիկ հավաքում և տեղադրումը werf-ի միջոցով, վարկանիշային փաստաթղթի կայքի օրինակով

Մենք արդեն մի քանի անգամ խոսել ենք մեր GitOps գործիքի մասին werf, և այս անգամ ցանկանում ենք կիսվել կայքի հավաքման փորձով՝ հենց այդ նախագծի փաստաթղթավորումից — werf.io (նրա ռուսերեն տարբերակը — ru.werf.io). Սա սովորական մենակիտ կայք է, սակայն դրա հավաքումը հետաքրքիր է նրանով, որ կառուցված է դինամիկ քանակությամբ արգենտներով:

Docker-պատկերների դինամիկ հավաքում և տեղադրումը werf-ի միջոցով, վարկանիշային փաստաթղթի կայքի օրինակով

Միանգամից չկանանք կայքի կառուցվածքի մանրամասներին՝ ընդհանուր մենյուի ստեղծում բոլոր տարբերությունների համար, հրապարակումներ և այլն՝ չենք նկարագրի: Բանակցեք այս հարցերի և առանձնահատկությունների շուրջ դինամիկ հավաքման վրա և մի փոքր CI/CD ուղեկցող գործընթացների:

Ներածություն՝ ինչպես է աշխատում կայքը

Սկսենք նրանից, որ werf-ի փաստաթղթավորումն պահվում է միասին իր օրենսգիրքի հետ: Սա հատուկ պահանջներ է դնում զարգացման համար, որոնք դրսևորվում են հիմնականում այս հոդվածից դուրս, սակայն կարելի է ասել, որ՝

  • Նոր werf ֆունկցիաները չպետք է դուրս գան փաստաթղթավորումը թարմացնելուց առանց հակառակ տվյալների; այն էլ՝ փաստաթղթավորման որևիցե փոփոխությունները ենթադրում են նոր werf տարբերակի թողարկում:
  • Նախագիծն ունի բավական ինտենսիվ զարգացում՝ նոր տարբերակները կարող են հայտնվել մի քանի անգամ օրվա ընթացքում:
  • Յուրաքանչյուր ձեռնարկային գործողությունը նոր փաստաթղթավորմամբ կայքը գործարկել առանձնապես հոգնեցուցիչ է:
  • Հաճախորդին ծածկելու համար այս բոլոր «համակարգները», առաջարկելով նրան այն, ինչը «յուրզ նշանակություն ունի», մենք ստեղծել ենք տեսակավորումվատ չունենaker instունդ болғанը, 5 կայքերի կայքից։ Թողարկման գործընթացը ենթադրում է տարբերակների հաջորդականացում կայքերից կայքեր հետևյալ են։
  • Կայքում կա ռուսերեն տարբերակ, որն «ապրում և զարգանում» է (ինքն են, պարունակությունը թարմանում), զուգահեռ հիմնական (ոչ առջևում) տարբերակին:

Ծածկելու համար օգտագործչին այդ «ըսանկալի համակարգը», առաջարկելով նրան այն, ինչը «էապես է գործում», մենք արել ենք անջատված գործիք տեղափոխման և թարմացման werf — սա multiwerf. Կայքի տարբերակներ ընտրելու ցանկում հասանելի են վերջին werf տարբերակներ յուրաքանչուր կայքում: Դրանք կատարվում են տուրում, ըստ հասցեի

werf.io/documentation հասանելի է ամենապաշտպանական կայքի արդյունքում այս վերջին թողարկման — դա էլ որոնողակետերում տեսանելի է։ Փաստաթղթավորումը հասանելի է տարբեր հասցեներում (օրինակ, werf.io/v1.0-beta/documentation 1.0-ի beta թողարկման համար): Համաձայն, կայքը հասանելի է հետևյալ տարբերակներով:

գործելու (անիրավ, ըստ հասցեի),

  1. յուրաքանչյուր ակտիվ թողարկման թարմացում (օրինակ,
  2. werf.io/v1.0-beta Ժողովուրդը նախաբանված տարբերակը կայքի կարգավորնելու համար բավական է, որ նախագծի միջոցներով որոնք կատարենք, запускае в каталоге).

repo werf համապատասխան հրահանգը ( Jekylljekyll build /docs ), նախքան անհրաժեշտ տարբերակին Git-նյութ տեղափոխվելը:Ստացվում է միայն ավելացնել, որ:հավաքման գործում օգտագործվում է հենց գործիքը (werf);

)

  • .
  • CI/CD գործընթացները կառուցված են GitLab CI հիմքում;
  • և ամեն բան, իհարկե, գործում է Kubernetes-ում:

Բեռնավորություններ

Հիմա ձևակերպենք խնդիրները, հաշվի առնելով նկարագրված բոլոր առանձնահատկությունները:

  1. werf տարբերակի փոփոխությունից հետո ցանկացած թարմացումների ալիքով վեբ կայքի փաստաթղթավորումը պետք է ինքնաբերաբար թարմանա.
  2. Էստ կ разработки нужно иметь возможность иногда տեսնել կայքի նախադիտում.

Կայքը վերածնունդ անել պետք է կատարել տարբերակի փոփոխությունից հետո ցանկացած ալիքով համապատասխան Git տարրերից, բայց տրամադրելու ընթացակարգում կունենանք հետևյալ առանձնահատկությունները:

  • Քանի որ տարբերակների ցուցակը ալիքներում փոփոխվում է, պետք է վերածրել միայն փաստաթղթավորման համար, որտեղ տարբերակը փոխվում է: Ի վերջո, վերածնել ամեն ինչ նորից չափազանց գեղեցիկ չէ:
  • Ռելիզների ալիքների համասեռման կատարումը կարող է փոխվել: Մի պահ, օրինակ, կարող է չլինել տարբերակ ալիքներում, ավելի կայուն պատերազմակցության 1.1, սակայն ժամանակի ընթացքում դրանք հայտն خواهند լինի - այդ դեպքում երկարաձգել հավաքումը ձեռքով:

Դիտվում է, որ հավաքումը կախված է փոփոխվող արտաքին տվյալներից.

Իմացում

Առաջադրանքի ընտրություն

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

Մենք գնացինք ճանապարհով Անհրաժեշտ բոլոր տարբերակների հավաքման մեկ պատկեր. Հավաքված բոլոր կայքի ստատիկները գտնվում են NGINX կոնտեյնում, իսկ համապատասխան սահմանափակումն է անցնում NGINX Ingress-ի միջոցով: Հեշտ կառուցվածքը - stateless հավելվածը - թույլ է տալիս հեշտությամբ масштабировать սահմանաչափը (ծանրաբեռնվածության կախվածությամբ) Kubernetes-ի ինքնակառավարող միջոցներով:

Եթե ճիշտ կլինենք, մենք հավաքում ենք երկու պատկեր: մեկը՝ production շրջանակի համար, իսկ մյուսը՝ լրացուցիչ՝ dev շրջանակի համար: Լրացուցիչ պատկերը օգտագործվում է (գործարկվում) միայն dev շրջանակում հիմնականի հետ միասին և պարունակում է կայքի տարբերակը review-խնդիրի մեջ, իսկ ոմանց միջև ուղղորդումը կատարվում է Ingress ռեսուրսների միջոցով:

werf مقابل git clone և արտեֆակտներ

Ինչպես արդեն նշվեց, որոշակի փաստաթղթավորման տարբերակի կայքի ստատիկը գեներելու համար հարկավոր է կատարել հավաքում, փոխելով համանման լծակների մեջ: Կարող էր նաև անել այս, կրկնել ցուցակը մոտեցքից, բայց դա բավականին ռեսուրսատար գործողություն է և, բացի այդ, անհրաժեշտ է գրել ոչ սովորական հրահանգներ... Այլ լուրջ բացասական կողմը՝ այդ մոտեցմամբ որևէ բան կեշ անել հնարավոր չէ հավաքման ժամանակ:

Այստեղ մեզ կօգնի հենց werf_utilita, որը իրականացնում է խելացի կեշավորում և թույլ է տալիս օգտագործել արտաքին պահոցներ. werf-ի օգտագործումը վերապահումից կոդի ավելացման համար զգալիորեն արագացնում է կառուցումը, քանի որ werf-ը, ըստ էության, մեկ անգամ է պահոցը դասավորում, այնուհետեւ իրականացնում է միայն հանելը ապա անհրաժեշտության դեպքում։ Այն lisäksi, երբ հավելում ենք տվյալներ պահոցից, կարող ենք ընտրել միայն անհրաժեշտ բաժինները (մեր դեպքում դա կատալո՞գը docs), ինչը զգալիորեն կրճատում է հավելվող տվյալների ծավալը։

Քանի որ Jekyll-ը գործիք է, նախատեսված ստատիկայի կոմպիլյացիայի համար եւ նա չի անհրաժեշտ վերջնական պատկերի մեջ, տրամաբանական կլիներ կոմպիլյացիան իրականացնել werf-ի արտեֆակտում, իսկ վերջնական պատկերը ներմուծել միայն կոմպիլյացիայի արդյունքը.

Գրենք werf.yaml

Այլ կերպ ասած, մենք սահմանեցինք, որ յուրաքանչյուրս տարբերակում ենք կոմպիլյացնել որևէ werf գործառույթում։ Այնուամենայնիվ, մենք չգիտենք, թե այդ գործառույթները որքան կլինեն կառուցման ընթացքում, հետեւաբար չենք կարող գրել ֆիքսված կառուցման կոնֆիգուրացիա (ճշտորեն ասած, կարող ենք, բայց դա այնքան էլ արդյունավետ չի լինի).

werf-ը թույլ է տալիս օգտվել Go-մանուշակներից իր կոնֆիգուրացիայի մեջ (werf.yaml), ինչը հնարավորություն է տալիս հանդիպել կոնֆիգը «մասին» արտաքին տվյալների հիման վրա (այրը, ինչը հարկավոր է!). Արտաքին տվյալները մեր դեպքում հանդիսանում են տարբերակների եւ թողարկումների մասին տեղեկատվություն, որի հիման վրա մենք կառուցում ենք անհրաժեշտ քանակի արհեստականներ եւ ստանում ենք արդյունքում երկու պատկերներ՝ werf-doc և werf-dev տարբեր հոսանքներում գործարկելու համար։

Արտաքին տվյալները փոխանցվում են միջավայրի փոփոխականների միջոցով։ Ահա նրանց հիմնական կազմը՝

  • RELEASES — սպառական շարքը, որի մեջ է ցուցակի թողարկումների եւ համապատասխան փաստաբանի անմիջական տարբերակը werf-ի, ըստ հաստափառով այստեղ է ցուցակով միջոցով ծավալվում <ՀԵՐՈՒՇ_ԹՈՒՐԱԲԱՆ>%<ՀԵՐՈՒՇ_ԲԱՅՑ>. Օրինակ՝ 1.0%v1.0.4-beta.20
  • CHANNELS — սպառողական շարքը, որի մեջ է ցուցակի փոսաթողարկային ելքը եւ համապատասխան փաստաբանի անմիջական տարբերակը werf-ի, ըստ հաստափառով այստեղ է ցուցակով միջոցով ծավալվում <ՓՈՍԱ>%<ՀԵՐՈՒՇ_ԲԱՅՑ>. Օրինակ՝ 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — werf-ի պարադիգման, որի ապահովման գործառնությունն է՝ հրատարակելով համեմատություն (չօգտագործելով ընթացքում փաստագիտներ ֆանտախտահի նշումը՝). Օրինակ՝ v1.0.4-beta.20
  • REVIEW_SHA — մառելու վերածումը, այն ինձց ասում է, ի՞նչ պետք է հավաքել փորձարկման շրջանակում։

Այս փոփոխականները կապացվում են GitLab CI-ի ալերգրում, իսկ ինչպես՝ գրավոր է ստորև։

Առաջին հերթին, գործառնական հարմարության համար, սահմանենք werf.yaml Go-մանուշակներում փոփոխականներ, նրանց շնորհելով միջավայրի փոփոխականների արժեքները՝

{{ $_ := set . "WerfVersions" (cat (env "CHANNELS") (env "RELEASES") | splitList " ") }}
{{ $Root := . }}
{{ $_ := set . "WerfRootVersion" (env "ROOT_VERSION") }}
{{ $_ := set . "WerfReviewCommit" (env "REVIEW_SHA") }}

Պիսի արվեստի նկարագրությունը, որը ձեւավորում է կայքի տարբերակի սպառանքի աշխարհում ձեւավորելու համար մեկ երևիք է, բոլոր անհրաժեշտ հիմքերի դեպքում (ներառյալ՝ թիմի կազմումը, ինչպես նաեւ dev հոսանքի կոմպիլյացիան)։ Ուստի մենք այն կհեռացված մի մոնտի հետ միջոցով գործի նշանակել — վերջնականությամբ վերոնշվել դիմավորումով include. Մանուշաքրին մեզ կանցկացնենք հետեւյալ արկղերով՝

  • Արժեք — ստեղծվող տարբերակ (թեգի անվանում)՝
  • Channel — թարմացումների ալիքի անուն, որի համար գեներացվում է արկղը։
  • Commit — կոմիտեի հեշ, եթե արկղը գեներացվում է review կոմիտեի համար։
  • համատեքստ։

Արկղի ձևանմուշի նկարագրությունը

{{- սահմանել "doc_artifact" -}}
{{- $Root := index . "Root" -}}
artifact: doc-{{ .Channel }}
from: jekyll/builder:3
mount:
- from: build_dir
  to: /usr/local/bundle
ansible:
  install:
  - shell: |
      export PATH=/usr/jekyll/bin/:$PATH
  - name: "Տեղադրեք կախվածությունները"
    shell: bundle install
    args:
      executable: /bin/bash
      chdir: /app/docs
  beforeSetup:
{{- if .Commit }}
  - shell: echo "Review SHA - {{ .Commit }}."
{{- end }}
{{- if eq .Channel "root" }}
  - name: "releases.yml HASH: {{ $Root.Files.Get "releases.yml" | sha256sum }}"
    copy:
      content: |
{{ $Root.Files.Get "releases.yml" | indent 8 }}
      dest:  /app/docs/_data/releases.yml
{{- else }}
  - file:
      path: /app/docs/_data/releases.yml
      state: touch
{{- end }}
  - file:
      path: "{{`{{ item }}`}}"
      state: directory
      mode: 0777
    with_items:
    - /app/main_site/
    - /app/ru_site/
  - file:
      dest: /app/docs/pages_ru/cli
      state: link
      src: /app/docs/pages/cli
  - shell: |
      echo -e "werfVersion: {{ .Version }}nwerfChannel: {{ .Channel }}" > /tmp/_config_additional.yml
      export PATH=/usr/jekyll/bin/:$PATH
{{- if and (ne .Version "review") (ne .Channel "root") }}
{{- $_ := set . "BaseURL" ( printf "v%s" .Channel ) }}
{{- else if ne .Channel "root" }}
{{- $_ := set . "BaseURL" .Channel }}
{{- end }}
      jekyll build -s /app/docs  -d /app/_main_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/tmp/_config_additional.yml
      jekyll build -s /app/docs  -d /app/_ru_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/app/docs/_config_ru.yml,/tmp/_config_additional.yml
    args:
      executable: /bin/bash
      chdir: /app/docs
git:
- url: https://github.com/flant/werf.git
  to: /app/
  owner: jekyll
  group: jekyll
{{- if .Commit }}
  commit: {{ .Commit }}
{{- else }}
  tag: {{ .Version }}
{{- end }}
  stageDependencies:
    install: ['docs/Gemfile','docs/Gemfile.lock']
    beforeSetup: '**/*'
  includePaths: 'docs'
  excludePaths: '**/*.sh'
{{- end }}

Արկղի անունը պետք է լինի ընդհանրապես եզակի։ Մենք կարող ենք դա հասնել, օրինակ, ավելացնելով ալիքի անվանումը (խմբի արժեքը .Channel) արկղի անվան ՝ որպես սուֆիքս։ artifact: doc-{{ .Channel }}. Բայց անհրաժեշտ է հասկանալ, որ արկղերից ներմուծելիս պետք է հղում անել նման անուններին։

Արկղի նկարագրության ժամանակ օգտագործվում է werf-ի նման հնարավորություն, ինչպես մոնտաժում։ Մոնտաժումը տիրույթը նշելու միջոցով build_dir ի տարբերակն է Jekyll կոշտքները պահպանելու համար՝ մինչեւ խողովակների վազք, որը երկարաժամկետ արագացնում է վերակառուցումը.

Դուք նույնպես կարող եք նկատել, որ օգտագործվում է releases.yml — այս YAML-ի ֆայլը պատմող նոմենկլատուրայի մասին, ինչը պահանջում է github.com (արկղ, որն ստացվում է խողովակների կատարումից)։ Այն անհրաժեշտ է կայքի կոմպիլացիայի համար, բայց այս հոդվածի համատեքստում մեզ հետաքրքրում է այն բանը, որ դրա վիճակն ազդում է միայն մեկ արկղի վերակառուցում — կայքի արմատային տարբերակի արկղ (սայլ է, որ այլ արկղերում դա անհրաժեշտ չէ)։

Սա իրականացվում է թե՛ անվաննումների միջոցով if Go-ման்த்தեզները և կառուցվածքների միջոցով {{ $Root.Files.Get "releases.yml" | sha256sum }} քայլի փուլում։ Սա գործում է հետևյալ ձևով՝ երբ արկղը կառուցվում է արմատային տարբերակի համար (փոխադարձ .Channel հավասար է root) ֆայլի հեշը releases.yml ազդում է ողջ փուլի ստորագրությանը, քանի որ դա Ansible-ի հանձնարարության անունին պատգաողելի է (պարամետրը name)։ Այսպիսով, երբ փոփոխվում է բովանդակությունը ֆայլ releases.yml համապատասխան արկղը վերակառուցվելու է։

Դիտեք նաև արտաքին պահոցների հետ աշխատանքը։ Առավելագույն արհեստավոր ստերևողության մեջ պահոցից werf, ավելացվում է միայն կատալոգ /docs, այսպիսով, փոխանցված պարամետրերից կախված, ավելացվում են տվյալները անմիջապես անհրաժեշտ պիտակի կամ review-կոմիտեի:

Արտեֆակտի շաբլոնն օգտագործելու համար, որ գեներացիա описание артефакта փոխանցված տարբերակների ալիքների և թողարկումների, կազմակերպում ենք ցիկլ ըստ փոփոխականի .WerfVersions մեջ werf.yaml:

{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ dict "Version" $VersionsDict._1 "Channel" $VersionsDict._0 "Root" $Root | include "doc_artifact" }}
---
{{ end -}}

Քաղաքականություն, որ ցիկլը կստեղծի մի քանի արհեստավոր (ն esperamos), անհրաժեշտ է հաշվի առնել բաժանորդը դրանց միջև՝ հաջորդականությունը --- (տվյալների մասին ֆայլի համակարքի սինտաքսից ավելին տեսնել՝ փաստաթղթավորումը). Ինչպես արդեն նշվեց, ցիկլում շաբլոնը կանչվի, փոխանցելով տարբերակի, URL-ի և արմատային համատեքստի պարամետրերը:

Նմանապես, բայց արդեն առանց ցիկլի, կանչում ենք արհեստավորի շաբլոն «특별한 кейսերի համար»: արմատային տարբերակի և նաև review-комитից տարբերակի համար:

{{ dict "Version" .WerfRootVersion "Channel" "root" "Root" $Root  | include "doc_artifact" }}
---
{{- if .WerfReviewCommit }}
{{ dict "Version" "review" "Channel" "review" "Commit" .WerfReviewCommit "Root" $Root  | include "doc_artifact" }}
{{- end }}

Ստուգեք, որ review-комիտի արհեստավորը կկառուցվի միայն այն դեպքում, եթե սահմանված լինի փոփոխականը .WerfReviewCommit.

Արտեֆակտները պատրաստ են՝ ժամանակն է զբաղվել ներմուծմամբ!

Վերջնական կերպարանքը, նախատեսված Kubernetes-ում աշխատելու համար, ներկայացում է սովորական NGINX, որի մեջ ավելացվել է սերվերի կոնֆիգուրացման ֆայլը nginx.conf և վիճակագրությունը արհեստավորներից։ Բացի կայքի արմատային տարբերակից, մեզ անհրաժեշտ է իրականացնել ցիկլ ըստ փոփոխականի .WerfVersions ալիքների և թողարկումների տարբերակների արհեստավորների ներմուծման համար + պահպանել արհեստավորների անվանման կանոնները, որոնք մենք հաստատեցինք ավելի վաղ: Քանի որ յուրաքանչյուր արհեստավոր պահում է կայքի տարբերակները երկու լեզուների համար, ներմուծում ենք դրանք վայրերում, որոնք նախատեսված են կոնֆիգուրացիայի:

Վերջնական արհեստավորի նկարագրությունը werf-doc

image: werf-doc
from: nginx:stable-alpine
ansible:
  setup:
  - name: "Setup /etc/nginx/nginx.conf"
    copy:
      content: |
{{ .Files.Get ".werf/nginx.conf" | indent 8 }}
      dest: /etc/nginx/nginx.conf
  - file:
      path: "{{`{{ item }}`}}"
      state: directory
      mode: 0777
    with_items:
    - /app/main_site/assets
    - /app/ru_site/assets
import:
- artifact: doc-root
  add: /app/_main_site
  to: /app/main_site
  before: setup
- artifact: doc-root
  add: /app/_ru_site
  to: /app/ru_site
  before: setup
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
  add: /app/_main_site
  to: /app/main_site/v{{ $Channel }}
  before: setup
{{ end -}}
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
  add: /app/_ru_site
  to: /app/ru_site/v{{ $Channel }}
  before: setup
{{ end -}}

Լրացուցիչ կերպարանք, որը հիմնականի հետ միասին աշխատում է dev-ավտոմատիկայում, պարունակում է միայն երկու կայքի տարբերակներ՝ review-комիտից տարբերակը և կայքի արմատային տարբերակը (տեղում ընդհանուր ակտիվներ և, եթե հիշում եք, տվյալներ թողարկումներին): Այսպիսով, լրացուցիչ կերպարանքը հիմնականից կտարբերվի միայն ներմուծման բաժնով (որովհետև, իհարկե, անունով):

ղեկավարություն: werf-dev
...
Ներմուծում:
- արկղիկ: doc-root
  ավելացնել: /app/_main_site
  հասցեով: /app/main_site
  նախքան: կարգավորում
- արկղիկ: doc-root
  ավելացնել: /app/_ru_site
  հասցեով: /app/ru_site
  նախքան: կարգավորում
{{- եթե .WerfReviewCommit  }}
- արկղիկ: doc-review
  ավելացնել: /app/_main_site
  հասցեով: /app/main_site/review
  նախքան: կարգավորում
- արկղիկ: doc-review
  ավելացնել: /app/_ru_site
  հասցեով: /app/ru_site/review
  նախքան: կարգավորում
{{- վերջ }}

Ինչպես արդեն նշվեց վերևում, review-commit-ի արկղիկը կստեղծվի միայն տեղադրված միջավայրի փոփոխականը գործարկելու ժամանակ REVIEW_SHA. Հնարավոր էր անգամ չստեղծել werf-dev պատկեր, եթե միջավայրի փոփոխականը չկա REVIEW_SHA, բայց դրա համար Քրոնոսացությաբ ակաունթեր Docker-յան պատկերների մաքրումը werf-ի կողմից աշխատելը werf-dev-ի համար, մենք կթողնենք նրա կազմվելը միայն արմատային տարբերակի արկղիկով (այլև նա արդեն կազմված է), որպեսզի պարզեցնենք pipeline-ի կառուցվածքը.

Օգտագործումը պատրաստ է! Մոտենում ենք CI/CD և կարևոր մանրամասներին.

Pipeline-ը GitLab CI-ում և դինամիկ կազմման առանձնահատկությունները

Կազմման ժամանակ անհրաժեշտ է տեղադրել այն միջավայրի փոփոխականները, որոնք օգտագործվում են werf.yaml. Սա չի վերաբերում REVIEW_SHA փոփոխականին, որը մենք կտեղադրենք GitHub-ի հանքից pipeline-ի ընթացքում.

Պետք է անհրաժեշտ արտաքին տվյալների ստեղծումը դուրս բերենք Bash-սկրիպտի մեջ generate_artifacts, որը ստեղծելու է երկու արկղիկ GitLab pipeline-ի համար:

  • ֆայլին releases.yml ու տարբերակների տվյալներով,
  • ֆայլին common_envs.sh, պարունակում է արտահ מוזխաների փոփոխականներ արտահանելու համար.

Ֆայլի մոնտաժը generate_artifacts գտնում եք մեր մասնագիտական օրինակների հանրագիտարանում.. Արդյունքները ստանալը հոդվածի առարկան չէ, իսկ ֆայլը common_envs.sh մեզ կարևոր է, որովհետև նրանից կախված է werf-ի աշխատանքը. Նրա բովանդակության օրինակ:

export RELEASES='1.0%v1.0.6-4'
export CHANNELS='1.0-alpha%v1.0.7-1 1.0-beta%v1.0.7-1 1.0-ea%v1.0.6-4 1.0-stable%v1.0.6-4 1.0-rock-solid%v1.0.6-4'
export ROOT_VERSION='v1.0.6-4'

Այդպիսի սկրիպտի արդյունքը կարող եք օգտագործել, օրինակ, Bash ֆունկցիայի միջոցով source.

Եվ այժմ ամենահետաքրքիր մասն է. Որպեսզի և կազմումը, և -ն ավարտը ճիշտ աշխատեն, անհրաժեշտ է անել այնպես, որ werf.yaml հասնափայտը միանման պակասագույնը մի pipeline-ի շրջանակներում. Եթե այս պայմանը չկատարվի, ապա փուլերի ստորագրությունները, որոնք հաշվում է werf-ը կազմման և, օրինակ, -ն ավարտելու համար, տարբեր կլինեն. Սա կհանգեցնի ավարտման սխալ, քանի որ անհրաժեշտ ավարտման արկղիկը չի լինի.

Խոսելով ուրիշ կերպ. Եթե կայքի պատկերագործման ժամանակ տեղեկությունը տարբերակների և տարբերակիցների մասին մեկ լինի, իսկ ավարտվող պահին դուրս գա նոր տարբերակ և միջավայրի փոփոխականները ունենան այլ արժեքներ, ապա ավարտումը կավարտվի սխալով. որովհետև նոր տարբերակի արկղիկը դեռևս կազմված չէ.

Ամոթ թողարկում werf.yaml կախված է արտաքին տվյալներից (օրինակ, ժամանակակից տարբերակների ցուցակից, ինչպես մեր դեպքում), ապա դրանց կազմը և արժեքները պետք է фиксируются pipeline-ի շրջանակներում. Սա հատկապես կարևոր է, եթե արտաքին պարամետրերը բավական հաճախ փոխվում են.

Մենք կստանք և կտրիճենք արտաքին տվյալները pipeline-ի առաջին փուլում GitLab-ում (Prebuild) և փոխանցում այն ավելի խորության հաջող տեղեկատվություն GitLab CI արկղիկ. Սա թույլ կտա գործարկելու և վերագործարկելու pipeline-ի առաջադրանքները (կազմություն, ավարտ, մաքրում) նույն կազմաձևում werf.yaml.

Փուլի բովանդակությունը Prebuild ֆայլ .gitlab-ci.yml:

Դեպրիվիդել:
  փուլ: նախակառուցում
  սկրիպտ:
    - bash ./generate_artifacts 1> common_envs.sh
    - cat ./common_envs.sh
  արխիվներ:
    ուղիներ:
      - releases.yml
      - common_envs.sh
    ժամկետը՝ 2 շաբաթ

Արտեֆակտում արտաքին տվյալները ձեւակերպելով, կարելի է կատարել կառուցում եւ տեղադրում, օգտագործելով GitLab CI-ի ստանդարտ փուլերը՝ Build եւ Deploy: Միասնական փուլը մեկնարկում ենք GitHub-յան werf ռեպոզիտորից ծրագրային միջավայրերի փոփոխություններով (այսինքն՝ GitHub-ում ռեպոզիտորիայի փոփոխությունների ժամանակ): Դրանք կարելի է վերցնել GitLab նախագծի հատկություններում 'CI / CD Settings' բաժնում CI / CD Settings -> Pipeline triggers, եւ ապա կստեղծենք GitHub-ում համապատասխան Webhook (Settings -> Webhooks).

Կառուցման փուլը կտեսակավորվի հետևյալ կերպ:

Build:
  փուլ: կառուցում
  սկրիպտ:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - werf build-and-publish --stages-storage :local
  բացառություններ:
    refs:
      - schedules
  կախվածություններ:
    - Prebuild

GitLab-ը կավելացնի կառուցման փուլում երկու արտեֆակտ նախորդ փուլից, Prebuild, այնպես որ մենք արտահանելու ենք փոփոխականները նախապատրաստված մուտքային տվյալներով՝ օգտագործելով կառուցվածքը source common_envs.sh. Կառուցման փուլը սկսում ենք բոլոր դեպքերում, բացի այն դեպքերից, երբ փուլը գործարկվում է ժամանակացույցի համաձայն: Ժամանակացույցով մենք կհետեւենք մաքրող փուլին՝ այս դեպքում կառուցումը անհրաժեշտ չէ:

Տեղադրման փուլում մենք նկարագրելու ենք երկու առաջադրանք՝ առանձին համար արտադրական եւ dev սենյակներ, օգտագործելով YAML-шабլոն:

.base_deploy: &base_deploy
  փուլ: տեղադրում
  սկրիպտ:
    - type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - werf deploy --stages-storage :local
  կախվածություններ:
    - Prebuild
  բացառություններ:
    refs:
      - schedules

Արտադրական տեղադրում:
  <<: *base_deploy
  փոփոխականներ:
    WERF_KUBE_CONTEXT: prod
  միջավայր:
    անվանում: արտադրական
    url: werf.io
  միայն:
    refs:
      - master
  բացառություններ:
    փոփոխականներ:
      - $REVIEW_SHA
    refs:
      - schedules

Թեստի տեղադրում:
  <<: *base_deploy
  փոփոխականներ:
    WERF_KUBE_CONTEXT: dev
  միջավայր:
    անվանում: փորձարկում
    url: werf.test.flant.com
  բացառություններ:
    refs:
      - schedules
  միայն:
    փոփոխականներ:
      - $REVIEW_SHA

Գործողությունները, հիմնականում, տարբերակվում են միայն այն բանի համար՝ որ werf-ը պետք է տեղադրվի (WERF_KUBE_CONTEXT), եւ միջավայրի փոփոխականների սահմանմամբ (environment.name և environment.url), որոնք հետո օգտագործվում են Helm-шабլոններում: Շաբլոնների բովանդակությունը չպիտի ներկայացվի, քանի որ այնտեղ ոչ մի հետաքրքրություն չկա քննարկվող թեմայի համար, բայց դուք կարող եք դրանք գտնել հոդվածի ռեպոզիտորայում.

Ավարտական քայլ

Քանի որ werf-ի տարբերակները հաճախ են թողարկվում, նոր նկարագրություններ հաճախ են կազմվում, իսկ Docker Registry-ն մշտապես աճում է: Իհարկե, անհրաժեշտ է կարգավորել ավտոմատ մաքրում նկարագրությունների քաղաքականությունների հիման վրա: Սա շատ հեշտ է իրագործել.

Հիմնականի իրականացման համար անհրաժեշտ է:

  • Մաքրող փուլ ավելացնել .gitlab-ci.yml;
  • Ավելացնել պարբերական մաքրող առաջադրանք;
  • Կարգավորել մուտքային փոփոխական անվտանգության ստորագրություն:

Մաքրող փուլ ավելացնել .gitlab-ci.yml:

Մաքրում:
  փուլ: մաքրել
  սկրիպտ:
    - տեսակը multiwerf && . $(multiwerf use 1.0 alpha --as-file)
    - տեսակը werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - source common_envs.sh
    - docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
    - werf cleanup --stages-storage :local
  միայն:
    refs:
      - schedules

Ամեն ինչինը մենք արդեն տեսել ենք վերն boven — մաքրման համար նախ անհրաժեշտ է մուտք գործել Docker Registry՝ բեռնող նշանն ունեցող նշանով, որը ունի Docker Registry-ում պատկերների ջնջում թույլատրող իրավունքներ (GitLab CI-ից ավտոմատ ստացված նշանը այդ իրավունքները չունի): Տեսակետը պետք է նախապես ստեղծվի GitLab-ում և դրա արժեքը պետք է նշանակվի շրջաբերական փոփոխականում WERF_IMAGES_CLEANUP_PASSWORD ծրագրի (CI/CD սահմանումներ -> փոփոխականներ).

Մաքրման առաջադրանքը անհրաժեշտ ժամանակացույցով ավելացվում է CI/CD ->
Ժամանակացույցներ
.

Այն ամենը: նախագիծը Docker Registry-ում այլևս չպետք է միակիսի վերգետնային աճի ոչ օգտագործված պատկերների պատճառով:

Առաջին մասի ավարտին հիշեցնեմ, որ հոդվածի ամբողջական ցուցակները հասանելի են Git:

Արդյունք

  1. Մենք ստացանք կառուցվածքի բոլոր ձևերը: մեկ գոյություն մի տարբերակին.
  2. Կառուցվածքը համընդհանուր է և չի պահանջում ձեռքով փոփոխություններ, երբ նոր werf տարբերակներ դուրս են գալիս: փաստաթղթավորումը կայքում ավտոմատ կերպով թարմացվում է:
  3. Ամեն դեպքում հավաքվում են երկու պատկերներ տարբեր շրջանակների համար.
  4. Աշխատում է արագ, քանի որ առավելագույնս օգտագործում է կաշվեֆիկացումը. նոր werf տարբերակի դուրս գալու կամ GitHub-ի ձողակելու հետ կապված վերանայելու տեղյակությունը — միայն համապատասխան արվեստի հավաքումը, որը փոփոխվում է տարբերակում:
  5. Ինչպես էլ լինի, պետք չէ մտածել չօգտագործվող պատկերների ջնջման մասին. մաքրման համակարգերով werf-ը կպահի կարգադրությունը Docker Registry-ում:

Արդուկները

  • werf-ի օգտագործումը բարելավում է հավաքման արագությունը, ինչպես նաև հավաքման ժամանակում կաշվեֆիկացման ժամանակ:
  • Արտաքին Git-գործատուներով աշխատելը ազատում է հարկադիր հետևյալ պակասից կամ սպիտակելում ազատվելուց... werf-ը օգտագործում է կաշվեֆիկացումը և անում է հատվածային հավաքման միայն մեկ անգամ, իսկ հետագայում օգտագործում է հանելը և միայն անհրաժեշտության դեպքում.
  • Go-թղթապանակների օգտագործման հնարավորությունը հավաքման կոնֆիգուրացիայի ֆայլում werf.yaml հնարում է նկարագրել հավաքումը, որի արդյունքները կախված են արտաքին տվյալներից.
  • werf-ի օդորակման օգտագործումը կտրուկ մեծացնում է առարկաների հավաքումը — միայն կաշվեֆիկացման հաշվին, որը ընդհանուր է բոլոր pipeline-ի համար:
  • werf-ը հեշտացնում է մաքրման կարգավորումը, ինչը հատկապես արդիական է դինամիկ հավաքման պատճառով:

P.S.

Նաեւ կարդացեք մեր բլոգում:

Ընտանիք: habr.com

Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով 🔥 Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster