Dynamická sestava a nasazení Docker obrazů s werf na příkladu webu verzované dokumentace

O našem nástroji GitOps jsme už několikrát hovořili, werftentokrát bychom rádi sdíleli zkušenosti se sestavením webové stránky s dokumentací samotného projektu — werf.io (jeho česká verze je — cz.werf.io). Jedná se o obyčejnou statickou stránku, avšak její sestavení je zajímavé tím, že je postaveno s využitím dynamického počtu artefaktů.

Dynamická sestava a nasazení Docker obrazů s werf na příkladu webu verzované dokumentace

Nechceme se zabývat detaily struktury webu jako generování hlavního menu pro všechny verze, stránkami s informacemi o vydáních atd. Místo toho se zaměříme na otázky a aspekty dynamického sestavení a trochu na související procesy CI/CD.

Úvod: jak je web strukturován

Začneme tím, že dokumentace k werf je uložena spolu s jeho kódem. To klade určité nároky na vývoj, které v zásadě přesahují rámec tohoto článku, ale minimálně lze říci, že:

  • Nové funkce werf nesmí vycházet bez aktualizace dokumentace a naopak, jakékoli změny v dokumentaci znamenají vydání nové verze werf;
  • Vývoj projektu je poměrně intenzivní: nové verze mohou vycházet několikrát denně;
  • Jakékoli ruční operace při nasazení webu s novou verzí dokumentace jsou minimálně únavné;
  • V projektu je přijat přístup k semantickému verzování, se 5 kanály stability. Proces vydávání předpokládá postupné procházení verzí kanály v pořadí vzrůstající stability: od alpha po rock-solid;
  • Web má českou verzi, která "žije a vyvíjí se" (tj. jejíž obsah se aktualizuje) paralelně s hlavní (tj. anglickou) verzí.

Abychom skryli před uživateli celou tuto "vnitřní kuchyni" a nabídli jim to, co "jednoduše funguje", vytvořili jsme samostatný nástroj pro instalaci a aktualizaci werf — to je multiwerf. Stačí zadat číslo vydání a kanál stability, který jste ochotni používat, a multiwerf zkontroluje, zda je na kanálu nová verze, a v případě potřeby ji stáhne.

V nabídce výběru verzí na webu jsou dostupné poslední verze werf v každém kanálu. Ve výchozím nastavení se na adrese werf.io/documentation otevře verze nejstabilnějšího kanálu pro poslední vydání — ta je také indexována vyhledávači. Dokumentace pro kanál je dostupná na samostatných adresách (například, werf.io/v1.0-beta/documentation pro beta-verzi 1.0).

Celkově jsou na webu k dispozici následující verze:

  1. kořenová (otevírá se podle výchozího nastavení),
  2. pro každý aktivní kanál aktualizací každé verze (například, werf.io/v1.0-beta).

Pro generaci konkrétní verze webu je obvykle dostatečné provést její kompilaci pomocí Jekyll, spuštěním příslušného příkazu v adresáři /docs repasitoráře werf (jekyll build), předtím se přepněte na Git-tag požadované verze.

Zbývá jen dodat, že:

  • pro sestavení se používá samotný nástroj (werf);
  • CI/CD procesy jsou postaveny na základě GitLab CI;
  • a to vše samozřejmě funguje v Kubernetes.

Úkoly

Nyní formulujme úkoly, které zohledňují celou popsanou specifiku:

  1. Po změně verze werf na jakémkoli kanálu aktualizací by měla být dokumentace na webu automaticky aktualizována..
  2. Pro vývoj je třeba mít možnost občas prohlížet předběžné verze webu..

Překompilaci webu je nutné provádět po změně verze na jakémkoli kanálu z odpovídajících Git-tagů, ale při procesu sestavení obrazu obdržíme následující zvláštnosti:

  • Jelikož se seznam verzí na kanálech mění, je nutné znovu sestavovat pouze dokumentaci pro kanály, kde se změnila verze. Opakovaně sestavovat vše znovu není příliš elegantní.
  • Samotná sada kanálů pro vydání se může měnit. V nějakém okamžiku, například, může na kanálech chybět verze stabilnější než vydání early-access 1.1, ale časem se objeví — neměli bychom přece ručně měnit sestavení?

