Tjänstcontainrar
Azure DevOps Services
Om din pipeline kräver stöd för en eller flera tjänster kan du behöva skapa, ansluta till och rensa tjänsterna per jobb. Din pipeline kan till exempel köra integreringstester som kräver åtkomst till en nyligen skapad databas och minnescachen för varje jobb i pipelinen.
En container är ett enkelt och bärbart sätt att köra en tjänst som din pipeline är beroende av. Med en tjänstcontainer kan du automatiskt skapa, nätverka och hantera livscykeln för en containerbaserad tjänst. Varje tjänstcontainer är endast tillgänglig för det jobb som kräver det. Tjänstcontainrar fungerar med alla typer av jobb, men används oftast med containerjobb.
Krav
Tjänstcontainrar måste definiera en
CMD
ellerENTRYPOINT
. Pipelinen körsdocker run
för den angivna containern utan argument.Azure Pipelines kan köra Linux- eller Windows-containrar. Du kan använda antingen den värdbaserade Ubuntu-containerpoolen för Linux-containrar eller den värdbaserade Windows-poolen för Windows-containrar. Den värdbaserade macOS-poolen stöder inte containrar som körs.
Kommentar
Tjänstcontainrar stöds inte i klassiska pipelines.
Jobb med en enda container
I följande exempel visar YAML-pipelinedefinitionen ett enda containerjobb.
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
Den föregående pipelinen hämtar containrarna nginx
och buildpack-deps
från Docker Hub och startar sedan containrarna. Containrarna är sammankopplade i nätverk så att de kan nå varandra med deras services
namn.
Inifrån den här jobbcontainern nginx
matchas värdnamnet till rätt tjänster med hjälp av Docker-nätverk. Alla containrar i nätverket exponerar automatiskt alla portar för varandra.
Ett enda icke-kontainerjobb
Du kan också använda tjänstcontainrar utan en jobbcontainer, som i följande exempel.
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
Den föregående pipelinen startar de senaste nginx
containrarna. Eftersom jobbet inte körs i en container finns det ingen automatisk namnmatchning. I stället kan du nå tjänster med hjälp localhost
av . Exemplet innehåller uttryckligen 8080:80
porten.
En annan metod är att låta en slumpmässig port tilldelas dynamiskt vid körning. Du kan sedan komma åt dessa dynamiska portar med hjälp av variabler. Dessa variabler har formatet : agent.services.<serviceName>.ports.<port>
. I ett Bash-skript kan du komma åt variabler med hjälp av processmiljön.
I föregående exempel redis
tilldelas en slumpmässig tillgänglig port på värden. Variabeln agent.services.redis.ports.6379
innehåller portnumret.
Flera jobb
Tjänstcontainrar är också användbara för att köra samma steg mot flera versioner av samma tjänst. I följande exempel körs samma steg mot flera versioner av 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
Hamnar
När du anropar en containerresurs eller en infogad container kan du ange en matris ports
med som ska exponeras för containern, som i följande exempel.
resources:
containers:
- container: my_service
image: my_service:latest
ports:
- 8080:80
- 5432
services:
redis:
image: redis
ports:
- 6379/tcp
Det krävs inte att ports
du anger om jobbet körs i en container, eftersom containrar i samma Docker-nätverk automatiskt exponerar alla portar för varandra som standard.
Om jobbet körs på värden ports
måste du komma åt tjänsten. En port tar formuläret <hostPort>:<containerPort>
eller bara <containerPort>
med ett valfritt /<protocol>
i slutet. Till exempel 6379/tcp
exponeras tcp
via port 6379
, bunden till en slumpmässig port på värddatorn.
För portar som är bundna till en slumpmässig port på värddatorn skapar pipelinen en variabel i formuläret agent.services.<serviceName>.ports.<port>
så att jobbet kan komma åt porten. Till exempel agent.services.redis.ports.6379
matchar den slumpmässigt tilldelade porten på värddatorn.
Volymer
Volymer är användbara för att dela data mellan tjänster eller för att bevara data mellan flera körningar av ett jobb. Du anger volymmonteringar som en matris i volumes
formuläret <source>:<destinationPath>
, där <source>
kan vara en namngiven volym eller en absolut sökväg på värddatorn och <destinationPath>
är en absolut sökväg i containern. Volymer kan namnges Docker-volymer, anonyma Docker-volymer eller bindningsmonteringar på värden.
services:
my_service:
image: myservice:latest
volumes:
- mydockervolume:/data/dir
- /data/dir
- /src/dir:/dst/dir
Kommentar
Om du använder Microsoft-värdbaserade pooler sparas inte dina volymer mellan jobb eftersom värddatorn rensas när varje jobb har slutförts.
Startalternativ
Tjänstcontainrar delar samma containerresurser som containerjobb. Det innebär att du kan använda samma startalternativ.
Hälsokontroll
Om någon tjänstcontainer anger en HEALTHCHECK kan agenten eventuellt vänta tills containern är felfri innan jobbet körs.
Exempel på flera containrar med tjänster
I följande exempel finns en Django Python-webbcontainer ansluten till PostgreSQL- och MySQL-databascontainrar.
- PostgreSQL-databasen är den primära databasen och dess container heter
db
. - Containern
db
använder volymen/data/db:/var/lib/postgresql/data
, och det finns tre databasvariabler som skickas till containern viaenv
. - Containern
mysql
använder port3306:3306
, och det finns även databasvariabler som skickas viaenv
. - Containern
web
är öppen med port8000
.
I stegen pip
installerar du beroenden och sedan körs Django-tester.
Om du vill konfigurera ett fungerande exempel behöver du en Django-webbplats som har konfigurerats med två databaser. Exemplet förutsätter att din manage.py-fil finns i rotkatalogen och att Django-projektet också finns i den katalogen. Annars kan du behöva uppdatera /__w/1/s/
sökvägen i /__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