Dinamika muntado kaj deplojo de Docker-bildoj kun werf uzante la ekzemplon de versionita dokumenta retejo

Ni jam parolis pri nia GitOps-ilo pli ol unufoje. werf, kaj ĉi-foje ni ŝatus kunhavigi nian sperton pri muntado de la retejo kun la dokumentado de la projekto mem - werf.io (ĝia rusa versio estas eo.werf.io). Ĉi tio estas ordinara senmova retejo, sed ĝia kunigo estas interesa ĉar ĝi estas konstruita uzante dinamikan nombron da artefaktoj.

Dinamika muntado kaj deplojo de Docker-bildoj kun werf uzante la ekzemplon de versionita dokumenta retejo

Eniru la nuancojn de la retejo-strukturo: generado de komuna menuo por ĉiuj versioj, paĝoj kun informoj pri eldonoj, ktp. - ni ne faros. Anstataŭe, ni koncentriĝu pri la aferoj kaj trajtoj de dinamika asembleo kaj iomete pri la akompanaj CI/KD-procezoj.

Enkonduko: kiel funkcias la retejo

Komence, werf-dokumentado estas konservita kune kun ĝia kodo. Tio trudas certajn evolupostulojn, kiuj estas ĝenerale ekster la amplekso de ĉi tiu artikolo, sed minimume oni povas diri tion:

  • Novaj werf-funkcioj ne devus esti liberigitaj sen ĝisdatigo de la dokumentaro kaj, male, ajnaj ŝanĝoj en la dokumentaro implicas la liberigon de nova versio de werf;
  • La projekto havas sufiĉe intensan evoluon: novaj versioj povas esti publikigitaj plurfoje tage;
  • Ĉiuj manaj operacioj por deploji retejon kun nova versio de dokumentaro estas almenaŭ tedaj;
  • La projekto adoptas semantikan aliron versionado, kun 5 stabileckanaloj. La eldonprocezo implikas sinsekvan trairejon de versioj tra kanaloj en ordo de kreskanta stabileco: de alfao ĝis rok-solida;
  • La retejo havas ruslingvan version, kiu "vivas kaj disvolvas" (t.e., kies enhavo estas ĝisdatigita) paralele kun la ĉefa (t.e., anglalingva) versio.

Por kaŝi ĉion ĉi tiun "internan kuirejon" de la uzanto, proponante al li ion, kio "nur funkcias", ni faris aparta ilo pri instalado kaj ĝisdatigo de werf Estas multiwerf. Vi nur bezonas specifi la eldonnumeron kaj la stabileckanalon, kiujn vi pretas uzi, kaj multiwerf kontrolos ĉu ekzistas nova versio sur la kanalo kaj elŝutos ĝin se necese.

En la versio-elekta menuo en la retejo, la plej novaj versioj de werf estas haveblaj en ĉiu kanalo. Defaŭlte, laŭ adreso werf.io/dokumentado malfermiĝas la versio de la plej stabila kanalo por la plej nova eldono - ĝi ankaŭ estas indeksita de serĉiloj. Dokumentaro por la kanalo haveblas ĉe apartaj adresoj (ekzemple, werf.io/v1.0-beta/documentation por beta-eldono 1.0).

Entute, la retejo havas disponeblajn jenajn versiojn:

  1. radiko (malfermiĝas defaŭlte),
  2. por ĉiu aktiva ĝisdatiga kanalo de ĉiu eldono (ekzemple, werf.io/v1.0-beta).

Por generi specifan version de retejo, ĝenerale, sufiĉas kompili ĝin uzante Jekyllper kurado en la dosierujo /docs werf-deponejo responda komando (jekyll build), post ŝanĝi al la Git-etikedo de la bezonata versio.

Restas nur aldoni ke:

  • la utileco mem (werf) estas uzata por kunigo;
  • CI/KD-procezoj estas konstruitaj surbaze de GitLab CI;
  • kaj ĉio ĉi, kompreneble, funkcias en Kubernetes.

taskoj

Nun ni formulu taskojn, kiuj konsideras ĉiujn priskribitajn specifaĵojn:

  1. Post ŝanĝi la werf-version en iu ajn ĝisdatiga kanalo dokumentaro en la retejo devus esti aŭtomate ĝisdatigita.
  2. Por evoluo vi devas povi foje vidi antaŭrigardajn versiojn de la retejo.

La retejo devas esti rekompilita post ŝanĝado de la versio en iu ajn kanalo de la respondaj Git-etikedoj, sed en la procezo de konstruado de la bildo ni ricevos la jenajn funkciojn:

  • Ĉar la listo de versioj sur kanaloj ŝanĝiĝas, necesas nur rekonstrui la dokumentadon por kanaloj kie la versio ŝanĝiĝis. Post ĉio, rekonstrui ĉion denove ne estas tre agrable.
  • La aro de kanaloj por eldonoj povas ŝanĝiĝi. Iam en la tempo, ekzemple, eble ne ekzistas versio sur la kanaloj pli stabila ol la frua aliro 1.1-eldono, sed kun la tempo ili aperos - en ĉi tiu kazo, ĉu vi ne devus ŝanĝi la aron permane?

Ĝi rezultas tion asembleo dependas de ŝanĝado de eksteraj datumoj.

Реализация

Elektante Aliron

Alternative, vi povas ruli ĉiun bezonatan version kiel aparta pod en Kubernetes. Ĉi tiu opcio implicas pli grandan nombron da objektoj en la areto, kiu kreskos kun la pliiĝo en la nombro da stabilaj werf-eldonoj. Kaj ĉi tio, siavice, implicas pli kompleksan prizorgadon: ĉiu versio havas sian propran HTTP-servilon, kaj kun malgranda ŝarĝo. Kompreneble, ĉi tio ankaŭ implicas pli grandajn rimedkostojn.

Ni prenis la saman vojon kunvenante ĉiujn necesajn versiojn en unu bildo. La kompilita statiko de ĉiuj versioj de la retejo troviĝas en ujo kun NGINX, kaj trafiko al la responda Deplojo venas per NGINX Ingress. Simpla strukturo - sennacia aplikaĵo - ebligas al vi facile skali Deplojon (depende de la ŝarĝo) uzante Kubernetes mem.

Por esti pli precizaj, ni kolektas du bildojn: unu por la produktadcirkvito, la dua estas plia por la dev-cirkvito. La aldona bildo estas uzata (lanĉita) nur en la dev-cirkvito kune kun la ĉefa kaj enhavas la version de la retejo de la revizio-komisio, kaj vojigo inter ili estas farita per Ingress-resursoj.

werf vs git-klono kaj artefaktoj

Kiel jam menciite, por generi retejajn statikojn por specifa versio de la dokumentaro, vi devas konstrui ŝanĝante al la taŭga deponeja etikedo. Vi ankaŭ povus fari tion per klonado de la deponejo ĉiufoje kiam vi konstruas, elektante la taŭgajn etikedojn el listo. Tamen, ĉi tio estas sufiĉe rimeda operacio kaj, krome, postulas verki ne-trivialajn instrukciojn... Alia grava malavantaĝo estas, ke kun ĉi tiu aliro ne estas maniero konservi ion dum kunigo.

Ĉi tie la werf-utilo mem venas al nia helpo, efektivigante inteligenta kaŝmemoro kaj permesante al vi uzi eksteraj deponejoj. Uzi werf por aldoni kodon el la deponejo signife plirapidigos la konstruon, ĉar werf esence klonas la deponejon unufoje kaj poste ekzekutas nur fetch se necese. Krome, aldonante datumojn el la deponejo, ni povas elekti nur la necesajn dosierujojn (en nia kazo ĉi tio estas la dosierujo docs), kiu signife reduktos la kvanton de aldonitaj datumoj.

Ĉar Jekyll estas ilo dizajnita por kompili senmovajn datumojn kaj ne estas bezonata en la fina bildo, estus logike kompili en werf artefakto, kaj en la finan bildon importu nur la kompilan rezulton.

Ni skribas werf.yaml

Do, ni decidis, ke ni kompilos ĉiun version en aparta werf-artefakto. Tamen ni ni ne scias kiom da ĉi tiuj artefaktoj estos dum kunigo, do ni ne povas skribi fiksan konstruan agordon (strikte, ni ankoraŭ povas, sed ĝi ne estos tute efika).

werf permesas vin uzi Iru ŝablonojn en via agorda dosiero (werf.yaml), kaj ĉi tio ebligas generi agordon sur la muŝo depende de eksteraj datumoj (kion vi bezonas!). Eksteraj datumoj en nia kazo estas informoj pri versioj kaj eldonoj, surbaze de kiuj ni kolektas la bezonatan nombron da artefaktoj kaj kiel rezulto ni akiras du bildojn: werf-doc и werf-dev kuri sur malsamaj cirkvitoj.

Eksteraj datumoj estas trapasitaj tra mediovariabloj. Jen ilia komponado:

  • RELEASES - linio kun listo de eldonoj kaj la responda aktuala versio de werf, en formo de spac-disigita listo de valoroj en la formato <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>. Ekzemplo: 1.0%v1.0.4-beta.20
  • CHANNELS - linio kun listo de kanaloj kaj la responda aktuala versio de werf, en formo de spac-disigita listo de valoroj en la formato <КАНАЛ>%<НОМЕР_ВЕРСИИ>. Ekzemplo: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — werf-eldonversio montrenda defaŭlte en la retejo (ne ĉiam necesas montri dokumentadon per la plej alta eldonnumero). Ekzemplo: v1.0.4-beta.20
  • REVIEW_SHA — hash de la revizio de kiu vi devas konstrui la version por la prova buklo.

Ĉi tiuj variabloj estos plenigitaj en la GitLab CI-dukto, kaj kiel ĝuste estas skribita sube.

Antaŭ ĉio, por komforto, ni difinas en werf.yaml Iru ŝablonajn variablojn, asignante al ili valorojn de mediaj variabloj:

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

La priskribo de la artefakto por kompili la statikan version de la retejo estas ĝenerale la sama por ĉiuj kazoj, kiujn ni bezonas (inkluzive de generi la radikan version, same kiel la version por la dev-cirkvito). Tial ni movos ĝin en apartan blokon uzante la funkcion define - por posta reuzo uzado include. Ni transdonos la sekvajn argumentojn al la ŝablono:

  • Version — generita versio (etikedo nomo);
  • Channel — la nomo de la ĝisdatiga kanalo por kiu la artefakto estas generita;
  • Commit — commit hash, se la artefakto estas generita por revizia komito;
  • kunteksto.

Artefakto Ŝablona Priskribo

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

La nomo de artefakto devas esti unika. Ni povas atingi ĉi tion, ekzemple, aldonante la kanalnomon (la valoro de la variablo .Channel) kiel sufikso al la nomo de la artefakto: artifact: doc-{{ .Channel }}. Sed vi devas kompreni, ke dum importado de artefaktoj, vi devos rilati al la samaj nomoj.

Dum priskribado de artefakto, la sekva werf-trajto estas uzata: muntado. Muntado indikante la servan dosierujon build_dir permesas vin konservi la kaŝmemoron Jekyll inter duktokuroj, kio signife akcelas remuntadon.

Vi eble ankaŭ rimarkis la uzon de la dosiero releases.yml estas YAML-dosiero kun eldondatumoj petitaj de github.com (artefakto akirita dum efektivigado de dukto). Ĝi estas bezonata dum kompilado de la retejo, sed en la kunteksto de la artikolo ĝi estas interesa por ni ĉar ĝi dependas de ĝia stato remuntado de nur unu artefakto — artefakto de la radika versio de la retejo (ĝi ne estas bezonata en aliaj artefaktoj).

Ĉi tio estas efektivigita uzante la kondiĉan deklaron if Iru ŝablonojn kaj dezajnojn {{ $Root.Files.Get "releases.yml" | sha256sum }} en scenejo etapoj. Ĝi funkcias jene: dum konstruado de artefakto por la radika versio (variablo .Channel egalas root) dosiero hash releases.yml influas la subskribon de la tuta stadio, ĉar ĝi estas parto de la nomo de la Ansible-tasko (parametro name). Tiel, kiam ŝanĝiĝas enhavo dosiero releases.yml la responda artefakto estos rekunmetita.

Bonvolu ankaŭ atenti labori kun ekstera deponejo. En la bildo de artefakto de werf-deponejo, nur la dosierujo estas aldonita /docs, kaj depende de la preterpasitaj parametroj, la datumoj de la bezonata etikedo aŭ revizio estas tuj aldonitaj.

Por uzi la artefaktan ŝablonon por generi priskribon de la artefakto de la translokigitaj versioj de kanaloj kaj eldonoj, ni organizas buklon sur la variablo .WerfVersions в werf.yaml:

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

Ĉar la buklo generos plurajn artefaktojn (ni esperas), necesas konsideri la apartigilon inter ili - la sekvenco --- (Por pliaj informoj pri agorda dosiera sintakso, vidu dokumentado). Kiel difinite antaŭe, kiam oni vokas ŝablonon en buklo, ni pasas la versio-parametrojn, URL kaj radikan kuntekston.

Simile, sed sen buklo, ni nomas la artefaktan ŝablonon por "specialaj kazoj": por la radika versio, same kiel la versio de la revizia komito:

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

Bonvolu noti, ke la artefakto por la revizia komito estos konstruita nur se la variablo estas agordita .WerfReviewCommit.

La artefaktoj estas pretaj - estas tempo komenci importi!

La fina bildo, dizajnita por funkcii sur Kubernetes, estas regula NGINX kun servila agorda dosiero aldonita nginx.conf kaj senmova de artefaktoj. Krom la artefakto de la radika versio de la retejo, ni devas ripeti la buklon sur la variablo .WerfVersions por importi artefaktojn de kanalo kaj liberigi versiojn + sekvu la regulon pri nomado de artefaktoj, kiun ni adoptis pli frue. Ĉar ĉiu artefakto konservas versiojn de la retejo por du lingvoj, ni importas ilin en la lokojn provizitajn de la agordo.

Priskribo de la fina bildo 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 -}}

La aldona bildo, kiu, kune kun la ĉefa, estas lanĉita en la dev-cirkvito, enhavas nur du versiojn de la retejo: la versio de la revizia komito kaj la radika versio de la retejo (estas ĝeneralaj valoraĵoj kaj, se vi memoras , liberigas datumojn). Tiel, la aldona bildo diferencas de la ĉefa nur en la importa sekcio (kaj, kompreneble, en la nomo):

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

Kiel notite supre, la artefakto por la revizia komito estos generita nur kiam la fiksita mediovariablo estas rulita REVIEW_SHA. Eblus tute ne generi la werf-dev-bildon se ne ekzistas mediovariablo REVIEW_SHA, sed por purigado per politikoj Docker-bildoj en werf funkciis por la werf-dev-bildo, ni lasos ĝin konstrui nur kun la radika versio artefakto (ĝi jam estas konstruita ĉiuokaze), por simpligi la duktostrukturon.

La asembleo estas preta! Ni transiru al CI/KD kaj gravaj nuancoj.

Dukto en GitLab CI kaj trajtoj de dinamika konstruo

Dum rulado de la konstruo ni devas agordi la medio-variablojn uzatajn en werf.yaml. Ĉi tio ne validas por la variablo REVIEW_SHA, kiun ni starigos dum voko de dukto de la GitHub-hoko.

Ni generos la necesajn eksterajn datumojn en Bash-skripto generate_artifacts, kiu generos du GitLab-duktoartefaktojn:

  • файл releases.yml kun eldondatenoj,
  • файл common_envs.sh, enhavante la mediovariablojn eksportotajn.

Dosiera enhavo generate_artifacts vi trovos en nia deponejoj kun ekzemploj. Ricevo de la datumoj mem ne estas la temo de la artikolo, sed la dosiero common_envs.sh estas grava por ni, ĉar la laboro de werf dependas de ĝi. Ekzemplo de ĝia enhavo:

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'

Vi povas uzi la eligon de tia skripto, ekzemple, uzante la funkcion Bash source.

Nun venas la amuza parto. Por ke ambaŭ la konstruado kaj deplojo de la aplikaĵo funkciu ĝuste, necesas certigi tion werf.yaml estis la sama malplej ene de unu dukto. Se ĉi tiu kondiĉo ne estas plenumita, tiam la subskriboj de la stadioj, kiujn werf kalkulas dum kunigo kaj, ekzemple, deplojo, estos malsamaj. Ĉi tio kondukos al deploja eraro, ĉar... la bildo bezonata por deplojo mankos.

Alivorte, se dum la muntado de la retejo-bildo la informoj pri eldonoj kaj versioj estas la sama, kaj en la momento de deplojo nova versio estas publikigita kaj la mediaj variabloj havas malsamajn valorojn, tiam la deplojo malsukcesos kun eraro: post ĉio, la artefakto de la nova versio ankoraŭ ne estis konstruita.

Se generacio werf.yaml dependas de eksteraj datumoj (ekzemple listo de aktualaj versioj, kiel en nia kazo), tiam la komponado kaj valoroj de tiaj datumoj devas esti registritaj ene de la dukto. Ĉi tio estas precipe grava se eksteraj parametroj sufiĉe ofte ŝanĝiĝas.

Ni volos ricevi kaj registri eksterajn datumojn ĉe la unua etapo de la dukto en GitLab (Antaŭkonstruo) kaj transdoni ilin plu en la formo GitLab CI artefakto. Ĉi tio permesos al vi ruli kaj rekomenci duktolaborojn (konstrui, deploji, purigi) kun la sama agordo en werf.yaml.

Enhavo de la scenejo Antaŭkonstruo dosiero .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

Kaptinte la eksterajn datumojn en la artefakto, vi povas konstrui kaj disfaldi uzante la normajn GitLab CI-duktostadiojn: Konstruu kaj Deploji. Ni lanĉas la dukton mem uzante hokojn de la GitHub werf-deponejo (t.e., kiam estas ŝanĝoj en la deponejo sur GitHub). Datumoj por ili troveblas en la proprietoj de la projekto GitLab en la sekcio CI/CD-Agordoj -> Pipeline-eksiloj, kaj poste kreu la respondan Webhook en GitHub (Agordoj -> Webhooks).

La konstrustadio aspektos jene:

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 aldonos du artefaktojn de la scenejo ĝis la konstrustadio Antaŭkonstruo, do ni eksportas variablojn kun pretaj enigdatenoj uzante la konstruaĵon source common_envs.sh. Ni komencas la konstruan etapon en ĉiuj kazoj, krom lanĉado de la dukto laŭ horaro. Laŭ la horaro, ni funkcios dukto por purigado - en ĉi tiu kazo ne necesas plenumi muntadon.

En la deplojfazo, ni priskribos du taskojn - aparte por deplojo al produktado kaj dev-cirkvitoj, uzante YAML-ŝablonon:

.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

La taskoj esence malsamas nur en indikado de la aretkunteksto en kiu werf devus plenumi la deplojon (WERF_KUBE_CONTEXT), kaj fiksante la cirklajn mediovariablojn (environment.name и environment.url), kiuj tiam estas uzataj en Helm-diagramŝablonoj. Ni ne provizos la enhavon de la ŝablonoj, ĉar... estas nenio interesa tie por la koncerna temo, sed vi povas trovi ilin en deponejoj por la artikolo.

fina tuŝo

Ĉar werf-versioj estas publikigitaj sufiĉe ofte, novaj bildoj estos konstruitaj ofte, kaj la Docker-Registro konstante kreskos. Tial, estas nepre agordi aŭtomatan bildpurigon bazitan sur politikoj. Ĝi estas tre facila por fari.

Por efektivigi vi bezonos:

  • Aldonu purigan paŝon al .gitlab-ci.yml;
  • Aldonu periodan plenumon de purigado;
  • Agordu mediovariablon kun skriba alirĵetono.

Aldonante purigan stadion al .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

Ni jam vidis preskaŭ ĉion ĉi iom pli alte - nur por purigi ĝin, vi devas unue ensaluti en la Docker-Registro per ĵetono, kiu havas la rajtojn forigi bildojn en la Docker-Registry (la aŭtomate eldonita GitLab CI-tasko-ĵetono ne faras havas tiajn rajtojn). La signo devas esti kreita en GitLab anticipe kaj ĝia valoro devas esti specifita en la mediovariablo WERF_IMAGES_CLEANUP_PASSWORD la projekto (CI/CD-Agordoj -> Variabloj).

Aldono de purigadtasko kun la bezonata horaro estas farita en CI/KD ->
Horaroj
.

Jen: projekto en la Docker Registry ne plu konstante kreskos el neuzataj bildoj.

Je la fino de la praktika parto, mi memorigu al vi, ke plenaj listoj de la artikolo disponeblas en Git:

rezulto

  1. Ni ricevis logikan kunigstrukturon: unu artefakto per versio.
  2. La asembleo estas universala kaj ne postulas manajn ŝanĝojn kiam novaj versioj de werf estas publikigitaj: la dokumentaro en la retejo estas aŭtomate ĝisdatigita.
  3. Du bildoj estas kunvenitaj por malsamaj konturoj.
  4. Ĝi funkcias rapide, ĉar Kaŝmemoro estas uzata kiel eble plej multe - kiam nova versio de werf estas publikigita aŭ GitHub-hoko estas postulata por revizio, nur la responda artefakto kun la ŝanĝita versio estas rekonstruita.
  5. Ne necesas pensi pri forigo de neuzataj bildoj: purigado laŭ werf-politikoj konservos la Docker-Registron en ordo.

trovoj

  • Uzado de werf permesas al la asembleo funkcii rapide pro kaŝmemoro de kaj la asembleo mem kaj kaŝmemoro kiam oni laboras kun eksteraj deponejoj.
  • Labori kun eksteraj Git-deponejoj forigas la bezonon kloni la tutan deponejon ĉiufoje aŭ reinventi la radon kun malfacila optimumiga logiko. werf uzas kaŝmemoron kaj faras la klonadon nur unufoje, kaj poste uzas fetch kaj nur kiam necese.
  • Kapablo uzi Go-ŝablonojn en la konstrua agorda dosiero werf.yaml permesas vin priskribi aron, kies rezulto dependas de eksteraj datumoj.
  • Uzi monton en werf signife plirapidigas la kolekton de artefaktoj - pro la kaŝmemoro, kiu estas komuna al ĉiuj duktoj.
  • werf faciligas agordi purigadon, kiu estas precipe grava dum konstruado dinamike.

PS

Legu ankaŭ en nia blogo:

fonto: www.habr.com

Aldoni komenton