Docker-afbeeldingen bouwen in een GitLab CI-pijplijn

0
29

Een veelvoorkomend gebruik voor CI-pipelines is het bouwen van de Docker-images die u nodig hebt ;ll gebruiken om uw toepassing te implementeren. GitLab CI is hiervoor een uitstekende keuze omdat het een geïntegreerde pull-proxyservice ondersteunt, wat snellere pijplijnen betekent, en een ingebouwd register om uw ingebouwde afbeeldingen op te slaan.

In deze handleiding laten we u zien hoe u Docker-builds instelt die beide bovenstaande functies gebruiken. De stappen die u moet nemen, variëren enigszins, afhankelijk van het GitLab Runner-uitvoerdertype dat u voor uw pijplijn zult gebruiken. We zullen de Shell- en Docker-uitvoerders hieronder behandelen.

Bouwen met de Shell Executor

Als u’ als u de Shell-uitvoerder gebruikt, moet u ervoor zorgen dat Docker is geïnstalleerd op de machine waarop uw runner wordt gehost. De uitvoerder werkt door reguliere shell-opdrachten uit te voeren met behulp van het docker-binaire bestand op de host van Runner.

Ga naar de Git-repository voor het project waarvoor je afbeeldingen wilt maken. Maak een .gitlab-ci.yml-bestand in de hoofdmap van de repository. Dit bestand definieert de GitLab CI-pipeline die wordt uitgevoerd wanneer u wijzigingen in uw project pusht.

Voeg de volgende inhoud toe aan het bestand:

stages: – build docker_build: stage: build script: – docker build -t voorbeeld.com/voorbeeld-afbeelding:laatste . – docker push voorbeeld.com/voorbeeld-afbeelding:laatste

Deze simplistische configuratie is voldoende om de basisprincipes van door pijpleidingen aangedreven image-builds te demonstreren. GitLab kloont automatisch je Git-repository in de build-omgeving, dus het uitvoeren van docker build zal het Dockerfile van je project gebruiken en de inhoud van de repository beschikbaar maken als de build-context.

Advertentie

Daarna de build is voltooid, kunt u de afbeelding naar uw register door Docker pushen. Anders zou het alleen beschikbaar zijn voor de lokale Docker-installatie die de build uitvoerde. Als u een privéregister gebruikt, voert u eerst docker-login uit om de juiste authenticatiegegevens op te geven:

script: – docker-login -u $DOCKER_REGISTRY_USER -p $DOCKER_REGISTRY_PASSWORD

Definieer de waarden van de twee referentievariabelen door naar Instellingen > CI/CD > Variabelen in de GitLab-webgebruikersinterface. Klik op de blauwe “Variabele toevoegen” om een ​​nieuwe variabele te maken en een waarde toe te wijzen. GitLab maakt deze variabelen beschikbaar in de shell-omgeving die wordt gebruikt om uw taak uit te voeren.

Bouwen met de Docker Executor

GitLab Runner's Docker-executor wordt vaak gebruikt om voor elke taak een volledig schone omgeving te bieden. De taak wordt uitgevoerd in een geïsoleerde container, zodat het docker-binaire bestand op de Runner-host niet toegankelijk is.

De Docker-uitvoerder geeft je twee mogelijke strategieën voor het bouwen van je image: gebruik Docker-in-Docker of bind de Docker-socket van de host in de build-omgeving van Runner. Vervolgens gebruikt u de officiële Docker-containerafbeelding als de afbeelding van uw taak, waardoor het docker-commando beschikbaar is in uw CI-script.

Docker-in-Docker

Docker-in-Docker

h3>

Het gebruik van Docker-in-Docker (DinD) om uw afbeeldingen te bouwen, geeft u een volledig geïsoleerde omgeving voor elke taak. Het Docker-proces dat de build uitvoert, is een onderliggend element van de container die GitLab Runner op de host maakt om de CI-taak uit te voeren.

U moet uw GitLab Runner Docker-uitvoerder registreren met de bevoorrechte modus ingeschakeld om DinD te gebruiken . Voeg de –docker-privileged vlag toe wanneer u uw hardloper registreert:

sudo gitlab-runner register -n –url https://example.com –registration-token $GITLAB_REGISTRATION_TOKEN –executor docker –description “Docker Runner” –docker-image “docker:20.10” –docker-volumes “/certs/client” –docker-privileged Advertentie

Voeg binnen uw CI-pijplijn de docker:dind-afbeelding toe als een service. Dit maakt Docker beschikbaar als een afzonderlijke afbeelding die is gekoppeld aan de afbeelding van de taak. U kunt het docker-commando gebruiken om afbeeldingen te bouwen met behulp van de Docker-instantie in de docker:dind container.

services: – docker:dind docker_build: stage: build image: docker:latest script: – docker build -t voorbeeld-afbeelding:laatste .

Het gebruik van DinD geeft je volledig geïsoleerde builds die elkaar of je host niet kunnen beïnvloeden. Het grootste nadeel is het ingewikkelder caching-gedrag: elke taak krijgt een nieuwe omgeving waar eerder gebouwde lagen niet toegankelijk zijn. Je kunt dit gedeeltelijk oplossen door te proberen de vorige versie van je afbeelding op te halen voordat je gaat bouwen, en vervolgens de –cache-from build-vlag te gebruiken om de lagen van de getrokken afbeelding beschikbaar te maken als een cachebron:

docker_build : stage: build image: docker:laatste script: – docker pull $CI_REGISTRY_IMAGE:nieuwste || true – docker build –cache-from $CI_REGISTRY_IMAGE:laatste -t ​​$CI_REGISTRY_IMAGE:laatste .

Socket-bindbevestigingen

Het monteren van de Docker-socket van uw host in de omgeving van uw taak is een alternatieve optie wanneer u de Docker-uitvoerder gebruikt. Dit geeft u naadloze caching en maakt het niet nodig om de docker:dind-service aan uw CI-configuratie toe te voegen.

Om dit in te stellen, registreert u uw Runner met een docker-volumes-vlag die de host's bindt Docker-socket naar /var/run/docker.sock in taakcontainers:

sudo gitlab-runner register -n –url https://example.com –registration-token $GITLAB_REGISTRATION_TOKEN –executor docker –description “Docker Runner” –docker-image “docker:20.10” –docker-volumes /var/run/docker.sock:/var/run/docker.sock

Nu kunnen jobs die draaien met de docker-image het docker-binaire bestand normaal gebruiken. Bewerkingen zullen daadwerkelijk plaatsvinden op uw hostcomputer en worden broers en zussen van de taakcontainer in plaats van kinderen.

Dit is in feite vergelijkbaar met het gebruik van de shell-uitvoerder met de Docker-installatie van uw host. Afbeeldingen blijven op de host staan, waardoor naadloos gebruik van reguliere docker-buildlaagcaching mogelijk wordt.

Advertentie

Hoewel deze aanpak kan leiden tot hogere prestaties, minder configuratie en geen van de beperkingen van DinD, heeft het zijn eigen unieke problemen. De meest prominente hiervan zijn de beveiligingsimplicaties: taken kunnen willekeurige Docker-opdrachten uitvoeren op uw Runner-host, dus een kwaadaardig project in uw GitLab-instantie kan docker run -it kwaadaardige-image:latest of docker rm -f $(docker ps -a ) met verwoestende gevolgen.

GitLab waarschuwt ook dat socketbinding problemen kan veroorzaken wanneer taken gelijktijdig worden uitgevoerd. Dit gebeurt wanneer u erop vertrouwt dat containers met specifieke namen worden gemaakt. Als twee instanties van een taak parallel lopen, zal de tweede mislukken omdat de containernaam al op uw host bestaat.

U zou moeten overwegen om in plaats daarvan DinD te gebruiken als u verwacht dat een van deze problemen lastig zal zijn. Hoewel DinD niet langer algemeen wordt aanbevolen, kan het zinvoller zijn voor openbare GitLab-instanties die gelijktijdige CI-taken uitvoeren.

Afbeeldingen naar GitLab's register pushen

GitLab-projecten hebben de optie van een geïntegreerd register dat u kunt gebruiken om uw afbeeldingen op te slaan. U kunt de inhoud van het register bekijken door naar Pakketten & registers > Containerregister in de zijbalk van uw project. Als u deze link niet ziet, schakelt u het register in door naar Instellingen > Algemeen > Zichtbaarheid, Project, Functies & Machtigingen en het activeren van het “Containerregister” schakelen.

 

GitLab stelt automatisch omgevingsvariabelen in uw CI-taken in waarmee u kunt verwijzen naar het containerregister van uw project. Pas de scriptsectie aan om in te loggen op het register en push uw afbeelding:

script: – docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY – docker build -t $CI_REGISTRY_IMAGE:latest . – docker push $CI_REGISTRY_IMAGE:laatste

GitLab genereert een veilige set referenties voor elk van uw CI-taken. De omgevingsvariabele $CI_JOB_TOKEN bevat een toegangstoken dat de taak kan gebruiken om verbinding te maken met het register als de gitlab-ci-token-gebruiker. De URL van de registerserver is beschikbaar als $CI_REGISTRY.

Advertentie

De laatste variabele, $CI_REGISTRY_IMAGE, biedt het volledige pad naar het containerregister van uw project. Dit is een geschikte basis voor uw afbeeldingstags. U kunt deze variabele uitbreiden om subrepositories te maken, zoals $CI_REGISTRY_IMAGE/production/api:latest.

 

Andere Docker-clients kunnen afbeeldingen uit het register halen door te verifiëren met behulp van een toegangstoken. U kunt deze genereren in de instellingen van uw project > Toegang tokens scherm. Voeg het read_registry-bereik toe en gebruik vervolgens de weergegeven inloggegevens om in te loggen in het register van uw project.

De afhankelijkheidsproxy van GitLab gebruiken

h2>

De Dependency Proxy van GitLab biedt een caching-laag voor de upstream-afbeeldingen die u uit Docker Hub haalt. Het helpt je binnen de snelheidslimieten van Docker Hub te blijven door alleen de inhoud van afbeeldingen op te halen wanneer ze daadwerkelijk zijn gewijzigd. Dit zal ook de prestaties van uw builds verbeteren.

De afhankelijkheidsproxy wordt geactiveerd op GitLab-groepsniveau door naar Instellingen > Pakketten & registers > Afhankelijkheidsproxy. Zodra het is ingeschakeld, voeg je de afbeeldingsreferenties in je .gitlab-ci.yml-bestand toe met $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX om ze door de proxy te halen:

docker_build: stage: build image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:latest services: naam: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/docker:dind alias: docker

Dat is alles! GitLab Runner logt automatisch in op het afhankelijkheidsproxyregister, dus het is niet nodig om uw inloggegevens handmatig op te geven.

GitLab slaat nu uw afbeeldingen in de cache op, waardoor u betere prestaties krijgt en beter bestand bent tegen netwerkstoringen. Merk op dat ook de dienstendefinitie moest worden aangepast – omgevingsvariabelen werken niet met het eerder gebruikte inline-formulier, dus de volledige afbeeldingsnaam moet worden opgegeven en vervolgens een opdrachtalias om naar te verwijzen in uw scriptsectie.

Advertentie

Hoewel we nu de proxy hebben ingesteld voor afbeeldingen die rechtstreeks worden gebruikt door onze taakfasen, was er meer werk nodig om ondersteuning toe te voegen voor de basisafbeelding in de Dockerfile om te bouwen. Een normale instructie als deze gaat niet door de proxy:

FROM ubuntu:latest

Om dit laatste stuk toe te voegen, gebruikt u de build-argumenten van Docker om de afhankelijkheidsproxy-URL beschikbaar te maken wanneer u er doorheen stapt de Dockerfile:

ARG GITLAB_DEPENDENCY_PROXY FROM ${GITLAB_DEPENDENCY_PROXY}/ubuntu:latest

Wijzig vervolgens uw docker-buildopdracht om de waarde van de variabele te definiëren:

script: > – docker build –build-arg GITLAB_DEPENDENCY_PROXY=${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX} -t voorbeeld-image:laatste .

Nu wordt uw basisimage ook door de afhankelijkheidsproxy gehaald.

Samenvatting

Docker-image-builds kunnen eenvoudig worden geïntegreerd in uw GitLab CI-pipelines. Na de initiële Runner-configuratie zijn de docker-build- en docker-push-commando's in de scriptsectie van uw taak alles wat u nodig hebt om een ​​afbeelding te maken met de Dockerfile in uw repository. Het ingebouwde containerregister van GitLab geeft u privéopslag voor de afbeeldingen van uw project.

Naast de basisversies is het de moeite waard om GitLab's afhankelijkheidsproxy te integreren om de prestaties te versnellen en te voorkomen dat de snelheidslimieten van Docker Hub worden bereikt. U moet ook de beveiliging van uw installatie controleren door te beoordelen of uw geselecteerde methode toestaat dat niet-vertrouwde projecten opdrachten uitvoeren op uw Runner-host. Hoewel het zijn eigen problemen met zich meebrengt, is Docker-in-Docker de veiligste benadering wanneer uw GitLab-instantie openbaar toegankelijk is of toegankelijk is voor een groot aantal gebruikers.