Dynamisk sammenstilling og distribusjon av Docker-bilder med werf ved å bruke eksemplet på en versjonert dokumentasjonsside

Vi har allerede snakket om GitOps-verktøyet vårt mer enn én gang. werf, og denne gangen vil vi gjerne dele vår erfaring med å sette sammen nettstedet med dokumentasjonen for selve prosjektet - werf.io (den russiske versjonen er en.werf.io). Dette er et vanlig statisk nettsted, men sammenstillingen er interessant ved at den er bygget ved hjelp av et dynamisk antall artefakter.

Dynamisk sammenstilling og distribusjon av Docker-bilder med werf ved å bruke eksemplet på en versjonert dokumentasjonsside

Gå inn i nyansene til nettstedstrukturen: generer en felles meny for alle versjoner, sider med informasjon om utgivelser, etc. - vi vil ikke. La oss heller fokusere på problemene og funksjonene ved dynamisk montering og litt på de medfølgende CI/CD-prosessene.

Introduksjon: hvordan nettstedet fungerer

Til å begynne med lagres werf-dokumentasjon sammen med koden. Dette stiller visse utviklingskrav som generelt ligger utenfor rammen av denne artikkelen, men som et minimum kan det sies at:

  • Nye werf-funksjoner bør ikke utgis uten å oppdatere dokumentasjonen, og omvendt, eventuelle endringer i dokumentasjonen innebærer utgivelse av en ny versjon av werf;
  • Prosjektet har en ganske intensiv utvikling: nye versjoner kan slippes flere ganger om dagen;
  • Eventuelle manuelle operasjoner for å distribuere et nettsted med en ny versjon av dokumentasjonen er i det minste kjedelig;
  • Prosjektet har en semantisk tilnærming versjonering, med 5 stabilitetskanaler. Utgivelsesprosessen innebærer sekvensiell passasje av versjoner gjennom kanaler for å øke stabiliteten: fra alfa til bunnsolid;
  • Nettstedet har en russiskspråklig versjon, som "lever og utvikler seg" (dvs. hvis innhold oppdateres) parallelt med hovedversjonen (dvs. engelskspråklig).

For å skjule alt dette "indre kjøkkenet" for brukeren, tilby ham noe som "bare fungerer", gjorde vi separat werf installasjon og oppdateringsverktøy - Er multiwerf. Du trenger bare å spesifisere utgivelsesnummeret og stabilitetskanalen du er klar til å bruke, og multiwerf vil sjekke om det er en ny versjon på kanalen og laste den ned om nødvendig.

I versjonsvalgmenyen på nettsiden er de nyeste versjonene av werf tilgjengelig i hver kanal. Som standard, etter adresse werf.io/documentation versjonen av den mest stabile kanalen for den siste utgivelsen åpnes - den er også indeksert av søkemotorer. Dokumentasjon for kanalen er tilgjengelig på separate adresser (f.eks. werf.io/v1.0-beta/documentation for betaversjon 1.0).

Totalt har nettstedet følgende versjoner tilgjengelig:

  1. root (åpnes som standard),
  2. for hver aktive oppdateringskanal for hver utgivelse (f.eks. werf.io/v1.0-beta).

For å generere en spesifikk versjon av et nettsted, generelt, er det nok å kompilere det ved hjelp av Jekyllved å kjøre i katalogen /docs werf repository tilsvarende kommando (jekyll build), etter å ha byttet til Git-taggen til den nødvendige versjonen.

Det gjenstår bare å legge til:

  • selve verktøyet (werf) brukes til montering;
  • CI/CD-prosesser er bygget på grunnlag av GitLab CI;
  • og alt dette foregår selvfølgelig i Kubernetes.

oppgaver

La oss nå formulere oppgaver som tar hensyn til alle de beskrevne detaljene:

  1. Etter å ha endret werf-versjonen på en hvilken som helst oppdateringskanal dokumentasjon på nettstedet skal oppdateres automatisk.
  2. For utvikling må du kunne noen ganger se forhåndsvisningsversjoner av nettstedet.

Siden må kompileres på nytt etter å ha endret versjonen på en hvilken som helst kanal fra de tilsvarende Git-taggene, men i prosessen med å bygge bildet får vi følgende funksjoner:

  • Siden listen over versjoner på kanaler endres, er det kun nødvendig å bygge om dokumentasjonen for kanaler der versjonen er endret. Å bygge opp igjen alt er tross alt ikke særlig hyggelig.
  • Settet med kanaler for utgivelser kan endres. På et tidspunkt kan det for eksempel ikke være en versjon på kanalene som er mer stabil enn 1.1-utgivelsen med tidlig tilgang, men over tid vil de dukke opp - i dette tilfellet, bør du ikke endre sammenstillingen manuelt?

Det viser seg at montering avhenger av endring av eksterne data.

implementering

Velge en tilnærming

Alternativt kan du kjøre hver påkrevde versjon som en separat pod i Kubernetes. Dette alternativet innebærer et større antall objekter i klyngen, som vil vokse med økningen i antall stabile werfutgivelser. Og dette innebærer i sin tur mer komplekst vedlikehold: hver versjon har sin egen HTTP-server, og med en liten belastning. Dette medfører selvsagt også større ressurskostnader.

Vi tok samme vei samle alle nødvendige versjoner i ett bilde. Den kompilerte statistikken for alle versjoner av nettstedet er plassert i en container med NGINX, og trafikk til den tilsvarende Deployment kommer gjennom NGINX Ingress. En enkel struktur - en statsløs applikasjon - lar deg enkelt skalere Deployment (avhengig av belastningen) ved å bruke Kubernetes selv.

For å være mer presis, samler vi inn to bilder: ett for produksjonskretsen, det andre er et ekstra for utviklingskretsen. Tilleggsbildet brukes (lanseres) bare på dev-kretsen sammen med den viktigste og inneholder versjonen av nettstedet fra gjennomgangsforpliktelsen, og ruting mellom dem utføres ved hjelp av Ingress-ressurser.

werf vs git klon og artefakter

Som allerede nevnt, for å generere nettstedsstatistikk for en spesifikk versjon av dokumentasjonen, må du bygge ved å bytte til riktig depottag. Du kan også gjøre dette ved å klone depotet hver gang du bygger, og velge de riktige taggene fra en liste. Dette er imidlertid en ganske ressurskrevende operasjon og krever dessuten å skrive ikke-trivielle instruksjoner... En annen alvorlig ulempe er at med denne tilnærmingen er det ingen måte å cache noe under montering.

Her kommer selve werf-verktøyet oss til hjelp og implementerer smart caching og lar deg bruke eksterne depoter. Å bruke werf for å legge til kode fra depotet vil øke byggingen betydelig, fordi werf kloner i hovedsak depotet én gang og kjører deretter bare fetch hvis nødvendig. I tillegg, når vi legger til data fra depotet, kan vi bare velge de nødvendige katalogene (i vårt tilfelle er dette katalogen docs), som vil redusere mengden lagt til data betydelig.

Siden Jekyll er et verktøy designet for å kompilere statiske data og ikke er nødvendig i det endelige bildet, ville det være logisk å kompilere i werf artefakt, og inn i det endelige bildet importer kun kompileringsresultatet.

Vi skriver werf.yaml

Så vi bestemte oss for at vi skulle kompilere hver versjon i en separat werfartefakt. Men vi vi vet ikke hvor mange av disse gjenstandene det vil være under montering, så vi kan ikke skrive en fast byggekonfigurasjon (strengt tatt kan vi fortsatt, men det vil ikke være helt effektivt).

werf lar deg bruke Gå maler i konfigurasjonsfilen din (werf.yaml), og dette gjør det mulig generere konfigurasjon på farten avhengig av eksterne data (hva du trenger!). Eksterne data i vårt tilfelle er informasjon om versjoner og utgivelser, på grunnlag av hvilke vi samler inn det nødvendige antallet artefakter og som et resultat får vi to bilder: werf-doc и werf-dev å kjøre på forskjellige kretser.

Eksterne data sendes gjennom miljøvariabler. Her er deres sammensetning:

  • RELEASES — en linje med en liste over utgivelser og den tilsvarende gjeldende versjonen av werf, i form av en mellomromseparert liste over verdier i formatet <НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>... Eksempel: 1.0%v1.0.4-beta.20
  • CHANNELS — en linje med en liste over kanaler og den tilsvarende gjeldende versjonen av werf, i form av en mellomromseparert liste over verdier i formatet <КАНАЛ>%<НОМЕР_ВЕРСИИ>... Eksempel: 1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22
  • ROOT_VERSION — werf utgivelsesversjon som skal vises som standard på nettstedet (det er ikke alltid nødvendig å vise dokumentasjon med det høyeste utgivelsesnummeret). Eksempel: v1.0.4-beta.20
  • REVIEW_SHA — hash av gjennomgangsforpliktelsen som du må bygge versjonen for testsløyfen fra.

Disse variablene vil bli fylt ut i GitLab CI-pipeline, og nøyaktig hvordan er skrevet nedenfor.

Først av alt, for enkelhets skyld definerer vi i werf.yaml Gå til malvariabler, og tilordne dem verdier fra miljøvariabler:

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

Beskrivelsen av artefakten for kompilering av den statiske versjonen av nettstedet er generelt den samme for alle tilfeller vi trenger (inkludert generering av rotversjonen, samt versjonen for dev-kretsen). Derfor vil vi flytte den inn i en egen blokk ved hjelp av funksjonen define - for senere gjenbruk include. Vi sender følgende argumenter til malen:

  • Version — generert versjon (tagnavn);
  • Channel — navnet på oppdateringskanalen som artefakten er generert for;
  • Commit — commit hash, hvis artefakten er generert for en review commit;
  • kontekst.

Beskrivelse av artefaktmal

{{- 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 må være unikt. Vi kan oppnå dette, for eksempel ved å legge til kanalnavnet (verdien til variabelen .Channel) som et suffiks til navnet på artefakten: artifact: doc-{{ .Channel }}. Men du må forstå at når du importerer fra artefakter, må du referere til de samme navnene.

Når du beskriver en artefakt, brukes følgende werf-funksjon: montering. Montering som indikerer tjenestekatalogen build_dir lar deg lagre Jekyll-bufferen mellom rørledningskjøringer, som øker remonteringen betydelig.

Du har kanskje også lagt merke til bruken av filen releases.yml er en YAML-fil med utgivelsesdata forespurt fra github.com (en artefakt oppnådd ved utføring av en rørledning). Det er nødvendig når du kompilerer nettstedet, men i sammenheng med artikkelen er det interessant for oss fordi det avhenger av tilstanden remontering av bare én artefakt — en artefakt av rotversjonen av nettstedet (det er ikke nødvendig i andre artefakter).

Dette implementeres ved å bruke den betingede erklæringen if Gå til maler og design {{ $Root.Files.Get "releases.yml" | sha256sum }} på scenen etapper. Det fungerer som følger: når du bygger en artefakt for rotversjonen (variabel .Channel er lik root) filhash releases.yml påvirker signaturen til hele scenen, siden den er en del av navnet på Ansible-oppgaven (parameter name). Altså ved endring innhold fil releases.yml den tilsvarende artefakten vil bli satt sammen igjen.

Vær også oppmerksom på å jobbe med et eksternt depot. I bildet av en artefakt fra werf depot, bare katalogen legges til /docs, og avhengig av de beståtte parameterne, blir dataene til den nødvendige taggen eller gjennomgangsforpliktelsen lagt til umiddelbart.

For å bruke artefaktmalen til å generere en beskrivelse av artefakten til de overførte versjonene av kanaler og utgivelser, organiserer vi en løkke på variabelen .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åper det), det er nødvendig å ta hensyn til separatoren mellom dem - sekvensen --- (For mer informasjon om konfigurasjonsfilsyntaks, se dokumentasjon). Som definert tidligere, når vi kaller en mal i en loop, sender vi versjonsparametrene, URL og rotkontekst.

På samme måte, men uten en løkke, kaller vi artefaktmalen for "spesielle tilfeller": for rotversjonen, samt versjonen fra gjennomgangsforpliktelsen:

{{ 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ær oppmerksom på at artefakten for gjennomgangsforpliktelsen bare bygges hvis variabelen er angitt .WerfReviewCommit.

Artefaktene er klare - det er på tide å begynne å importere!

Det endelige bildet, designet for å kjøre på Kubernetes, er en vanlig NGINX med en serverkonfigurasjonsfil lagt til nginx.conf og statisk fra artefakter. I tillegg til artefakten til rotversjonen av nettstedet, må vi gjenta løkken på variabelen .WerfVersions for å importere artefakter av kanal- og utgivelsesversjoner + følg navneregelen for artefakter som vi tok i bruk tidligere. Siden hver artefakt lagrer versjoner av nettstedet for to språk, importerer vi dem til stedene gitt av konfigurasjonen.

Beskrivelse av det endelige bildet 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 -}}

Tilleggsbildet, som, sammen med det viktigste, lanseres på dev-kretsen, inneholder bare to versjoner av nettstedet: versjonen fra gjennomgangsforpliktelsen og rotversjonen av nettstedet (det er generelle eiendeler og, hvis du husker , utgivelsesdata). Dermed vil tilleggsbildet avvike fra hovedbildet bare i importdelen (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 nevnt ovenfor, vil artefakten for gjennomgangsforpliktelsen kun genereres når den angitte miljøvariabelen kjøres REVIEW_SHA. Det ville være mulig å ikke generere werf-dev-bildet i det hele tatt hvis det ikke er noen miljøvariabel REVIEW_SHA, men for å rengjøring etter politikk Docker-bilder i werf fungerte for werf-dev-bildet, vi vil la det bygges kun med rotversjonsartefakten (det er allerede bygget uansett), for å forenkle rørledningsstrukturen.

Monteringen er klar! La oss gå videre til CI/CD og viktige nyanser.

Pipeline i GitLab CI og funksjoner i dynamisk bygg

Når vi kjører bygningen, må vi angi miljøvariablene som brukes i werf.yaml. Dette gjelder ikke for REVIEW_SHA-variabelen, som vi vil angi når vi kaller pipeline fra GitHub-kroken.

Vi vil generere de nødvendige eksterne dataene i et Bash-skript generate_artifacts, som vil generere to GitLab-rørledningsartefakter:

  • файл releases.yml med utgivelsesdata,
  • файл common_envs.sh, som inneholder miljøvariablene som skal eksporteres.

Filinnhold generate_artifacts finner du i vår depoter med eksempler. Å motta selve dataene er ikke emnet for artikkelen, men filen common_envs.sh er viktig for oss, fordi arbeidet til werf avhenger av det. Et eksempel på innholdet:

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 bruke utdata fra et slikt skript, for eksempel ved å bruke Bash-funksjonen source.

Nå kommer den morsomme delen. For at både bygging og distribusjon av applikasjonen skal fungere riktig, er det nødvendig å sikre det werf.yaml det var det samme minst innenfor én rørledning. Hvis denne betingelsen ikke er oppfylt, vil signaturene til trinnene som werf beregner under montering og for eksempel utplassering være annerledes. Dette vil føre til en distribusjonsfeil, fordi... bildet som kreves for distribusjon, vil mangle.

Med andre ord, hvis informasjonen om utgivelser og versjoner er den samme under sammenstillingen av nettstedsbildet, og på tidspunktet for utrullingen blir en ny versjon utgitt og miljøvariablene har forskjellige verdier, vil distribusjonen mislykkes med en feil: tross alt er gjenstanden til den nye versjonen ennå ikke bygget.

Hvis generasjon werf.yaml avhenger av eksterne data (for eksempel en liste over gjeldende versjoner, som i vårt tilfelle), så bør sammensetningen og verdiene til slike data registreres i rørledningen. Dette er spesielt viktig hvis eksterne parametere endres ganske ofte.

Vi vil motta og ta opp eksterne data ved første fase av rørledningen i GitLab (Forhåndsbygg) og send dem videre i skjemaet GitLab CI-artefakt. Dette vil tillate deg å kjøre og starte rørledningsjobber på nytt (bygge, distribuere, rydde opp) med samme konfigurasjon i werf.yaml.

Scenens innhold Forhåndsbygg 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

Etter å ha fanget de eksterne dataene i artefakten, kan du bygge og distribuere ved å bruke standard GitLab CI-pipelinestadier: Bygg og distribuer. Vi lanserer selve rørledningen ved å bruke kroker fra werf GitHub-depotet (dvs. når det er endringer i GitHub-depotet). Data for dem kan finnes i GitLab-prosjektegenskapene i seksjonen CI/CD-innstillinger -> Pipeline-utløsere, og lag deretter den tilsvarende Webhook i GitHub (Innstillinger -> Webhooks).

Byggestadiet vil se slik ut:

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 legge til to artefakter fra scenen til byggefasen Forhåndsbygg, så vi eksporterer variabler med forberedte inputdata ved å bruke konstruksjonen source common_envs.sh. Vi starter byggefasen i alle tilfeller, bortsett fra lansering av rørledningen i henhold til en tidsplan. I henhold til tidsplanen vil vi kjøre en rørledning for rengjøring - i dette tilfellet er det ikke nødvendig å utføre montering.

På distribusjonsstadiet vil vi beskrive to oppgaver - separat for distribusjon til produksjons- og utviklingskretser, ved å bruke en YAML-mal:

.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

Oppgavene er i hovedsak bare forskjellige når det gjelder å angi klyngekonteksten som werf skal utføre distribusjonen i (WERF_KUBE_CONTEXT), og angi løkkemiljøvariablene (environment.name и environment.url), som deretter brukes i Helm-kartmaler. Vi vil ikke oppgi innholdet i malene, fordi... det er ikke noe interessant der for det aktuelle emnet, men du kan finne dem i arkiver for artikkelen.

Endelig berøring

Siden werf-versjoner utgis ganske ofte, vil nye bilder bli bygget ofte, og Docker Registry vil stadig vokse. Derfor er det viktig å konfigurere automatisk bildeopprydding basert på retningslinjer. Det er veldig enkelt å gjøre.

For å implementere trenger du:

  • Legg til et rensetrinn til .gitlab-ci.yml;
  • Legg til periodisk utførelse av en rengjøringsoppgave;
  • Sett opp en miljøvariabel med et skrivetilgangstoken.

Legge til et rensetrinn 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 sett nesten alt dette litt høyere - bare for å rense det må du først logge på Docker Registry med et token som har rettighetene til å slette bilder i Docker Registry (det automatisk utstedte GitLab CI-oppgavetokenet gjør det ikke har slike rettigheter). Tokenet må opprettes i GitLab på forhånd og verdien må spesifiseres i miljøvariabelen WERF_IMAGES_CLEANUP_PASSWORD prosjekt (CI/CD-innstillinger -> Variabler).

Å legge til en rengjøringsoppgave med den nødvendige tidsplanen er gjort i CI/CD ->
Rutetider
.

Det er det: et prosjekt i Docker Registry vil ikke lenger konstant vokse fra ubrukte bilder.

På slutten av den praktiske delen, la meg minne deg på at fullstendige oppføringer fra artikkelen er tilgjengelige i :

Resultat

  1. Vi mottok en logisk monteringsstruktur: én artefakt per versjon.
  2. Monteringen er universell og krever ikke manuelle endringer når nye versjoner av werf slippes: dokumentasjonen på nettsiden oppdateres automatisk.
  3. To bilder er satt sammen for forskjellige konturer.
  4. Det fungerer raskt, fordi Caching brukes så mye som mulig - når en ny versjon av werf er utgitt eller en GitHub-hook blir kalt for en gjennomgangsforpliktelse, blir bare den tilsvarende artefakten med den endrede versjonen gjenoppbygd.
  5. Ingen grunn til å tenke på å slette ubrukte bilder: rengjøring i henhold til werf-policyer vil holde Docker-registeret i orden.

Funn

  • Ved å bruke werf kan sammenstillingen fungere raskt på grunn av caching av både selve sammenstillingen og caching når du arbeider med eksterne repositories.
  • Å jobbe med eksterne Git-depoter eliminerer behovet for å klone hele depotet hver gang eller finne opp hjulet på nytt med vanskelig optimaliseringslogikk. werf bruker en cache og gjør kloningen bare én gang, og bruker deretter fetch og bare når det er nødvendig.
  • Evne til å bruke Go-maler i byggekonfigurasjonsfilen werf.yaml lar deg beskrive en sammenstilling hvis resultat avhenger av eksterne data.
  • Bruk av mount in werf øker innsamlingen av artefakter betydelig - på grunn av cachen, som er felles for alle rørledninger.
  • werf gjør det enkelt å konfigurere opprydding, noe som er spesielt viktig når du bygger dynamisk.

PS

Les også på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar