We hebben het al vaker over onze GitOps-tool gehad , en deze keer willen we de ervaring delen van het samenstellen van een website met de documentatie van het project zelf - (de Russische versie is ). Dit is een gewone statische site, maar de samenstelling ervan is interessant omdat deze is opgebouwd met behulp van een dynamisch aantal artefacten.

We gaan hier niet in op de details van de sitestructuur: het genereren van een gemeenschappelijk menu voor alle versies, een pagina met informatie over releases, etc. In plaats daarvan richten we ons op de problemen en functies van dynamische assemblage en een beetje op de bijbehorende CI/CD-processen.
Inleiding: Hoe de site werkt
Laten we beginnen met het feit dat werf-documentatie samen met de code wordt opgeslagen. Dit stelt bepaalde eisen aan de ontwikkeling, die over het algemeen buiten het bestek van dit artikel vallen, maar we kunnen in ieder geval het volgende zeggen:
- Nieuwe werf-functies mogen niet worden vrijgegeven zonder de documentatie te updaten. Omgekeerd impliceren alle wijzigingen in de documentatie de vrijgave van een nieuwe versie van werf.
- Het project kent een behoorlijk intensieve ontwikkeling: er kunnen meerdere keren per dag nieuwe versies verschijnen;
- Alle handmatige handelingen om een site te implementeren met een nieuwe versie van de documentatie zijn op zijn minst vervelend;
- Het project hanteert een semantische benadering , met 5 stabiliteitskanalen. Het releaseproces omvat een opeenvolgende doorgang van versies door kanalen in volgorde van toenemende stabiliteit: van alfa tot rotsvast;
- De site heeft een Russischtalige versie, die ‘leeft en zich ontwikkelt’ (d.w.z. waarvan de inhoud wordt bijgewerkt) parallel aan de hoofdversie (d.w.z. de Engelstalige versie).
Om al deze ‘innerlijke werkingen’ voor de gebruiker te verbergen en hem iets te bieden dat ‘gewoon werkt’, hebben we aparte tool voor het installeren en updaten van werf - Is U hoeft alleen het releasenummer en het stabiliteitskanaal op te geven dat u wilt gebruiken. Multiwerf controleert dan of er een nieuwe versie op het kanaal beschikbaar is en downloadt deze indien nodig.
De nieuwste versies van werf zijn beschikbaar in elk kanaal in het versiekeuzemenu op de site. Standaard zijn bij De meest stabiele kanaalversie voor de nieuwste release wordt geopend - deze wordt ook geïndexeerd door zoekmachines. Documentatie voor het kanaal is beschikbaar op aparte adressen (bijvoorbeeld voor bètaversie 1.0).
In totaal zijn de volgende versies beschikbaar op de site:
- root (opent standaard),
- voor elk actief updatekanaal van elke release (bijv. ).
Om een specifieke versie van een site te genereren, is het in het algemeen voldoende om deze te compileren met behulp van , actief in de directory /docs werf repository corresponderende opdracht (jekyll build), nadat er eerder was overgeschakeld naar de Git-tag van de vereiste versie.
Het enige dat nog rest, is het volgende:
- het hulpprogramma zelf (werf) wordt gebruikt voor de assemblage;
- CI/CD-processen worden gebouwd op basis van GitLab CI;
- en dit alles draait uiteraard in Kubernetes.
taken
Laten we nu de taken formuleren die rekening houden met alle beschreven bijzonderheden:
- Na het wijzigen van de werfversie op een updatekanaal de documentatie op de site moet automatisch worden bijgewerkt.
- Om je te ontwikkelen moet je soms in staat zijn om Bekijk voorbeelden van de site.
De site moet opnieuw worden gecompileerd nadat de versie op een willekeurig kanaal is gewijzigd via de bijbehorende Git-tags, maar tijdens het proces van het samenstellen van de image krijgen we de volgende functies:
- Omdat de versielijst op kanalen verandert, hoeft alleen de documentatie voor de kanalen waar de versie is gewijzigd, opnieuw te worden opgebouwd. Alles vanaf nul opnieuw opbouwen is immers niet zo prettig.
- De set kanalen voor releases kan veranderen. Op een gegeven moment is er bijvoorbeeld mogelijk geen stabielere versie op de kanalen dan de early access 1.1-release, maar die zullen na verloop van tijd verschijnen. Je kunt de build in dat geval toch niet handmatig wijzigen?
Het blijkt dat de assemblage is afhankelijk van het wijzigen van externe gegevens.
uitvoering
Een aanpak kiezen
U kunt er ook voor kiezen om elke vereiste versie als een aparte pod in Kubernetes te draaien. Deze optie impliceert een groter aantal objecten in het cluster, dat zal toenemen naarmate het aantal stabiele werf-releases toeneemt. Dit impliceert op zijn beurt complexer onderhoud: elke versie heeft een eigen HTTP-server met een beperkte belasting. Dit brengt uiteraard ook hogere resourcekosten met zich mee.
Wij gingen dezelfde weg builds van alle vereiste versies in één imageDe gecompileerde statica van alle versies van de site bevinden zich in een container met NGINX, en het verkeer naar de bijbehorende implementatie verloopt via NGINX Ingress. Een eenvoudige structuur – een stateless applicatie – maakt het mogelijk om de implementatie eenvoudig te schalen (afhankelijk van de belasting) met behulp van Kubernetes zelf.
Om preciezer te zijn, we bouwen twee images: één voor het productiecircuit en de tweede is een extra image voor het dev-circuit. De extra image wordt alleen gebruikt (gedraaid) op het dev-circuit, samen met de hoofdimage, en bevat de versie van de site uit de reviewcommit. De routering tussen de images gebeurt met behulp van Ingress-resources.
werf vs git kloon en artefacten
Zoals gezegd, om sitestatistieken voor een specifieke versie van de documentatie te genereren, moet je builden door over te schakelen naar de bijbehorende repositorytag. Je kunt dit ook doen door de repository elke keer dat je buildt te klonen en de bijbehorende tags uit de lijst te selecteren. Dit is echter een vrij resource-intensieve bewerking en vereist bovendien het schrijven van niet-triviale instructies... Een ander ernstig nadeel is dat er met deze aanpak geen mogelijkheid is om iets te cachen tijdens de build.
Hier komt het werf-hulpprogramma zelf te hulp, door slimme caching en stelt u in staat om te gebruiken Door werf te gebruiken om code uit een repository toe te voegen, wordt de build aanzienlijk versneld, omdat werf de repository in feite één keer kloont en vervolgens uitvoert alleen fetch indien nodig. Bovendien kunnen we bij het toevoegen van gegevens uit de repository alleen de benodigde mappen selecteren (in ons geval is dit de map docs), waardoor de hoeveelheid toegevoegde gegevens aanzienlijk wordt verminderd.
Omdat Jekyll een hulpmiddel is dat is ontworpen om statische bestanden te compileren en niet nodig is in de uiteindelijke afbeelding, zou het logisch zijn om te compileren in , en in de uiteindelijke afbeelding importeer alleen het compilatieresultaat.
Wij schrijven werf.yaml
We besloten dus dat we elke versie in een apart werf-artefact zouden compileren. We we weten niet hoeveel van deze artefacten er tijdens de assemblage zullen zijn, dus we kunnen geen vaste buildconfiguratie schrijven (strikt genomen wel, maar dat is niet erg efficiënt).
werf stelt u in staat om te gebruiken in uw configuratiebestand (werf.yaml), en dit maakt het mogelijk genereer configuratie "on the fly" Afhankelijk van externe data (wat we nodig hebben!). In ons geval zijn externe data informatie over versies en releases, op basis waarvan we het benodigde aantal artefacten verzamelen en twee afbeeldingen als resultaat krijgen: werf-doc и werf-dev voor het starten op verschillende circuits.
Externe gegevens worden doorgegeven via omgevingsvariabelen. Dit is hun samenstelling:
-
RELEASES— een regel met een lijst met releases en de bijbehorende huidige versie van werf, als een door spaties gescheiden lijst met waarden in de indeling<НОМЕР_РЕЛИЗА>%<НОМЕР_ВЕРСИИ>. Voorbeeld:1.0%v1.0.4-beta.20 -
CHANNELS— een regel met een lijst met kanalen en de bijbehorende huidige versie van werf, in de vorm van een door spaties gescheiden lijst met waarden in de indeling<КАНАЛ>%<НОМЕР_ВЕРСИИ>. Voorbeeld:1.0-beta%v1.0.4-beta.20 1.0-alpha%v1.0.5-alpha.22 -
ROOT_VERSION— werf releaseversie die standaard op de site wordt weergegeven (het is niet altijd nodig om documentatie weer te geven met het hoogste releasenummer). Voorbeeld:v1.0.4-beta.20 -
REVIEW_SHA— de hash van de review commit waaruit de versie voor het testcircuit moet worden opgebouwd.
Deze variabelen worden ingevuld in de GitLab CI-pijplijn. Hoe dat precies gebeurt, wordt hieronder beschreven.
Laten we eerst voor het gemak definiëren werf.yaml Ga naar sjabloonvariabelen door ze waarden toe te wijzen vanuit omgevingsvariabelen:
{{ $_ := set . "WerfVersions" (cat (env "CHANNELS") (env "RELEASES") | splitList " ") }}
{{ $Root := . }}
{{ $_ := set . "WerfRootVersion" (env "ROOT_VERSION") }}
{{ $_ := set . "WerfReviewCommit" (env "REVIEW_SHA") }} De beschrijving van het artefact voor het compileren van de statische versie van de site is over het algemeen hetzelfde voor alle gevallen die we nodig hebben (inclusief het genereren van de rootversie, evenals de versie voor de dev-contour). Daarom zullen we het naar een apart blok verplaatsen met behulp van de functie define — voor later hergebruik met behulp van includeWe geven de volgende argumenten door aan de sjabloon:
-
Version— de gegenereerde versie (tagnaam); -
Channel— de naam van het updatekanaal waarvoor het artefact wordt gegenereerd; -
Commit— commit-hash, als het artefact wordt gegenereerd voor een review-commit; - context.
Beschrijving van het artefactsjabloon
{{- define "doc_artifact" -}}
{{- $Root := index . "Root" -}}
artifact: doc-{{ .Channel }}
from: jekyll/builder:3
mount:
- from: build_dir
to: /usr/local/bundle
ansible:
install:
- shell: |
export PATH=/usr/jekyll/bin/:$PATH
- name: "Install Dependencies"
shell: bundle install
args:
executable: /bin/bash
chdir: /app/docs
beforeSetup:
{{- if .Commit }}
- shell: echo "Review SHA - {{ .Commit }}."
{{- end }}
{{- if eq .Channel "root" }}
- name: "releases.yml HASH: {{ $Root.Files.Get "releases.yml" | sha256sum }}"
copy:
content: |
{{ $Root.Files.Get "releases.yml" | indent 8 }}
dest: /app/docs/_data/releases.yml
{{- else }}
- file:
path: /app/docs/_data/releases.yml
state: touch
{{- end }}
- file:
path: "{{`{{ item }}`}}"
state: directory
mode: 0777
with_items:
- /app/main_site/
- /app/ru_site/
- file:
dest: /app/docs/pages_ru/cli
state: link
src: /app/docs/pages/cli
- shell: |
echo -e "werfVersion: {{ .Version }}nwerfChannel: {{ .Channel }}" > /tmp/_config_additional.yml
export PATH=/usr/jekyll/bin/:$PATH
{{- if and (ne .Version "review") (ne .Channel "root") }}
{{- $_ := set . "BaseURL" ( printf "v%s" .Channel ) }}
{{- else if ne .Channel "root" }}
{{- $_ := set . "BaseURL" .Channel }}
{{- end }}
jekyll build -s /app/docs -d /app/_main_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/tmp/_config_additional.yml
jekyll build -s /app/docs -d /app/_ru_site/{{ if .BaseURL }} --baseurl /{{ .BaseURL }}{{ end }} --config /app/docs/_config.yml,/app/docs/_config_ru.yml,/tmp/_config_additional.yml
args:
executable: /bin/bash
chdir: /app/docs
git:
- url: https://github.com/flant/werf.git
to: /app/
owner: jekyll
group: jekyll
{{- if .Commit }}
commit: {{ .Commit }}
{{- else }}
tag: {{ .Version }}
{{- end }}
stageDependencies:
install: ['docs/Gemfile','docs/Gemfile.lock']
beforeSetup: '**/*'
includePaths: 'docs'
excludePaths: '**/*.sh'
{{- end }} De artefactnaam moet uniek zijn. We kunnen dit bijvoorbeeld bereiken door de kanaalnaam (de variabele waarde) toe te voegen. .Channel) als achtervoegsel bij de artefactnaam: artifact: doc-{{ .Channel }}Maar u moet begrijpen dat u bij het importeren van artefacten dezelfde namen moet gebruiken.
Bij het beschrijven van een artefact wordt de volgende werf-eigenschap gebruikt: . Monteren met een opgegeven servicedirectory build_dir Hiermee kunt u de Jekyll-cache behouden tussen pijplijnruns, wat versnelt de hermontage aanzienlijk.
Mogelijk heeft u ook het gebruik van het bestand opgemerkt releases.yml — is een YAML-bestand met opgevraagde releasegegevens (een artefact verkregen bij het uitvoeren van een pijplijn). Het is nodig bij het compileren van een site, maar in de context van het artikel is het voor ons interessant omdat de status ervan afhangt van hermontage van slechts één artefact — artefact van de rootversie van de site (het is niet nodig in andere artefacten).
Dit wordt geïmplementeerd met behulp van de voorwaardelijke operator. if Ga naar sjablonen en constructies {{ $Root.Files.Get "releases.yml" | sha256sum }} in fase Het werkt als volgt: bij het bouwen van een artefact voor de rootversie (variabele .Channel is gelijk aan root) bestandshash releases.yml beïnvloedt de handtekening van het hele podium, omdat het een onderdeel is van de Ansible-taaknaam (parameter name). Dus bij het veranderen inhoud het dossier releases.yml Het bijbehorende artefact wordt opnieuw in elkaar gezet.
Let ook op bij het werken met een externe repository. In de artefactafbeelding van , alleen de directory wordt toegevoegd /docsen afhankelijk van de doorgegeven parameters worden de gegevens van de vereiste tag of review commit direct toegevoegd.
Om de artefactsjabloon te gebruiken om een artefactbeschrijving van de overgedragen kanaalversies en releases te genereren, organiseren we een lus per variabele .WerfVersions в werf.yaml:
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ dict "Version" $VersionsDict._1 "Channel" $VersionsDict._0 "Root" $Root | include "doc_artifact" }}
---
{{ end -}} Omdat de cyclus meerdere artefacten zal genereren (dat hopen we), is het noodzakelijk om rekening te houden met de scheidingslijn ertussen: de sequentie --- (voor meer informatie over de syntaxis van het configuratiebestand, zie Zoals we eerder hebben gedefinieerd, geven we bij het aanroepen van de sjabloon in de lus de versieparameters, URL en rootcontext door.
Op dezelfde manier, maar dan zonder de cyclus, roepen we de artefactsjabloon aan voor ‘speciale gevallen’: voor de rootversie, evenals de versie uit de reviewcommit:
{{ 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 }} Houd er rekening mee dat het artefact voor de reviewcommit alleen wordt gebouwd als de variabele is ingesteld. .WerfReviewCommit.
De artefacten zijn klaar: tijd om te importeren!
De uiteindelijke image die op Kubernetes moet draaien, is een gewone NGINX met een toegevoegd serverconfiguratiebestand. nginx.conf en statica van artefacten. Naast het artefact van de rootversie van de site moeten we de cyclus herhalen per variabele. .WerfVersions Om kanaal- en releaseversie-artefacten te importeren, volgt u de naamgevingsregel voor artefacten die we eerder hebben gebruikt. Omdat elk artefact siteversies voor twee talen opslaat, importeren we ze naar de locaties die door de configuratie zijn opgegeven.
Beschrijving van de uiteindelijke afbeelding werf-doc
image: werf-doc
from: nginx:stable-alpine
ansible:
setup:
- name: "Setup /etc/nginx/nginx.conf"
copy:
content: |
{{ .Files.Get ".werf/nginx.conf" | indent 8 }}
dest: /etc/nginx/nginx.conf
- file:
path: "{{`{{ item }}`}}"
state: directory
mode: 0777
with_items:
- /app/main_site/assets
- /app/ru_site/assets
import:
- artifact: doc-root
add: /app/_main_site
to: /app/main_site
before: setup
- artifact: doc-root
add: /app/_ru_site
to: /app/ru_site
before: setup
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
add: /app/_main_site
to: /app/main_site/v{{ $Channel }}
before: setup
{{ end -}}
{{ range .WerfVersions -}}
{{ $VersionsDict := splitn "%" 2 . -}}
{{ $Channel := $VersionsDict._0 -}}
{{ $Version := $VersionsDict._1 -}}
- artifact: doc-{{ $Channel }}
add: /app/_ru_site
to: /app/ru_site/v{{ $Channel }}
before: setup
{{ end -}}De extra afbeelding, die samen met de hoofdafbeelding op de dev-circuit wordt gelanceerd, bevat slechts twee versies van de site: de versie van de review commit en de rootversie van de site (deze bevat gemeenschappelijke assets en, als je je herinnert, releasegegevens). De extra afbeelding verschilt dus alleen van de hoofdafbeelding in het importgedeelte (en natuurlijk ook in de naam):
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 }} Zoals hierboven vermeld, wordt het artefact voor de reviewcommit alleen gegenereerd wanneer de ingestelde omgevingsvariabele wordt uitgevoerd REVIEW_SHAHet zou mogelijk zijn om de werf-dev-image helemaal niet te genereren als er geen omgevingsvariabele is REVIEW_SHA, maar om Docker-images in werf werkten voor de werf-dev-image, we laten deze alleen bouwen met het root-versie-artefact (het is toch al gebouwd), om de pijplijnstructuur te vereenvoudigen.
De build is klaar! Laten we verder gaan met CI/CD en belangrijke details.
Pipeline in GitLab CI en functies van dynamische build
Bij het uitvoeren van de build moeten we de omgevingsvariabelen instellen die worden gebruikt in werf.yamlDit is niet van toepassing op de variabele REVIEW_SHA, die we instellen wanneer we de pijplijn aanroepen vanuit de GitHub-hook.
We verplaatsen de vorming van de benodigde externe gegevens naar een Bash-script generate_artifacts, die twee GitLab-pijplijnartefacten genereert:
- файл
releases.ymlmet vrijgavegegevens, - файл
common_envs.sh, die omgevingsvariabelen voor export bevat.
Bestand inhoud generate_artifacts vindt u in onze De dataverzameling zelf is niet het onderwerp van het artikel, maar het bestand common_envs.sh is belangrijk voor ons, omdat de werking van Werf ervan afhangt. Een voorbeeld van de inhoud:
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' De uitvoer van een dergelijk script kan bijvoorbeeld worden gebruikt met behulp van de Bash-functie source.
Nu komt het meest interessante deel. Om zowel de assemblage als de implementatie van de applicatie correct te laten verlopen, is het noodzakelijk om ervoor te zorgen dat: werf.yaml был hetzelfde minst binnen één pijpleidingAls aan deze voorwaarde niet wordt voldaan, zullen de fasehandtekeningen die werf berekent tijdens de assemblage en bijvoorbeeld de implementatie, anders zijn. Dit leidt tot een implementatiefout, omdat de voor de implementatie benodigde afbeelding ontbreekt.
Met andere woorden: als tijdens het samenstellen van de site-image de informatie over releases en versies gelijk is, en op het moment van implementatie een nieuwe versie uitkomt en de omgevingsvariabelen andere waarden hebben, dan eindigt de implementatie met een fout: het artefact van de nieuwe versie is immers nog niet samengesteld.
Als generatie werf.yaml Als een pijplijn afhankelijk is van externe gegevens (bijvoorbeeld een lijst met actuele versies, zoals in ons geval), dan moeten de samenstelling en waarden van die gegevens in de pijplijn worden vastgelegd. Dit is vooral belangrijk als externe parameters vaak veranderen.
Wij zullen externe gegevens ontvangen en registreren in de eerste fase van de pijplijn in GitLab (voorbouw) en ze verder in de vorm doorgeven GitLab CI-artefactenHiermee kunt u pijplijntaken (bouwen, implementeren, opschonen) uitvoeren en opnieuw starten met dezelfde configuratie in werf.yaml.
Inhoud van het podium voorbouw het dossier .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 weekMet vaste externe gegevens in het artefact kunt u bouwen en implementeren met behulp van de standaardfasen van de GitLab CI-pipeline: Build en Deploy. We starten de pipeline zelf met behulp van hooks uit de werf GitHub-repository (d.w.z. wanneer er wijzigingen zijn in de repository op GitHub). De gegevens hiervoor kunnen worden opgehaald uit de GitLab-projecteigenschappen in de sectie CI/CD-instellingen -> Pijplijntriggersen maak vervolgens de overeenkomstige webhook in GitHub (Instellingen -> Webhooks).
De bouwfase ziet er als volgt uit:
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 zal twee artefacten van de stage toevoegen aan de build stage voorbouw, dus we exporteren variabelen met voorbereide invoergegevens met behulp van de constructie source common_envs.shWe starten de build-fase in alle gevallen, behalve wanneer we de pijplijn volgens schema lanceren. Op schema lanceren we de pijplijn voor het opschonen - in dit geval is het niet nodig om de build uit te voeren.
In de implementatiefase beschrijven we twee taken - afzonderlijk voor implementatie naar productie- en dev-circuits, met behulp van een YAML-sjabloon:
.base_deploy: &base_deploy
stage: deploy
script:
- type multiwerf && . $(multiwerf use 1.0 alpha --as-file)
- type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
- source common_envs.sh
- werf deploy --stages-storage :local
dependencies:
- Prebuild
except:
refs:
- schedules
Deploy to Production:
<<: *base_deploy
variables:
WERF_KUBE_CONTEXT: prod
environment:
name: production
url: werf.io
only:
refs:
- master
except:
variables:
- $REVIEW_SHA
refs:
- schedules
Deploy to Test:
<<: *base_deploy
variables:
WERF_KUBE_CONTEXT: dev
environment:
name: test
url: werf.test.flant.com
except:
refs:
- schedules
only:
variables:
- $REVIEW_SHA De taken verschillen wezenlijk alleen in de aanduiding van de clustercontext waarin werf de implementatie moet uitvoeren (WERF_KUBE_CONTEXT), en het instellen van de contouromgevingsvariabelen (environment.name и environment.url), die vervolgens worden gebruikt in Helm-kaartsjablonen. We zullen de inhoud van de sjablonen niet verstrekken, aangezien er niets interessants is over het onderwerp, maar u kunt ze vinden in .
Laatste greep
Omdat werf-versies regelmatig worden uitgebracht, worden er regelmatig nieuwe images gemaakt en groeit het Docker-register voortdurend. Daarom is het noodzakelijk om automatische image cleaning op basis van beleid in te stellen. Dit is heel eenvoudig.
Voor de implementatie heeft u het volgende nodig:
- Voeg een reinigingsstap toe aan
.gitlab-ci.yml; - Voeg periodieke uitvoering van de schoonmaaktaak toe;
- Stel een omgevingsvariabele in met een schrijftoegangstoken.
Voeg een reinigingsfase toe aan .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
We hebben dit hierboven bijna allemaal al gezien. Om het op te schonen, moet je eerst inloggen op Docker Registry met een token dat rechten heeft om afbeeldingen in Docker Registry te verwijderen (het automatisch uitgegeven token van de GitLab CI-taak heeft dergelijke rechten niet). Het token moet vooraf in GitLab worden aangemaakt en de waarde ervan moet worden opgegeven in de omgevingsvariabele. WERF_IMAGES_CLEANUP_PASSWORD project (CI/CD-instellingen -> Variabelen).
Het toevoegen van een schoonmaaktaak met het vereiste schema gebeurt in CI/CD ->
Schema's.
Dat is alles: uw Docker Registry-project groeit niet langer voortdurend met ongebruikte images.
Ter afsluiting van het praktische gedeelte wil ik u eraan herinneren dat de volledige lijsten van het artikel beschikbaar zijn in :
- ;
- .
Resultaat
- We kregen een logische assemblagestructuur: één artefact per versie.
- De montage is universeel en vereist geen handmatige wijzigingen bij de release van een nieuwe versie van werf: de documentatie op de site wordt automatisch bijgewerkt.
- Er worden twee afbeeldingen verzameld voor verschillende contouren.
- Het werkt snel omdat caching maximaal wordt benut: wanneer een nieuwe versie van werf wordt uitgebracht of een GitHub-hook wordt aangeroepen voor een reviewcommit, wordt alleen het overeenkomstige artefact met de gewijzigde versie opnieuw opgebouwd.
- U hoeft zich geen zorgen te maken over het verwijderen van ongebruikte afbeeldingen: werf-beleidsgebaseerde opschoning zorgt ervoor dat uw Docker-register opgeruimd blijft.
Bevindingen
- Door werf te gebruiken, kan de build snel worden uitgevoerd, omdat zowel de build zelf als de cache worden opgeslagen bij het werken met externe opslagplaatsen.
- Door met externe Git-repositories te werken, vervalt de noodzaak om de repository elke keer volledig te klonen of het wiel opnieuw uit te vinden met lastige optimalisatielogica. Werf gebruikt een cache en kloont slechts één keer, en gebruikt vervolgens
fetchen alleen als het nodig is. - Mogelijkheid om Go-sjablonen te gebruiken in het buildconfiguratiebestand
werf.yamlHiermee kunt u een assemblage beschrijven waarvan het resultaat afhankelijk is van externe gegevens. - Het gebruik van mounting in werf versnelt het verzamelen van artefacten aanzienlijk - dankzij de cache, die gemeenschappelijk is voor alle pipelines.
- Met werf kunt u opschonen eenvoudig configureren, wat vooral belangrijk is bij dynamische builds.
PS
Lees ook op onze blog:
- «";
- «";
- «";
- «.
Bron: www.habr.com