Dostáváme se k tomu, že sestavení závisí na měnících se externích datech.

Implementace

Volba přístupu

Jako možnost lze spustit každou potřebnou verzi jako samostatný pod v Kubernetes. Tato varianta zahrnuje více objektů v clustru, které porostou s rostoucím počtem stabilních vydání werf. A to na druhé straně vyžaduje složitější údržbu: pro každou verzi vzniká vlastní HTTP server, přičemž s menším zatížením. Samozřejmě, to také vede k větším nákladům na zdroje.

My jsme zvolili cestu kompilace všech potřebných verzí do jednoho obrazu. Sestavená statika všech verzí webu se nachází v kontejneru s NGINX, a provoz na odpovídající Deployment přichází přes NGINX Ingress. Jednoduchá struktura — stateless aplikace — umožňuje snadno škálovat Deployment (v závislosti na zatížení) pomocí samotného Kubernetes.

Konkrétně sbíráme dvě obrazové soubory: jeden pro produkční prostředí, druhý jako doplňkový pro vývojové prostředí. Doplňkový obraz se používá (spouští) pouze na vývojovém prostředí spolu s hlavním a obsahuje verzi webové stránky z revizního commitu, přičemž routování mezi nimi se provádí pomocí zdrojů Ingress.

werf vs git clone a artefakty

Jak již bylo zmíněno, pro vygenerování statiky webu pro konkrétní verzi dokumentace je třeba provést sestavení s přepnutím na příslušný tag repozitáře. Mohli bychom to udělat i tak, že bychom každý čas při sestavení klonovali repozitář a vybírali odpovídající tagy ze seznamu. To je však poměrně náročná operace a navíc vyžaduje napsání složitých instrukcí... Dalším vážným nedostatkem je, že za takového přístupu není možné cokoliv kešovat během sestavení.

Sem nám přichází na pomoc samotný nástroj werf, který implementuje inteligentní kešování a umožňuje používat externí repozitáře. Použití werf pro přidání kódu z repozitáře výrazně urychlí sestavení, protože werf v podstatě jednou provede klonování repozitáře a poté provádí pouze fetch v případě potřeby. Kromě toho, při přidání dat z repozitáře můžeme vybrat pouze potřebné adresáře (v našem případě je to adresář docs), což výrazně sníží objem přidávaných dat.

Jelikož Jekyll je nástroj určený pro kompilaci statiky a není potřebný v konečném obraze, bylo by logické provést kompilaci v artefaktu werf, a do konečného obrazu importovat pouze výsledek kompilace.

Píšeme werf.yaml

Takže jsme se rozhodli, že budeme kompilovat každou verzi v samostatném artefaktu werf. Nicméně nevíme, kolik těchto artefaktů bude při sestavení , proto nemůžeme napsat fixní konfiguraci sestavení (přesněji řečeno, mohli bychom, ale nebylo by to zcela efektivní).werf umožňuje používat

Go šablony ve svém konfiguračním souboru ( ), a to umožňujewerf.yamlgenerovat konfiguraci "za běhu" v závislosti na externích údajích (to, co potřebujeme!). Externími údaji v našem případě je informace o verzích a releasích, na jejichž základě sestavujeme potřebné množství artefaktů a získáváme v důsledku dvě obrazy: werf-doc werf-dev a werf-dev pro spuštění na různých okruzích.

Externí data se předávají pomocí proměnných prostředí. Zde je jejich složení:

  • VERZE — řetězec se seznamem verzí a odpovídajícími aktuálními verzemi werf, ve formě seznamu odděleného mezerami ve formátu %. Příklad: 1.0%v1.0.4-beta.20
  • KANÁLY — řetězec se seznamem kanálů a odpovídajícími aktuálními verzemi werf, ve formě seznamu odděleného mezerami ve formátu %. Příklad: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERZE — verze relace werf, která se zobrazuje jako výchozí na webu (není vždy nutné zobrazovat dokumentaci k nejvyššímu číslu relace). Příklad: v1.0.4-beta.20
  • REVIEW_SHA — hash review-commitu, ze kterého je třeba sestavit verzi pro testovací okruh.

Tyto proměnné budou naplňovány v pipeline GitLab CI, jak přesně — je popsáno níže.

Jako první, pro usnadnění, určíme v werf.yaml proměnné Go šablon, přiřadíme jim hodnoty z proměnných prostředí:

{{ $_ := set . "WerfVersions" (cat (env "KANÁLY") (env "VERZE") | splitList " ") }}
{{ $Root := . }}
{{ $_ := set . "WerfRootVerze" (env "ROOT_VERZE") }}
{{ $_ := set . "WerfReviewCommit" (env "REVIEW_SHA") }}

Popis artefaktu pro kompilaci statiky verze webu je v podstatě stejný pro všechny potřebné případy (včetně generování kořenové verze, jakož i verze pro dev-okruh). Proto ho vyčleníme do samostatného bloku pomocí funkce definovat — pro následné opětovné použití pomocí include. Šabloně budeme předávat následující argumenty:

  • Verze — generovanou verzi (název tagu);
  • Channel — název kanálu aktualizací, pro který se artefakt generuje;
  • Commit — hash commitu, pokud je artefakt generován pro review-commit;
  • kontext.

Popis šablony artefaktu

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

Název artefaktu musí být jedinečný. Můžeme toho dosáhnout například přidáním názvu kanálu (hodnota proměnné .Channel) jako přípony názvu artefaktu: artifact: doc-{{ .Channel }}. Ale je třeba chápat, že při importu z artefaktů bude nezbytné odkazovat na stejná jména.

Při popisu artefaktu se používá taková funkce werf jako montáž. Montáž s uvedením pracovní složky build_dir umožňuje uchovávat cache Jekyll mezi spuštěními pipeline, což výrazně urychluje opětovnou sestavení..

Také jste si možná všimli použití souboru releases.yml — to je YAML soubor s daty o vydáních, který se dotazuje na github.com (artefakt získaný při provádění pipeline). Je potřeba při kompilaci webové stránky, ale v kontextu článku nás zajímá tím, že od jeho stavu závisí opětovná sestavení pouze jednoho artefaktu — artefaktu webu hlavní verze (v dalších artefaktech není potřeba).

To je realizováno pomocí podmínkového operátoru if Go šablon a konstrukce {{ $Root.Files.Get "releases.yml" | sha256sum }} ve fázi etapy. Funguje to takto: při sestavení artefaktu pro kořenovou verzi (proměnná .Channel je root) hash souboru releases.yml ovlivňuje podpis celé fáze, protože je součástí názvu úkolu Ansible (parametr name). Takže pokud dojde ke změně obsahu, soubory releases.yml odpovídající artefakt bude znovu sestaven.

Všimněte si také práce s externím repozitářem. Do obrazu artefaktu z repozitáře werf, se přidá pouze adresář /docs, přičemž v závislosti na předaných parametrech se přidají data potřebného tagu nebo review-commitu.

Abychom použili šablonu artefaktu pro generování popisu artefaktu předaných verzí kanálů a vydání, uspořádáme cyklus podle proměnné .WerfVersions v werf.yaml:

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

Protože cyklus vygeneruje několik artefaktů (na to doufáme), je nutné vzít v úvahu oddělovač mezi nimi — sekvenci --- (podrobnosti o syntaxi konfiguračního souboru viz dokumentaci). Jak jsme se dohodli dříve, při volání šablony v cyklu předáváme parametry verze, URL a kořenový kontext.

Podobně, ale již bez cyklu, voláme šablonu artefaktu pro "zvláštní případy": pro kořenovou verzi a také verzi z review-commitu:

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

Všimněte si, že artefakt pro review-commit bude sestaven pouze v případě, že je nastavena proměnná .WerfReviewCommit.

Artefakty jsou připravené — je čas zabývat se importem!

Výsledný obraz určený pro spuštění v Kubernetes je běžný NGINX, do kterého byl přidán konfigurační soubor serveru nginx.conf a statika z artefaktů. Kromě artefaktu kořenové verze webu musíme zopakovat cyklus podle proměnné .WerfVersions pro import artefaktů verzí kanálů a vydání + dodržet pravidlo pojmenování artefaktů, které jsme přijali dříve. Vzhledem k tomu, že každý artefakt uchovává verze webu pro dva jazyky, importujeme je na místa uvedená v konfiguraci.

Popis konečného obrazu 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 -}}

Další obraz, který se spouští společně se základním na vývojovém konturu, obsahuje pouze dvě verze webu: verzi z review-commitu a kořenovou verzi webu (tam jsou společné assety a, pokud si pamatujete, údaje o releasech). Tímto způsobem se liší dodatečný obraz od hlavního pouze sekcí importu (no a samozřejmě názvem):

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

Jak již bylo zmíněno výše, artefakt pro review-commit bude generován pouze při spuštění nastavené proměnné prostředí REVIEW_SHA. Mohli bychom vůbec negenerovat obraz werf-dev, pokud není proměnná prostředí REVIEW_SHA, ale aby čištění podle politik Docker-obrazů v werf pracovalo pro obraz werf-dev, necháme ho sestavovat pouze s artefaktem kořenové verze (stejně už je sestaven), pro zjednodušení struktury pipeline.

Sestavení je hotovo! Přecházíme na CI/CD a důležité nuance.

Pipeline v GitLab CI a vlastnosti dynamického sestavení

Při spouštění sestavení je nutné nastavit proměnné prostředí, které se používají v werf.yaml. To se netýká proměnné REVIEW_SHA, kterou nastavíme při vyvolání pipeline z GitHub webhooku.

Tvorbu potřebných externích dat přesuneme do Bash-skriptu generate_artifacts, který bude generovat dva artefakty pipeline GitLab:

  • soubor releases.yml s údaji o releasech,
  • soubor common_envs.sh, obsahující proměnné prostředí pro export.

Obsah souboru generate_artifacts najdete v našem repozitáři s příklady. Získání dat není předmětem článku, ale soubor common_envs.sh nás zajímá, protože na něm závisí fungování werf. Příklad jeho obsahu:

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'

Výstup takového skriptu je možné použít například prostřednictvím funkce Bash. source.

A teď to nejzajímavější. Aby jak sestavení, tak nasazení aplikace fungovalo správně, je nutné zajistit, aby werf.yaml byl bylo stejné alespoň v rámci jednoho pipeline. Pokud tato podmínka nebude splněna, budou podpisy fází, které werf vypočítá při sestavení a například nasazení, odlišné. To povede k chybě nasazení, protože požadovaný obraz pro nasazení bude chybět.

Jinými slovy, pokud během sestavení obrazu webu budou informace o relezech a verzích jedny, a v okamžiku nasazení se objeví nová verze a proměnné prostředí budou mít jiné hodnoty, pak nasazení skončí s chybou: artefakt nové verze ještě nebyl sestaven.

Pokud generace werf.yaml závisí na vnějších datech (například seznamu aktuálních verzí, jak je tomu v našem případě), potom složení a hodnoty těchto dat musí být zafixovány v rámci pipeline. To je obzvlášť důležité, pokud se vnější parametry poměrně často mění.

Budeme získávat a fixovat vnější data v první fázi pipeline v GitLab (Prebuild) a předávat je dále jako artefakt GitLab CI. To umožní spouštět a restartovat úkoly pipeline (sestavení, nasazení, úklid) se stejnou konfigurací v werf.yaml.

Obsah fáze Prebuild soubory .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

Po fixaci vnějších dat v artefaktu je možné provádět sestavení a nasazení pomocí standardních fází pipeline GitLab CI: Build a Deploy. Samotnou pipeline spouštíme pomocí webhooků z GitHub repozitáře werf (t.j. při změnách v repozitáři na GitHubu). Data pro ně lze vzít v vlastnostech projektu GitLab v sekci CI / CD Settings -> Pipeline triggers, a poté vytvoříme v GitHubu odpovídající Webhook (Settings -> Webhooks).

Fáze sestavení bude vypadat následovně:

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 přidá do fáze sestavení dva artefakty z fáze Prebuild, takže exportujeme proměnné s připravenými vstupními daty pomocí konstrukce source common_envs.sh. Spouštíme fázi sestavení ve všech případech kromě spuštění pipeline podle plánu. Podle plánu se spustí pipeline pro úklid — v tomto případě není potřeba provádět sestavení.

Ve fázi nasazení popíšeme dva úkoly — zvlášť pro nasazení na production a dev prostředí, s použitím YAML šablony:

.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

Nasazení do produkce:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: prod
  environment:
    name: production
    url: werf.io
  only:
    refs:
      - master
  except:
    variables:
      - $REVIEW_SHA
    refs:
      - schedules

Nasazení na test:
  <<: *base_deploy
  variables:
    WERF_KUBE_CONTEXT: dev
  environment:
    name: test
    url: werf.test.flant.com
  except:
    refs:
      - schedules
  only:
    variables:
      - $REVIEW_SHA

Úkoly se v podstatě liší pouze uvedením kontextu clusteru, do kterého by měl werf provádět nasazení (WERF_KUBE_CONTEXT), a nastavením proměnných prostředí kontextu (environment.name a environment.url), které se pak používají ve šablonách Helm chartu. Obsah šablon zde uvádět nebudeme, protože tam není nic zajímavého pro diskutované téma, ale můžete je najít v repozitáři článku.

Závěrečná úprava

Protože verze werf vycházejí poměrně často, často se budou sestavovat nové obrazy a Docker Registry bude neustále růst. Je proto nutné nastavit automatické čištění obrazů podle politik. Udělat to je velmi jednoduché.

Pro implementaci bude potřeba:

  • Přidat fázi úklidu do .gitlab-ci.yml;
  • Přidat periodicky vykonávaný úkol úklidu;
  • Nastavit proměnnou prostředí s přístupovým tokenem pro zápis.

Přidáváme fázi úklidu do .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

Téměř všechno jsme již viděli výše — pouze pro úklid je potřeba se nejprve autorizovat v Docker Registry s tokenem, který má práva na odstranění obrazů v Docker Registry (automatically vydaný token pro úkoly GitLab CI nemá tato práva). Token je třeba předem založit v GitLab a jeho hodnotu uvést v proměnné prostředí WERF_IMAGES_CLEANUP_PASSWORD projektem (CI/CD Settings -> Variables).

Přidání úkolu úklidu s potřebným plánem se provádí v CI/CD ->
Schedules
.

Vše: projekt v Docker Registry již nebude neustále růst díky nepoužívaným obrazům.

Na závěr praktické části připomínám, že kompletní výpisy z článku jsou k dispozici na Git:

Výsledek

  1. Dostali jsme logickou strukturu sestavení: jeden artefakt na jednu verzi.
  2. Sestavení je univerzální a nevyžaduje ruční změny při vydání nových verzí werf: dokumentace na webu se automaticky aktualizuje.
  3. Sestavují se dva obrazy pro různé okruhy.
  4. Pracuje rychle, protože maximálně využívá kešování — při vydání nové verze werf nebo vyvolání GitHub webhooku pro review commit se provádí znovusestavení pouze odpovídajícího artefaktu se změněnou verzí.
  5. Není třeba přemýšlet o odstraňování nepoužívaných obrazů: čištění podle politik werf udržuje pořádek v Docker Registry.

Závěry

  • Použití werf umožňuje, aby sestavení fungovalo rychle díky kešování jak samotného sestavení, tak kešování při práci s externími repozitáři.
  • Práce s externími Git repozitáři zbavuje potřeby klonovat repozitář každýkrát kompletně nebo vymýšlet kolo s komplikovanou logikou optimalizace. werf využívá keš a klonuje pouze jednou, pak dále používá fetch a pouze podle potřeby.
  • Možnost využití Go šablon v konfiguračním souboru sestavení werf.yaml umožňuje popsat sestavení, jehož výsledek závisí na externích datech.
  • Použití montáží v werf výrazně zrychluje sběr artefaktů — díky keši, která je společná pro všechny pipeline.
  • werf umožňuje snadno nastavit čištění, což je obzvláště důležité při dynamickém sestavení.

P.S.

Přečtěte si také náš blog:

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster