Dynamisk samling og udrulning af Docker-billeder med werf ved hjælp af eksemplet på et versionsdokumentationssted

Vi har allerede talt om vores GitOps-værktøj mere end én gang. werf, og denne gang vil vi gerne dele vores erfaring med at samle sitet med dokumentationen af ​​selve projektet - werf.io (den russiske version er en.werf.io). Dette er et almindeligt statisk sted, men dets samling er interessant, fordi det er bygget ved hjælp af et dynamisk antal artefakter.

Dynamisk samling og udrulning af Docker-billeder med werf ved hjælp af eksemplet på et versionsdokumentationssted

Gå ind i nuancerne i webstedets struktur: generering af en fælles menu for alle versioner, sider med information om udgivelser osv. - vi vil ikke. Lad os i stedet fokusere på problemerne og funktionerne ved dynamisk montering og lidt på de medfølgende CI/CD-processer.

Introduktion: hvordan webstedet fungerer

Til at begynde med gemmes werf-dokumentation sammen med dens kode. Dette stiller visse udviklingskrav, som generelt ligger uden for denne artikels rammer, men som minimum kan det siges, at:

  • Nye werf-funktioner bør ikke frigives uden at opdatere dokumentationen, og omvendt indebærer ændringer i dokumentationen frigivelsen af ​​en ny version af werf;
  • Projektet har en ret intensiv udvikling: nye versioner kan frigives flere gange om dagen;
  • Enhver manuell handling for at implementere et websted med en ny version af dokumentation er i det mindste kedelige;
  • Projektet har en semantisk tilgang versionering, med 5 stabilitetskanaler. Frigivelsesprocessen involverer sekventiel passage af versioner gennem kanaler i rækkefølge for at øge stabiliteten: fra alfa til stensikkert;
  • Siden har en russisksproget version, som "lever og udvikler sig" (dvs. hvis indhold opdateres) parallelt med hovedversionen (dvs. engelsksproget).

For at skjule alt dette "indre køkken" for brugeren og tilbyde ham noget, der "bare virker", gjorde vi separat werf installations- og opdateringsværktøj - Er multiwerf. Du skal blot angive udgivelsesnummeret og den stabilitetskanal, som du er klar til at bruge, og multiwerf vil tjekke om der er en ny version på kanalen og downloade den om nødvendigt.

I versionsvalgsmenuen på hjemmesiden er de seneste versioner af werf tilgængelige i hver kanal. Som standard efter adresse werf.io/documentation versionen af ​​den mest stabile kanal for den seneste udgivelse åbner - den er også indekseret af søgemaskiner. Dokumentation for kanalen er tilgængelig på separate adresser (f.eks. werf.io/v1.0-beta/dokumentation til betaversion 1.0).

I alt har siden følgende versioner tilgængelige:

  1. root (åbner som standard),
  2. for hver aktiv opdateringskanal for hver udgivelse (f.eks. werf.io/v1.0-beta).

For at generere en specifik version af et websted er det generelt nok at kompilere det ved hjælp af Jekyllved at køre i mappen /docs werf repository tilsvarende kommando (jekyll build), efter at have skiftet til Git-tagget for den påkrævede version.

Tilbage er blot at tilføje:

  • selve værktøjet (werf) bruges til montering;
  • CI/CD processer er bygget på basis af GitLab CI;
  • og alt dette kører selvfølgelig i Kubernetes.

opgaver

Lad os nu formulere opgaver, der tager højde for alle de beskrevne detaljer:

  1. Efter at have ændret werf-versionen på enhver opdateringskanal dokumentation på webstedet bør automatisk opdateres.
  2. For udvikling skal du kunne nogle gange se forhåndsvisningsversioner af webstedet.

Siden skal genkompileres efter at have ændret versionen på en hvilken som helst kanal fra de tilsvarende Git-tags, men i processen med at bygge billedet får vi følgende funktioner:

  • Da listen over versioner på kanaler ændres, er det kun nødvendigt at genopbygge dokumentationen for kanaler, hvor versionen er ændret. Det er jo ikke særlig rart at bygge alt op igen.
  • Sæt af kanaler for udgivelser kan ændre sig. På et tidspunkt kan der for eksempel ikke være en version på kanalerne, der er mere stabil end 1.1-udgivelsen med tidlig adgang, men med tiden vil de dukke op - i dette tilfælde, bør du ikke ændre samlingen manuelt?

Det viser sig, at montering afhænger af ændring af eksterne data.

implementering

At vælge en tilgang

Alternativt kan du køre hver påkrævet version som en separat pod i Kubernetes. Denne mulighed indebærer et større antal objekter i klyngen, som vil vokse med stigningen i antallet af stabile werffrigivelser. Og dette indebærer til gengæld mere kompleks vedligeholdelse: hver version har sin egen HTTP-server og med en lille belastning. Det medfører naturligvis også større ressourceomkostninger.

Vi gik samme vej samle alle nødvendige versioner i ét billede. Den kompilerede statik for alle versioner af webstedet er placeret i en container med NGINX, og trafik til den tilsvarende Deployment kommer gennem NGINX Ingress. En simpel struktur - en statsløs applikation - giver dig mulighed for nemt at skalere Deployment (afhængigt af belastningen) ved hjælp af Kubernetes selv.

For at være mere præcis samler vi to billeder: et til produktionskredsløbet, det andet er et ekstra til udviklerkredsløbet. Det ekstra billede bruges (lanceres) kun på dev-kredsløbet sammen med det primære og indeholder versionen af ​​webstedet fra review-commit, og routing mellem dem udføres ved hjælp af Ingress-ressourcer.

werf vs git klon og artefakter

Som allerede nævnt, for at generere webstedsstatik for en specifik version af dokumentationen, skal du bygge ved at skifte til det relevante repository-tag. Du kan også gøre dette ved at klone depotet, hver gang du bygger, ved at vælge de relevante tags fra en liste. Dette er dog en ret ressourcekrævende operation og kræver desuden skrivning af ikke-trivielle instruktioner... En anden alvorlig ulempe er, at med denne tilgang er der ingen måde at cache noget under montering.

Her kommer selve werfværket til hjælp og implementerer smart caching og giver dig mulighed for at bruge eksterne depoter. Brug af werf til at tilføje kode fra depotet vil fremskynde opbygningen betydeligt, fordi werf kloner i det væsentlige depotet én gang og udfører derefter kun fetch Hvis det er nødvendigt. Derudover kan vi, når vi tilføjer data fra depotet, kun vælge de nødvendige mapper (i vores tilfælde er dette biblioteket docs), hvilket vil reducere mængden af ​​tilføjede data betydeligt.

Da Jekyll er et værktøj designet til at kompilere statiske data og ikke er nødvendigt i det endelige billede, ville det være logisk at kompilere i werf artefakt, og ind i det endelige billede importer kun kompileringsresultatet.

Vi skriver werf.yaml

Så vi besluttede, at vi ville kompilere hver version i en separat werfartefakt. Dog vi vi ved ikke, hvor mange af disse artefakter, der vil være under samlingen, så vi kan ikke skrive en fast build-konfiguration (strengt taget kan vi stadig, men det vil ikke være helt effektivt).

werf giver dig mulighed for at bruge Gå skabeloner i din konfigurationsfil (werf.yaml), og det gør det muligt generer konfiguration med det samme afhængig af eksterne data (hvad du har brug for!). Eksterne data i vores tilfælde er oplysninger om versioner og udgivelser, på grundlag af hvilke vi indsamler det nødvendige antal artefakter, og som et resultat opnår vi to billeder: werf-doc и werf-dev at køre på forskellige kredsløb.

Eksterne data sendes gennem miljøvariabler. Her er deres sammensætning:

  • RELEASES — en linje med en liste over udgivelser og den tilsvarende aktuelle version af werf i form af en mellemrumssepareret liste over værdier i formatet <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>. Et eksempel: 1.0%v1.0.4-beta.20
  • CHANNELS — en linje med en liste over kanaler og den tilsvarende aktuelle version af werf i form af en mellemrumssepareret liste over værdier i formatet <КАНАЛ>%<НОМЕР_ВЕРСИИ>. Et eksempel: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — werf-udgivelsesversion skal vises som standard på webstedet (det er ikke altid nødvendigt at vise dokumentation med det højeste udgivelsesnummer). Eksempel: v1.0.4-beta.20
  • REVIEW_SHA — hash af review-commit, hvorfra du skal bygge versionen til testloopet.

Disse variabler vil blive udfyldt i GitLab CI-pipelinen, og hvordan præcist er skrevet nedenfor.

Først og fremmest definerer vi for nemheds skyld i werf.yaml Gå til skabelonvariabler, og tildel dem værdier fra miljøvariabler:

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

Beskrivelsen af ​​artefakten til kompilering af den statiske version af webstedet er generelt den samme for alle tilfælde, vi har brug for (inklusive generering af rodversionen, såvel som versionen til dev-kredsløbet). Derfor flytter vi den ind i en separat blok ved hjælp af funktionen define - til efterfølgende genbrug include. Vi vil videregive følgende argumenter til skabelonen:

  • Version — genereret version (mærkenavn);
  • Channel — navnet på den opdateringskanal, som artefakten er genereret for;
  • Commit — commit hash, hvis artefakten er genereret til en review commit;
  • sammenhæng.

Beskrivelse af artefaktskabelon

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

Artefaktnavnet skal være unikt. Vi kan opnå dette, for eksempel ved at tilføje kanalnavnet (værdien af ​​variablen .Channel) som et suffiks til navnet på artefakten: artifact: doc-{{ .Channel }}. Men du skal forstå, at når du importerer fra artefakter, skal du henvise til de samme navne.

Når du beskriver en artefakt, bruges følgende werf-funktion: montering. Montering, der angiver servicebiblioteket build_dir giver dig mulighed for at gemme Jekyll-cachen mellem pipeline-kørsler, hvilket fremskynder genmonteringen markant.

Du har muligvis også bemærket brugen af ​​filen releases.yml er en YAML-fil med udgivelsesdata anmodet fra github.com (en artefakt opnået ved udførelse af en pipeline). Det er nødvendigt, når du kompilerer webstedet, men i forbindelse med artiklen er det interessant for os, fordi det afhænger af dets tilstand genmontering af kun én artefakt — en artefakt af rodversionen af ​​webstedet (det er ikke nødvendigt i andre artefakter).

Dette implementeres ved hjælp af den betingede erklæring if Gå skabeloner og designs {{ $Root.Files.Get "releases.yml" | sha256sum }} i scenen niveauer. Det fungerer som følger: når man bygger et artefakt til rodversionen (variabel .Channel er lig med root) fil hash releases.yml påvirker signaturen for hele scenen, da den er en del af navnet på Ansible-opgaven (parameter name). Altså når man skifter indhold fil releases.yml den tilsvarende artefakt vil blive samlet igen.

Vær også opmærksom på at arbejde med et eksternt lager. I billedet af en artefakt fra werf depot, kun mappen tilføjes /docs, og afhængigt af de beståede parametre, tilføjes dataene for det påkrævede tag eller review-commit med det samme.

For at bruge artefaktskabelonen til at generere en beskrivelse af artefakten af ​​de overførte versioner af kanaler og udgivelser, organiserer vi en løkke på variablen .WerfVersions в werf.yaml:

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

Fordi løkken vil generere flere artefakter (vi håber det), det er nødvendigt at tage højde for separatoren mellem dem - sekvensen --- (For mere information om konfigurationsfilsyntaks, se dokumentation). Som defineret tidligere, når vi kalder en skabelon i en loop, sender vi versionsparametrene, URL og root-kontekst.

På samme måde, men uden en løkke, kalder vi artefaktskabelonen for "særlige tilfælde": for rodversionen, såvel som versionen fra review-commit:

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

Bemærk venligst, at artefakten for gennemgangsforpligtelsen kun vil blive bygget, hvis variablen er indstillet .WerfReviewCommit.

Artefakterne er klar - det er tid til at begynde at importere!

Det endelige billede, designet til at køre på Kubernetes, er en almindelig NGINX med en serverkonfigurationsfil tilføjet nginx.conf og statisk fra artefakter. Ud over artefakten af ​​rodversionen af ​​webstedet skal vi gentage løkken på variablen .WerfVersions for at importere artefakter af kanal- og udgivelsesversioner + følg artefaktnavngivningsreglen, som vi adopterede tidligere. Da hver artefakt gemmer versioner af webstedet for to sprog, importerer vi dem til de steder, som konfigurationen giver.

Beskrivelse af det endelige billede 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 -}}

Det ekstra billede, som sammen med det primære, lanceres på udviklerkredsløbet, indeholder kun to versioner af webstedet: versionen fra review-commit og rodversionen af ​​webstedet (der er generelle aktiver og, hvis du husker , frigivelsesdata). Således vil det ekstra billede kun adskille sig fra det vigtigste i importsektionen (og selvfølgelig i navnet):

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

Som nævnt ovenfor genereres artefakten for gennemgangsforpligtelsen kun, når den indstillede miljøvariabel køres REVIEW_SHA. Det ville være muligt slet ikke at generere werf-dev-billedet, hvis der ikke er nogen miljøvariabel REVIEW_SHA, men for at rengøring efter politikker Docker-billeder i werf fungerede for werf-dev-billedet, vi lader det kun bygges med artefakten af ​​rodversionen (det er allerede bygget alligevel), for at forenkle pipeline-strukturen.

Forsamlingen er klar! Lad os gå videre til CI/CD og vigtige nuancer.

Pipeline i GitLab CI og funktioner i dynamisk opbygning

Når vi kører build, skal vi indstille de miljøvariabler, der bruges i werf.yaml. Dette gælder ikke for REVIEW_SHA-variablen, som vi indstiller, når vi kalder pipeline fra GitHub-krogen.

Vi genererer de nødvendige eksterne data i et Bash-script generate_artifacts, som vil generere to GitLab pipeline artefakter:

  • файл releases.yml med udgivelsesdata,
  • файл common_envs.sh, der indeholder de miljøvariabler, der skal eksporteres.

Filens indhold generate_artifacts finder du i vores arkiver med eksempler. Modtagelse af selve data er ikke emnet for artiklen, men filen common_envs.sh er vigtigt for os, fordi werfs arbejde afhænger af det. Et eksempel på dets indhold:

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'

Du kan bruge outputtet af et sådant script, for eksempel ved at bruge Bash-funktionen source.

Nu kommer den sjove del. For at både opbygningen og udrulningen af ​​applikationen skal fungere korrekt, er det nødvendigt at sikre det werf.yaml Det var det samme mindst inden for én rørledning. Hvis denne betingelse ikke er opfyldt, så vil signaturerne for de etaper, som werf beregner under montering og f.eks. implementering, være anderledes. Dette vil føre til en installationsfejl, fordi... det billede, der kræves til implementering, vil mangle.

Med andre ord, hvis oplysningerne om udgivelser og versioner er de samme under samlingen af ​​webstedsbilledet, og på tidspunktet for implementeringen frigives en ny version, og miljøvariablerne har forskellige værdier, vil implementeringen mislykkes med en fejl: når alt kommer til alt, er artefakten af ​​den nye version endnu ikke bygget.

Hvis generation werf.yaml afhænger af eksterne data (for eksempel en liste over aktuelle versioner, som i vores tilfælde), så skal sammensætningen og værdierne af sådanne data registreres i pipelinen. Dette er især vigtigt, hvis eksterne parametre ændres ret ofte.

Vi vil modtage og optage eksterne data i første fase af pipelinen i GitLab (Forudbygget) og send dem videre i formularen GitLab CI artefakt. Dette giver dig mulighed for at køre og genstarte pipelinejob (opbygning, implementering, oprydning) med den samme konfiguration i werf.yaml.

Scenens indhold Forudbygget fil .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

Efter at have fanget de eksterne data i artefakten, kan du bygge og implementere ved hjælp af standard GitLab CI pipeline stadier: Byg og Deploy. Vi starter selve pipelinen ved hjælp af kroge fra werf GitHub-depotet (dvs. når der er ændringer i GitHub-depotet). Data for dem kan findes i GitLab-projektegenskaberne i afsnittet CI/CD-indstillinger -> Pipeline-udløsere, og opret derefter den tilsvarende Webhook i GitHub (Indstillinger -> Webhooks).

Byggefasen vil se sådan ud:

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 vil tilføje to artefakter fra scenen til byggefasen Forudbygget, så vi eksporterer variabler med forberedte inputdata ved hjælp af konstruktionen source common_envs.sh. Vi starter byggefasen i alle tilfælde, bortset fra at lancere rørledningen i henhold til en tidsplan. I henhold til tidsplanen vil vi køre en rørledning til rengøring - i dette tilfælde er der ikke behov for at udføre montage.

På implementeringsstadiet vil vi beskrive to opgaver - separat for implementering til produktions- og dev-kredsløb ved hjælp af en YAML-skabelon:

.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

Opgaverne adskiller sig i det væsentlige kun ved at angive den klyngekontekst, som werf skal udføre udrulningen i (WERF_KUBE_CONTEXT), og indstille sløjfemiljøvariablerne (environment.name и environment.url), som derefter bruges i Helm-diagramskabeloner. Vi vil ikke levere indholdet af skabelonerne, fordi... der er ikke noget interessant der for det pågældende emne, men du kan finde dem i arkiver for artiklen.

Endelig berøring

Da werf-versioner udgives ret ofte, vil der ofte blive bygget nye billeder, og Docker Registry vil konstant vokse. Derfor er det bydende nødvendigt at konfigurere automatisk billedoprydning baseret på politikker. Det er meget nemt at gøre.

For at implementere skal du:

  • Tilføj et rengøringstrin til .gitlab-ci.yml;
  • Tilføj periodisk udførelse af en rengøringsopgave;
  • Opsæt en miljøvariabel med et skriveadgangstoken.

Tilføjelse af et rengøringstrin til .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

Vi har allerede set næsten alt dette lidt højere - kun for at rense det skal du først logge ind på Docker Registry med et token, der har rettighederne til at slette billeder i Docker Registry (det automatisk udstedte GitLab CI opgavetoken gør ikke har sådanne rettigheder). Tokenet skal være oprettet i GitLab på forhånd, og dets værdi skal angives i miljøvariablen WERF_IMAGES_CLEANUP_PASSWORD projekt (CI/CD-indstillinger -> Variabler).

Tilføjelse af en rengøringsopgave med den påkrævede tidsplan er udført i CI/CD ->
Tidsplaner
.

Det er det: Et projekt i Docker Registry vil ikke længere konstant vokse fra ubrugte billeder.

I slutningen af ​​den praktiske del, lad mig minde dig om, at fulde lister fra artiklen er tilgængelige i Git:

Outcome

  1. Vi modtog en logisk samlingsstruktur: en artefakt pr. version.
  2. Samlingen er universel og kræver ikke manuelle ændringer, når nye versioner af werf frigives: dokumentationen på hjemmesiden opdateres automatisk.
  3. To billeder er samlet til forskellige konturer.
  4. Det virker hurtigt, pga Caching bruges så meget som muligt - når en ny version af werf frigives, eller en GitHub-hook kaldes til en review-commit, bliver kun den tilsvarende artefakt med den ændrede version genopbygget.
  5. Ingen grund til at tænke på at slette ubrugte billeder: rengøring i henhold til werf-politikker vil holde Docker Registry i orden.

Fund

  • Brug af werf gør det muligt for samlingen at arbejde hurtigt på grund af caching af både selve samlingen og caching, når man arbejder med eksterne repositories.
  • At arbejde med eksterne Git-lagre eliminerer behovet for at klone hele depotet hver gang eller genopfinde hjulet med en vanskelig optimeringslogik. werf bruger en cache og udfører kun kloningen én gang og bruger derefter fetch og kun når det er nødvendigt.
  • Mulighed for at bruge Go-skabeloner i build-konfigurationsfilen werf.yaml giver dig mulighed for at beskrive en samling, hvis resultat afhænger af eksterne data.
  • Brug af mount i werf fremskynder indsamlingen af ​​artefakter markant - på grund af cachen, som er fælles for alle rørledninger.
  • werf gør det nemt at konfigurere oprydning, hvilket er særligt vigtigt, når man bygger dynamisk.

PS

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar