Servicecontainers
Azure DevOps Services
Als uw pijplijn ondersteuning van een of meer services vereist, wilt u in veel gevallen elke service per taak maken, verbinden en opschonen. Een pijplijn kan bijvoorbeeld integratietests uitvoeren waarvoor toegang tot een database en een geheugencache is vereist. De database en geheugencache moeten nieuw worden gemaakt voor elke taak in de pijplijn.
Een container biedt een eenvoudige en draagbare manier om een service uit te voeren waarvan uw pijplijn afhankelijk is. Met een servicecontainer kunt u automatisch de levenscyclus van uw containerservice maken, netwerken en beheren. Elke servicecontainer is alleen toegankelijk voor de taak waarvoor deze is vereist. Servicecontainers werken met elk type taak, maar ze worden het meest gebruikt met containertaken.
Vereisten
Servicecontainers moeten een CMD
of ENTRYPOINT
definiëren.
De pijplijn wordt zonder extra argumenten uitgevoerd docker run
voor de opgegeven container.
Azure Pipelines kan Linux- of Windows-containers uitvoeren. Gebruik gehoste Ubuntu voor Linux-containers of de gehoste Windows-containergroep voor Windows-containers. (De gehoste macOS-pool biedt geen ondersteuning voor actieve containers.)
Taak met één container
Een eenvoudig voorbeeld van het gebruik van containertaken:
resources:
containers:
- container: my_container
image: buildpack-deps:focal
- container: nginx
image: nginx
pool:
vmImage: 'ubuntu-latest'
container: my_container
services:
nginx: nginx
steps:
- script: |
curl nginx
displayName: Show that nginx is running
Deze pijplijn haalt de nginx
containers en buildpack-deps
op uit Docker Hub en start vervolgens de containers. De containers zijn aan elkaar gekoppeld, zodat ze elkaar op hun services
naam kunnen bereiken.
Vanuit deze taakcontainer wordt de nginx
hostnaam omgezet in de juiste services met behulp van Docker-netwerken.
Alle containers in het netwerk maken alle poorten automatisch beschikbaar voor elkaar.
Eén taak
U kunt ook servicecontainers zonder taakcontainer gebruiken. Een eenvoudig voorbeeld:
resources:
containers:
- container: nginx
image: nginx
ports:
- 8080:80
env:
NGINX_PORT: 80
- container: redis
image: redis
ports:
- 6379
pool:
vmImage: 'ubuntu-latest'
services:
nginx: nginx
redis: redis
steps:
- script: |
curl localhost:8080
echo $AGENT_SERVICES_REDIS_PORTS_6379
Met deze pijplijn worden de meest recente nginx
containers gestart. Omdat de taak niet wordt uitgevoerd in een container, is er geen automatische naamomzetting.
In dit voorbeeld ziet u hoe u in plaats daarvan services kunt bereiken met behulp van localhost
.
In het bovenstaande voorbeeld geven we de poort expliciet op (bijvoorbeeld 8080:80
).
Een alternatieve benadering is om een willekeurige poort dynamisch te laten toewijzen tijdens runtime. U kunt deze dynamische poorten vervolgens openen met behulp van variabelen.
In een Bash-script hebt u toegang tot een variabele met behulp van de procesomgeving. Deze variabelen hebben de vorm: agent.services.<serviceName>.ports.<port>
.
In het bovenstaande voorbeeld redis
krijgt een willekeurige beschikbare poort op de host toegewezen.
De agent.services.redis.ports.6379
variabele bevat het poortnummer.
Meerdere taken
Servicecontainers zijn ook handig voor het uitvoeren van dezelfde stappen voor meerdere versies van dezelfde service. In het volgende voorbeeld worden dezelfde stappen uitgevoerd voor meerdere versies van PostgreSQL.
resources:
containers:
- container: my_container
image: ubuntu:22.04
- container: pg15
image: postgres:15
- container: pg14
image: postgres:14
pool:
vmImage: 'ubuntu-latest'
strategy:
matrix:
postgres15:
postgresService: pg15
postgres14:
postgresService: pg14
container: my_container
services:
postgres: $[ variables['postgresService'] ]
steps:
- script: printenv
Poorten
Wanneer u een containerresource of een inlinecontainer opgeeft, kunt u een matrix van ports
opgeven voor de container.
resources:
containers:
- container: my_service
image: my_service:latest
ports:
- 8080:80
- 5432
services:
redis:
image: redis
ports:
- 6379/tcp
ports
Opgeven is niet vereist als uw taak wordt uitgevoerd in een container, omdat containers in hetzelfde Docker-netwerk standaard automatisch alle poorten aan elkaar blootstellen.
Als uw taak wordt uitgevoerd op de host, ports
moet u toegang krijgen tot de service. Een poort heeft de vorm <hostPort>:<containerPort>
of alleen <containerPort>
, met een optionele /<protocol>
aan het einde, bijvoorbeeld 6379/tcp
om beschikbaar te maken tcp
via poort 6379
, gebonden aan een willekeurige poort op de hostcomputer.
Voor poorten die zijn gebonden aan een willekeurige poort op de hostcomputer, maakt de pijplijn een variabele van de vorm agent.services.<serviceName>.ports.<port>
, zodat deze kan worden geopend door de taak. Wordt bijvoorbeeld agent.services.redis.ports.6379
omgezet in de willekeurig toegewezen poort op de hostcomputer.
Volumes
Volumes zijn handig voor het delen van gegevens tussen services of voor het persistent maken van gegevens tussen meerdere uitvoeringen van een taak.
U kunt volumekoppelingen opgeven als een matrix van volumes
. Volumes kunnen de naam Docker-volumes, anonieme Docker-volumes of bindingskoppelingen op de host hebben.
services:
my_service:
image: myservice:latest
volumes:
- mydockervolume:/data/dir
- /data/dir
- /src/dir:/dst/dir
Volumes hebben de vorm <source>:<destinationPath>
, waarbij <source>
een benoemd volume of een absoluut pad op de hostcomputer kan zijn en <destinationPath>
een absoluut pad in de container is.
Notitie
Als u onze gehoste pools gebruikt, blijven uw volumes niet behouden tussen taken omdat de hostcomputer wordt opgeschoond nadat de taak is voltooid.
Andere opties
Servicecontainers delen dezelfde containerresources als containertaken. Dit betekent dat u dezelfde extra opties kunt gebruiken.
Statuscontrole
Als een servicecontainer een STATUSCONTROLE opgeeft, wacht de agent optioneel totdat de container in orde is voordat de taak wordt uitgevoerd.
Voorbeeld van meerdere containers met services
In dit voorbeeld is er een Django Python-webcontainer verbonden met twee databasecontainers: PostgreSQL en MySQL. De PostgreSQL-database is de primaire database en de container heeft de naam db
. De db
container maakt gebruik van volume /data/db:/var/lib/postgresql/data
en er worden drie databasevariabelen aan de container doorgegeven via env
. De mysql
container maakt gebruik van poort 3306:3306
en er worden ook databasevariabelen doorgegeven via env
. De web
container is geopend met poort 8000
. In de stappen pip
installeert u afhankelijkheden en vervolgens wordt de Django-test uitgevoerd. Als u een werkend voorbeeld wilt instellen, moet u een Django-site instellen met twee databases. In dit voorbeeld wordt ervan uitgegaan dat uw manage.py
bestand zich in de hoofdmap bevindt en uw Django-project zich in die map bevindt. Mogelijk moet u het /__w/1/s/
pad bijwerken in /__w/1/s/manage.py test
.
resources:
containers:
- container: db
image: postgres
volumes:
- '/data/db:/var/lib/postgresql/data'
env:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
- container: mysql
image: 'mysql:5.7'
ports:
- '3306:3306'
env:
MYSQL_DATABASE: users
MYSQL_USER: mysql
MYSQL_PASSWORD: mysql
MYSQL_ROOT_PASSWORD: mysql
- container: web
image: python
volumes:
- '/code'
ports:
- '8000:8000'
pool:
vmImage: 'ubuntu-latest'
container: web
services:
db: db
mysql: mysql
steps:
- script: |
pip install django
pip install psycopg2
pip install mysqlclient
displayName: set up django
- script: |
python /__w/1/s/manage.py test
Feedback
https://aka.ms/ContentUserFeedback.
Binnenkort: Gedurende 2024 worden GitHub Issues uitgefaseerd als het feedbackmechanisme voor inhoud. Dit wordt vervangen door een nieuw feedbacksysteem. Ga voor meer informatie naar:Feedback verzenden en bekijken voor