Dynamyske gearstalling en ynset fan Docker-ôfbyldings mei werf mei it foarbyld fan in ferzje fan dokumintaasjeside

Wy hawwe al mear as ien kear praat oer ús GitOps-ark. werf, en dizze kear wolle wy ús ûnderfining diele by it gearstallen fan de side mei de dokumintaasje fan it projekt sels - werf.io (syn Russyske ferzje is en.werf.io). Dit is in gewoane statyske side, mar syn gearstalling is ynteressant yn dat it is boud mei in dynamysk oantal artefakten.

Dynamyske gearstalling en ynset fan Docker-ôfbyldings mei werf mei it foarbyld fan in ferzje fan dokumintaasjeside

Gean yn 'e nuânses fan' e sidestruktuer: it generearjen fan in mienskiplik menu foar alle ferzjes, siden mei ynformaasje oer releases, ensfh. - Wy sille net. Litte wy ynstee rjochtsje op 'e problemen en funksjes fan dynamyske gearstalling en in bytsje op' e byhearrende CI / CD-prosessen.

Yntroduksje: hoe't de side wurket

Om te begjinnen, werf dokumintaasje wurdt bewarre tegearre mei syn koade. Dit stelt bepaalde ûntwikkelingseasken op dy't oer it algemien bûten it berik fan dit artikel lizze, mar op syn minst kin sein wurde dat:

  • Nije werffunksjes meie net frijjûn wurde sûnder de dokumintaasje by te wurkjen en oarsom betsjuttet alle feroarings yn de dokumintaasje it útbringen fan in nije ferzje fan werf;
  • It projekt hat in frij yntinsive ûntwikkeling: nije ferzjes kinne ferskate kearen deis útbrocht wurde;
  • Alle hânmjittige operaasjes om in side yn te setten mei in nije ferzje fan dokumintaasje binne op syn minst saai;
  • It projekt nimt in semantyske oanpak oan ferzje, mei 5 stabiliteitskanalen. It frijlittingsproses omfettet opienfolgjende passaazje fan ferzjes troch kanalen yn folchoarder fan tanimmende stabiliteit: fan alfa oant rock-solid;
  • De side hat in Russysktalige ferzje, dy't "libbet en ûntwikkelt" (dat wol sizze, wêrfan de ynhâld wurdt bywurke) parallel mei de haadferzje (dus Ingelsktalige).

Om al dizze "ynterne keuken" fan 'e brûker te ferbergjen, him wat te bieden dat "gewoan wurket", hawwe wy dien apart werf ynstallaasje en update ark Is multiwerf. Jo moatte gewoan it releasenûmer en it stabiliteitskanaal opjaan dat jo ree binne om te brûken, en multiwerf sil kontrolearje oft der in nije ferzje is op it kanaal en download it as it nedich is.

Yn it ferzjekeuzemenu op de webside binne yn elk kanaal de lêste ferzjes fan werf beskikber. Standert, troch adres werf.io/documentation de ferzje fan it meast stabile kanaal foar de lêste release iepent - it wurdt ek yndeksearre troch sykmasines. Dokumintaasje foar it kanaal is beskikber op aparte adressen (bygelyks, werf.io/v1.0-beta/documentation foar beta release 1.0).

Yn totaal hat de side de folgjende ferzjes beskikber:

  1. root (iepenet standert),
  2. foar elk aktyf updatekanaal fan elke release (bygelyks, werf.io/v1.0-beta).

Om in spesifike ferzje fan in side te generearjen, is it yn 't algemien genôch om it te kompilearjen mei help fan Jekylltroch te rinnen yn 'e map /docs werf repository corresponding command (jekyll build), nei it wikseljen nei de Git-tag fan 'e fereaske ferzje.

It bliuwt allinich om ta te foegjen dat:

  • it nut sels (werf) wurdt brûkt foar montage;
  • CI / CD prosessen binne boud op basis fan GitLab CI;
  • en dit alles rint fansels yn Kubernetes.

taken

Litte wy no taken formulearje dy't rekken hâlde mei alle beskreaune spesifikaasjes:

  1. Nei it feroarjen fan de werf ferzje op elk update kanaal dokumintaasje op 'e side moat automatysk bywurke wurde.
  2. Foar ûntwikkeling moatte jo soms kinne besjoch foarbyldferzjes fan 'e side.

De side moat opnij kompilearre wurde nei it feroarjen fan de ferzje op elk kanaal fan 'e oerienkommende Git-tags, mar yn it proses fan it bouwen fan it byld krije wy de folgjende funksjes:

  • Sûnt de list mei ferzjes op kanalen feroaret, is it allinich nedich om de dokumintaasje opnij op te bouwen foar kanalen wêr't de ferzje feroare is. Alles wer opbouwe is ommers net sa moai.
  • De set fan kanalen foar releases kin feroarje. Op in stuit kin d'r bygelyks gjin ferzje op 'e kanalen wêze dy't stabiler is dan de iere tagong 1.1-release, mar oer de tiid sille se ferskine - yn dit gefal moatte jo de gearstalling net manuell feroarje?

It bliuwt dat gearkomste is ôfhinklik fan it feroarjen fan eksterne gegevens.

Ymplemintaasje

Kies in oanpak

As alternatyf kinne jo elke fereaske ferzje útfiere as in aparte pod yn Kubernetes. Dizze opsje betsjuttet in grutter tal objekten yn it kluster, dat sil groeie mei it tanimmen fan it tal stabile werfútjeften. En dit, op syn beurt, ymplisearret mear komplekse ûnderhâld: elke ferzje hat syn eigen HTTP-tsjinner, en mei in lytse lading. Dat bringt fansels ek gruttere boarnekosten mei.

Wy namen itselde paad gearstalling fan alle nedige ferzjes yn ien ôfbylding. De gearstalde statyk fan alle ferzjes fan 'e side lizze yn in kontener mei NGINX, en ferkear nei de oerienkommende Deployment komt fia NGINX Ingress. In ienfâldige struktuer - in steatleaze applikaasje - lit jo ynset maklik skaalje (ôfhinklik fan 'e lading) mei Kubernetes sels.

Om krekter te wêzen, sammelje wy twa ôfbyldings: ien foar it produksjesirkwy, de twadde is in ekstra foar it dev-sirkwy. De ekstra ôfbylding wurdt brûkt (lansearre) allinnich op de dev circuit tegearre mei de wichtichste en befettet de ferzje fan de side út de resinsje commit, en routing tusken harren wurdt útfierd mei help fan Ingress boarnen.

werf vs git kloon en artefakten

Lykas al neamd, om sidestatyk te generearjen foar in spesifike ferzje fan 'e dokumintaasje, moatte jo bouwe troch te wikseljen nei de passende repository-tag. Jo kinne dit ek dwaan troch it repository te klonen elke kear as jo bouwe, selektearje de passende tags út in list. Dit is lykwols in frij boarne-yntinsive operaasje en fereasket boppedat it skriuwen fan net-triviale ynstruksjes ... In oar serieus neidiel is dat mei dizze oanpak gjin manier is om wat te cache tidens assemblage.

Hjir komt it werfbedriuw sels ús te helpen, útfierend smart caching en lit jo brûke eksterne repositories. It brûken fan werf om koade út it repository ta te foegjen sil de bou signifikant fersnelle, om't werf kloont yn wêzen de repository ien kear en fiert dan út allinnich fetch as it nedich is. Derneist kinne wy ​​​​by it tafoegjen fan gegevens út it repository allinich de nedige mappen selektearje (yn ús gefal is dit de map docs), wat de hoemannichte tafoege gegevens signifikant sil ferminderje.

Om't Jekyll in ark is ûntworpen foar it kompilearjen fan statyske gegevens en net nedich is yn 'e definitive ôfbylding, soe it logysk wêze om te kompilearjen yn werf artefakt, en yn 'e definitive ôfbylding ymportearje allinich it kompilaasjeresultaat.

Wy skriuwe werf.yaml

Sa, wy besletten dat wy soenen kompilearje elke ferzje yn in apart werf artefakt. Lykwols wy wy witte net hoefolle fan dizze artefakten sille wêze tidens gearkomste, Sa kinne wy ​​gjin fêste build-konfiguraasje skriuwe (strikt sprutsen kinne wy ​​noch, mar it sil net hielendal effektyf wêze).

werf kinne jo brûke Gean sjabloanen yn jo konfiguraasjetriem (werf.yaml), en dit makket it mooglik generearje config on the fly ôfhinklik fan eksterne gegevens (wat jo nedich hawwe!). Eksterne gegevens yn ús gefal binne ynformaasje oer ferzjes en releases, op basis wêrfan wy it fereaske oantal artefakten sammelje en as gefolch krije wy twa ôfbyldings: werf-doc и werf-dev om te rinnen op ferskate circuits.

Eksterne gegevens wurde trochjûn troch omjouwingsfariabelen. Hjir is har komposysje:

  • RELEASES - in rigel mei in list mei útjeften en de byhearrende aktuele ferzje fan werf, yn 'e foarm fan in spaasjes skieden list mei wearden yn it formaat <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>... Foarbyld: 1.0%v1.0.4-beta.20
  • CHANNELS - in rigel mei in list mei kanalen en de oerienkommende aktuele ferzje fan werf, yn 'e foarm fan in spaasjes skieden list mei wearden yn it formaat <КАНАЛ>%<НОМЕР_ВЕРСИИ>... Foarbyld: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION - werf release ferzje dy't standert werjûn wurde op 'e side (it is net altyd nedich om dokumintaasje wer te jaan mei it heechste releasenûmer). Foarbyld: v1.0.4-beta.20
  • REVIEW_SHA - hash fan 'e beoardielingskommisje wêrfan jo de ferzje moatte bouwe foar de testloop.

Dizze fariabelen sille wurde ynfolle yn 'e GitLab CI-pipeline, en hoe krekt wurdt hjirûnder skreaun.

Earst fan alles, foar gemak, wy definiearje yn werf.yaml Gean sjabloanfariabelen, tawize se wearden fan omjouwingsfariabelen:

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

De beskriuwing fan it artefakt foar it kompilearjen fan 'e statyske ferzje fan' e side is oer it algemien itselde foar alle gefallen dy't wy nedich binne (ynklusyf it generearjen fan 'e rootferzje, lykas de ferzje foar it dev-sirkwy). Dêrom sille wy it yn in apart blok ferpleatse mei de funksje define - foar folgjende wergebrûk include. Wy sille de folgjende arguminten trochjaan oan it sjabloan:

  • Version - generearre ferzje (tagnamme);
  • Channel - de namme fan it fernijingskanaal wêrfoar it artefakt wurdt generearre;
  • Commit - commit hash, as it artefakt wurdt generearre foar in resinsje commit;
  • kontekst.

Artefakt Template Beskriuwing

{{- define "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: "Install Dependencies"
    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 }}

De artefaktnamme moat unyk wêze. Wy kinne dit berikke, bygelyks troch it tafoegjen fan de kanaalnamme (de wearde fan 'e fariabele .Channel) as efterheaksel oan de namme fan it artefakt: artifact: doc-{{ .Channel }}. Mar jo moatte begripe dat as jo ymportearje fan artefakten, jo moatte ferwize nei deselde nammen.

By it beskriuwen fan in artefakt wurdt de folgjende werffunksje brûkt: mounting. Montage oanjout de tsjinst triemtafel build_dir kinne jo bewarje de Jekyll cache tusken pipeline rint, hokker fersnelt de gearstalling signifikant.

Jo hawwe miskien ek it gebrûk fan it bestân opmurken releases.yml is in YAML-bestân mei frijlittingsgegevens oanfrege fan github.com (in artefakt krigen by it útfieren fan in pipeline). It is nedich by it kompilearjen fan de side, mar yn 'e kontekst fan it artikel is it foar ús ynteressant, om't it hinget fan syn steat reassembly fan mar ien artefakt - in artefakt fan 'e rootferzje fan' e side (it is net nedich yn oare artefakten).

Dit wurdt ymplementearre mei de betingsten ferklearring if Gean sjabloanen en ûntwerpen {{ $Root.Files.Get "releases.yml" | sha256sum }} yn it poadium stadia. It wurket as folget: by it bouwen fan in artefakt foar de rootferzje (fariabele .Channel is gelyk oan root) triem hash releases.yml beynfloedet de hantekening fan it hiele poadium, om't it diel is fan 'e namme fan 'e Ansible-taak (parameter name). Dus, by it feroarjen ynhâld map releases.yml it korrespondearjende artefakt wurdt opnij gearstald.

Soargje ek omtinken foar it wurkjen mei in eksterne repository. Yn it byld fan in artefakt út werf repository, allinnich de map wurdt tafoege /docs, en ôfhinklik fan de trochjûn parameters, de gegevens fan de fereaske tag of review commit wurdt tafoege fuortendaliks.

Om it artefaktsjabloan te brûken om in beskriuwing te generearjen fan it artefakt fan 'e oerdroegen ferzjes fan kanalen en releases, organisearje wy in loop oer de fariabele .WerfVersions в werf.yaml:

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

Omdat de lus sil ferskate artefakten generearje (wy hoopje dat), it is needsaaklik om rekken te hâlden mei de skieding tusken har - de folchoarder --- (Foar mear ynformaasje oer syntaksis fan konfiguraasjetriem, sjoch dokumintaasje). Lykas earder definiearre, by it oproppen fan in sjabloan yn in loop, passe wy de ferzjeparameters, URL en root-kontekst.

Lykas, mar sûnder in loop, neame wy it artefaktsjabloan foar "spesjale gefallen": foar de rootferzje, lykas ek de ferzje fan 'e beoardielingscommit:

{{ 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 }}

Tink derom dat it artefakt foar de beoardieling allinich sil wurde boud as de fariabele is ynsteld .WerfReviewCommit.

De artefakten binne klear - it is tiid om te begjinnen mei ymportearjen!

De definitive ôfbylding, ûntworpen om op Kubernetes te rinnen, is in gewoane NGINX mei in serverkonfiguraasjetriem tafoege nginx.conf en statysk út artefakten. Neist it artefakt fan 'e rootferzje fan' e side, moatte wy de loop op 'e fariabele werhelje .WerfVersions om artefakten fan kanaal- en frijlittingsferzjes te ymportearjen + folgje de artefaktnammeregel dy't wy earder oannaam. Om't elk artefakt ferzjes fan 'e side foar twa talen opslacht, ymportearje wy se yn' e plakken dy't troch de konfiguraasje oanbean wurde.

Beskriuwing fan de finale ôfbylding 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 -}}

