Kontenery usługi
Azure DevOps Services
Jeśli potok wymaga obsługi co najmniej jednej usługi, może być konieczne utworzenie, nawiązanie połączenia i wyczyszczenie usług na zadanie. Na przykład potok może uruchamiać testy integracji, które wymagają dostępu do nowo utworzonej bazy danych i pamięci podręcznej dla każdego zadania w potoku.
Kontener zapewnia prosty i przenośny sposób uruchamiania usługi, od którego zależy potok. Kontener usługi umożliwia automatyczne tworzenie, sieć i zarządzanie cyklem życia konteneryzowanej usługi. Każdy kontener usługi jest dostępny tylko dla zadania , które go wymaga. Kontenery usługi działają z dowolnym rodzajem zadania, ale są najczęściej używane z zadaniami kontenera.
Wymagania
Kontenery usługi muszą definiować element
CMD
lubENTRYPOINT
. Potok jest uruchamianydocker run
dla podanego kontenera bez żadnych argumentów.Usługa Azure Pipelines może uruchamiać kontenery systemu Linux lub Windows. Możesz użyć hostowanej puli kontenerów systemu Ubuntu dla kontenerów systemu Linux lub hostowanej puli systemu Windows dla kontenerów systemu Windows. Hostowana pula systemu macOS nie obsługuje uruchomionych kontenerów.
Uwaga
Kontenery usługi nie są obsługiwane w potokach klasycznych.
Jedno zadanie kontenera
Poniższa przykładowa definicja potoku YAML przedstawia jedno zadanie kontenera.
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
Powyższy potok pobiera nginx
kontenery i buildpack-deps
z usługi Docker Hub , a następnie uruchamia kontenery. Kontenery są połączone w sieć, aby mogły się ze sobą łączyć według ich services
nazwy.
Z poziomu tego kontenera nginx
zadań nazwa hosta jest rozpoznawana jako poprawne usługi przy użyciu sieci platformy Docker. Wszystkie kontenery w sieci automatycznie uwidaczniają sobie wszystkie porty.
Jedno zadanie niekontenerowe
Kontenery usług można również używać bez kontenera zadań, jak w poniższym przykładzie.
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
Poprzedni potok uruchamia najnowsze nginx
kontenery. Ponieważ zadanie nie jest uruchomione w kontenerze, nie ma automatycznego rozpoznawania nazw. Zamiast tego możesz uzyskać dostęp do usług przy użyciu polecenia localhost
. Przykład jawnie udostępnia 8080:80
port.
Alternatywną metodą jest dynamiczne przypisywanie losowego portu w czasie wykonywania. Następnie możesz uzyskać dostęp do tych portów dynamicznych przy użyciu zmiennych. Te zmienne mają postać: agent.services.<serviceName>.ports.<port>
. W skryscie powłoki Bash można uzyskać dostęp do zmiennych przy użyciu środowiska przetwarzania.
W poprzednim przykładzie redis
przypisano losowy dostępny port na hoście. Zmienna agent.services.redis.ports.6379
zawiera numer portu.
Wiele zadań
Kontenery usługi są również przydatne do uruchamiania tych samych kroków w wielu wersjach tej samej usługi. W poniższym przykładzie te same kroki są wykonywane względem wielu wersji bazy danych 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
Porty
Podczas wywoływania zasobu kontenera lub wbudowanego kontenera można określić tablicę ports
do uwidocznienia w kontenerze, jak w poniższym przykładzie.
resources:
containers:
- container: my_service
image: my_service:latest
ports:
- 8080:80
- 5432
services:
redis:
image: redis
ports:
- 6379/tcp
Określenie ports
nie jest wymagane, jeśli zadanie jest uruchomione w kontenerze, ponieważ kontenery w tej samej sieci platformy Docker automatycznie uwidaczniają wszystkie porty do siebie domyślnie.
Jeśli zadanie jest uruchomione na hoście, ports
wymagane jest uzyskanie dostępu do usługi. Port przyjmuje formularz <hostPort>:<containerPort>
lub po prostu <containerPort>
opcjonalny /<protocol>
na końcu. Na przykład 6379/tcp
uwidacznia tcp
port 6379
, powiązany z losowym portem na maszynie hosta.
W przypadku portów powiązanych z losowym portem na maszynie hosta potok tworzy zmienną formularza agent.services.<serviceName>.ports.<port>
, dzięki czemu zadanie może uzyskać dostęp do portu. Na przykład agent.services.redis.ports.6379
jest rozpoznawany losowo przypisany port na maszynie hosta.
Woluminy
Woluminy są przydatne do udostępniania danych między usługami lub utrwalania danych między wieloma przebiegami zadania. Woluminy są określane jako tablica volumes
formularza <source>:<destinationPath>
, gdzie <source>
może być nazwanym woluminem lub ścieżką bezwzględną na maszynie hosta i <destinationPath>
jest ścieżką bezwzględną w kontenerze. Woluminy mogą mieć nazwę Woluminy platformy Docker, anonimowe woluminy platformy Docker lub powiązane instalacje na hoście.
services:
my_service:
image: myservice:latest
volumes:
- mydockervolume:/data/dir
- /data/dir
- /src/dir:/dst/dir
Uwaga
Jeśli używasz pul hostowanych przez firmę Microsoft, woluminy nie są utrwalane między zadaniami, ponieważ maszyna hosta jest czyszczona po zakończeniu każdego zadania.
Opcje uruchamiania
Kontenery usługi współdzielą te same zasoby kontenera co zadania kontenera. Oznacza to, że można użyć tych samych opcji uruchamiania.
Sprawdzanie kondycji
Jeśli jakikolwiek kontener usługi określa HEALTHCHECK, agent może opcjonalnie poczekać, aż kontener będzie w dobrej kondycji przed uruchomieniem zadania.
Przykład wielu kontenerów z usługami
Poniższy przykład zawiera kontener internetowy Django Python połączony z kontenerami baz danych PostgreSQL i MySQL.
- Baza danych PostgreSQL jest podstawową bazą danych, a jej kontener nosi nazwę
db
. - Kontener
db
używa woluminu/data/db:/var/lib/postgresql/data
i istnieją trzy zmienne bazy danych przekazywane do kontenera za pośrednictwem poleceniaenv
. - Kontener
mysql
używa portu3306:3306
i istnieją również zmienne bazy danych przekazywane za pośrednictwem poleceniaenv
. - Kontener
web
jest otwarty z portem8000
.
W krokach zainstaluje zależności, pip
a następnie uruchomi testy Django.
Aby skonfigurować działający przykład, musisz skonfigurować witrynę Django z dwoma bazami danych. W przykładzie przyjęto założenie, że plik manage.py znajduje się w katalogu głównym, a projekt Django znajduje się również w tym katalogu. Jeśli nie, może być konieczne zaktualizowanie ścieżki /__w/1/s/
w pliku /__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