De ekstra ôfbylding, dy't, tegearre mei de wichtichste, wurdt lansearre op 'e dev-sirkwy, befettet mar twa ferzjes fan' e side: de ferzje fan 'e beoardieling en de rootferzje fan' e side (d'r binne algemiene aktiva en, as jo it ûnthâlde , release data). Sa sil de ekstra ôfbylding allinich ferskille fan 'e wichtichste yn' e ymportseksje (en, fansels, yn 'e namme):

image: werf-dev
...
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
{{- if .WerfReviewCommit  }}
- artifact: doc-review
  add: /app/_main_site
  to: /app/main_site/review
  before: setup
- artifact: doc-review
  add: /app/_ru_site
  to: /app/ru_site/review
  before: setup
{{- end }}

Lykas hjirboppe oanjûn, sil it artefakt foar de beoardieling allinich wurde generearre as de ynstelde omjouwingsfariabele wurdt útfierd REVIEW_SHA. It soe mooglik wêze om it werf-dev-ôfbylding hielendal net te generearjen as der gjin omjouwingsfariabele is REVIEW_SHA, mar om te skjinmeitsjen troch belied Docker-ôfbyldings yn werf wurken foar it werf-dev-ôfbylding, wy litte it allinich bouwe mei it artefakt fan 'e rootferzje (it is yn elk gefal al boud), om de pipelinestruktuer te ferienfâldigjen.

De gearkomste is klear! Lit ús gean nei CI / CD en wichtige nuânses.

Pipeline yn GitLab CI en funksjes fan dynamyske build

By it útfieren fan de build moatte wy de omjouwingsfariabelen ynstelle dy't brûkt wurde yn werf.yaml. Dit jildt net foar de REVIEW_SHA-fariabele, dy't wy sille ynstelle by it roppen fan pipeline fan 'e GitHub-haak.

Wy sille de nedige eksterne gegevens generearje yn in Bash-skript generate_artifacts, dy't twa GitLab pipeline artefakten sil generearje:

  • file releases.yml mei útjeftegegevens,
  • file common_envs.sh, mei de omjouwingsfariabelen dy't moatte wurde eksportearre.

Triem ynhâld generate_artifacts jo fine yn ús repositories mei foarbylden. It ûntfangen fan de gegevens sels is net it ûnderwerp fan it artikel, mar it bestân common_envs.sh is wichtich foar ús, omdat it wurk fan werf hinget der fan ôf. In foarbyld fan har ynhâld:

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'

Jo kinne de útfier fan sa'n skript brûke, bygelyks mei de Bash-funksje source.

No komt it leuke diel. Om sawol de bou as de ynset fan 'e applikaasje goed te wurkjen, is it nedich om te soargjen dat werf.yaml wie itselde minst binnen ien pipeline. As dizze betingst net foldien wurdt, dan binne de hantekeningen fan de etappes dy't werf berekkent by montage en bygelyks ynset oars. Dit sil liede ta in ynsetflater, om't ... de ôfbylding nedich foar ynset sil ûntbrekke.

Mei oare wurden, as tidens de gearstalling fan it sideôfbylding de ynformaasje oer releases en ferzjes itselde is, en op it momint fan ynset wurdt in nije ferzje frijjûn en de omjouwingsfariabelen hawwe ferskillende wearden, dan sil de ynset mislearje mei in flater: ommers, it artefakt fan 'e nije ferzje is noch net boud.

As generaasje werf.yaml hinget ôf fan eksterne gegevens (bygelyks in list mei aktuele ferzjes, lykas yn ús gefal), dan moatte de gearstalling en wearden fan sokke gegevens binnen de pipeline wurde opnommen. Dit is benammen wichtich as eksterne parameters frij faak feroarje.

Wy sille ûntfange en opnimme eksterne gegevens yn it earste stadium fan 'e pipeline yn GitLab (Prebuild) en stjoer se fierder yn it formulier GitLab CI artefakt. Hjirmei kinne jo pipeline-taken útfiere en opnij starte (bouwe, ynsette, skjinmeitsje) mei deselde konfiguraasje yn werf.yaml.

Ynhâld fan it poadium Prebuild map .gitlab-ci.yml:

Prebuild:
  stage: prebuild
  script:
    - bash ./generate_artifacts 1> common_envs.sh
    - cat ./common_envs.sh
  artifacts:
    paths:
      - releases.yml
      - common_envs.sh
    expire_in: 2 week

Nei't jo de eksterne gegevens yn it artefakt hawwe fêstlein, kinne jo bouwe en ynsette mei de standert GitLab CI-pipelinestadia: Bouwe en ynsette. Wy lansearje de pipeline sels mei haken fan it werf GitHub repository (dat wol sizze, as der feroaringen binne yn it GitHub repository). Gegevens foar har kinne fûn wurde yn 'e GitLab-projekteigenskippen yn' e seksje CI/CD ynstellings -> Pipeline triggers, en meitsje dan de oerienkommende Webhook yn GitHub (Ynstellings -> Webhooks).

De boufaze sil der sa útsjen:

Build:
  stage: build
  script:
    - 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
  except:
    refs:
      - schedules
  dependencies:
    - Prebuild

GitLab sil twa artefakten tafoegje fan it poadium nei it boustadium Prebuild, sadat wy fariabelen eksportearje mei taret ynfiergegevens mei it konstruksje source common_envs.sh. Wy begjinne de boufaze yn alle gefallen, útsein foar it lansearjen fan de pipeline neffens in skema. Neffens it skema sille wy in pipeline útfiere foar skjinmeitsjen - yn dit gefal is d'r gjin need nedich om montage út te fieren.

Yn it ynsetstadium sille wy twa taken beskriuwe - apart foar ynset nei produksje- en dev-sirkels, mei in YAML-sjabloan:

.base_deploy: &base_deploy
  stage: deploy
  script:
    - 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
  dependencies:
    - Prebuild
  except:
    refs:
      - schedules

Deploy to Production:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: prod
  environment:
    name: production
    url: werf.io
  only:
    refs:
      - master
  except:
    variables:
      - $REVIEW_SHA
    refs:
      - schedules

Deploy to Test:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: dev
  environment:
    name: test
    url: werf.test.flant.com
  except:
    refs:
      - schedules
  only:
    variables:
      - $REVIEW_SHA

De taken ferskille yn wêzen allinnich yn it oanjaan fan de klusterkontekst dêr't werf de ynset yn útfiere moat (WERF_KUBE_CONTEXT), en it ynstellen fan de loopomjouwingsfariabelen (environment.name и environment.url), dy't dan wurde brûkt yn Helm-diagramsjabloanen. Wy sille de ynhâld fan 'e sjabloanen net leverje, om't ... der is neat nijsgjirrich dêr foar it ûnderwerp yn kwestje, mar jo kinne fine se yn repositories foar it artikel.

Finale berekkening

Om't werf-ferzjes frij faak útbrocht wurde, wurde nije ôfbyldings faak boud, en sil it Docker Registry konstant groeie. Dêrom is it ymperatyf om automatyske ôfbyldingsreiniging te konfigurearjen basearre op belied. It is hiel maklik om te dwaan.

Om útfiere jo sille nedich:

  • Foegje in skjinmeitsjen stap ta .gitlab-ci.yml;
  • Add periodike útfiering fan in skjinmeitsjen taak;
  • Stel in omjouwingsfariabele op mei in skriuwtagongstoken.

It tafoegjen fan in skjinmeitsjen poadium oan .gitlab-ci.yml:

Cleanup:
  stage: cleanup
  script:
    - 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
    - docker login -u nobody -p ${WERF_IMAGES_CLEANUP_PASSWORD} ${WERF_IMAGES_REPO}
    - werf cleanup --stages-storage :local
  only:
    refs:
      - schedules

Wy hawwe dit al hast allegear in bytsje heger sjoen - allinich om it skjin te meitsjen moatte jo earst ynlogge by it Docker Registry mei in token dat de rjochten hat om ôfbyldings te wiskjen yn 'e Docker Registry (it automatysk útjûn GitLab CI taak token docht net hawwe sokke rjochten). It token moat fan tefoaren yn GitLab oanmakke wurde en de wearde moat oanjûn wurde yn 'e omjouwingsfariabele WERF_IMAGES_CLEANUP_PASSWORD it projekt (CI/CD ynstellings -> Fariabelen).

It tafoegjen fan in skjinmeitsjen taak mei it fereaske skema wurdt dien yn CI/CD ->
Schedules
.

Dat is it: in projekt yn 'e Docker Registry sil net langer konstant groeie fan net brûkte ôfbyldings.

Oan 'e ein fan it praktyske diel, lit my jo herinnerje dat folsleine listings út it artikel binne beskikber yn gean:

resultaat

  1. Wy krigen in logyske gearstallingstruktuer: ien artefakt per ferzje.
  2. De gearstalling is universeel en fereasket gjin hânmjittich feroarings by it útbringen fan nije ferzjes fan werf: de dokumintaasje op de webside wurdt automatysk bywurke.
  3. Twa bylden wurde gearstald foar ferskillende kontoeren.
  4. It wurket fluch, want Caching wurdt safolle mooglik brûkt - as in nije ferzje fan werf wurdt útbrocht of in GitHub-haak wurdt oproppen foar in beoardielingsferplichting, wurdt allinich it korrespondearjende artefakt mei de feroare ferzje opnij boud.
  5. Gjin needsaak om te tinken oer it wiskjen fan net brûkte ôfbyldings: skjinmeitsjen neffens werfbelied sil de Docker Registry op oarder hâlde.

befinings

  • It brûken fan werf lit de gearstalling fluch wurkje fanwegen caching fan sawol de gearstalling sels as caching by it wurkjen mei eksterne repositories.
  • Wurkje mei eksterne Git-repositories elimineert de needsaak om elke kear it heule repository te klonjen of it tsjil opnij útfine mei lestige optimalisaasjelogika. werf brûkt in cache en docht it klonjen mar ien kear, en dan brûkt fetch en allinnich as it nedich is.
  • Mooglikheid om Go-sjabloanen te brûken yn it konfiguraasjetriem foar bouwen werf.yaml kinne jo beskriuwe in gearkomste waans resultaat hinget ôf fan eksterne gegevens.
  • It brûken fan mount yn werf fersnelt de kolleksje fan artefakten signifikant - troch de cache, dy't mienskiplik is foar alle pipelines.
  • werf makket it maklik om skjinmeitsjen te konfigurearjen, wat benammen wichtich is by dynamysk bouwen.

PS

Lês ek op ús blog:

Boarne: www.habr.com

Add a comment