服务容器
Azure DevOps Services
如果管道需要一个或多个服务的支持,在许多情况下,需要按作业创建、连接和清理每个服务。 例如,管道可以运行需要访问数据库和内存缓存的集成测试。 需要为管道中的每个作业重新创建数据库和内存缓存。
容器提供了一种简单且可移植的方式来运行管道所依赖的服务。 使用服务容器可以自动创建、联网和管理容器化服务的生命周期。 每个服务容器只能由需要它的作业访问。 服务容器适用于任何类型的作业,但它们最常用于容器作业。
要求
服务容器必须定义 CMD
或 ENTRYPOINT
。
管道将为提供的容器运行 docker run
,而无需其他参数。
Azure Pipelines 可以运行 Linux 或 Windows 容器。 使用适用于 Linux 容器的托管 Ubuntu,或使用适用于 Windows 容器的托管 Windows 容器池。 (托管 macOS 池不支持运行 containers。)
单个容器作业
使用 容器作业的简单示例:
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
此管道从 Docker Hub 提取 nginx
和 buildpack-deps
容器,然后启动容器。 容器联网在一起,以便可以按名称 services
相互访问。
在此作业容器内部, nginx
主机名使用 Docker 网络解析为正确的服务。
网络上的所有容器会自动向对方公开所有端口。
单个作业
还可以在没有作业容器的情况下使用服务容器。 一个简单的示例:
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
此管道启动最新的 nginx
容器。 由于作业未在容器中运行,因此没有自动名称解析。
此示例演示如何改为使用 localhost
访问服务。
在上面的示例中,我们显式 (提供端口, 8080:80
例如,) 。
另一种方法是在运行时动态分配随机端口。 然后,可以使用 变量访问这些动态端口。
在 Bash 脚本中,可以使用进程环境访问变量。 这些变量采用以下形式: agent.services.<serviceName>.ports.<port>
。
在上面的示例中, redis
在主机上分配了一个随机可用端口。
变量 agent.services.redis.ports.6379
包含端口号。
多个作业
对于针对同一服务的多个版本运行相同的步骤,服务容器也很有用。 在以下示例中,相同的步骤针对多个版本的 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
端口
指定容器资源或内联容器时,可以指定要在容器上公开的 ports
数组。
resources:
containers:
- container: my_service
image: my_service:latest
ports:
- 8080:80
- 5432
services:
redis:
image: redis
ports:
- 6379/tcp
ports
如果作业在容器中运行,则不需要指定 ,因为同一 Docker 网络上的容器默认会自动向彼此公开所有端口。
如果作业在主机上运行,则需要 ports
访问服务。 端口采用 形式<hostPort>:<containerPort>
或仅<containerPort>
采用 ,末尾为可选/<protocol>
,例如6379/tcp
通过端口 6379
公开 tcp
,绑定到主机上的随机端口。
对于绑定到主机上的随机端口的端口,管道会创建 形式的 agent.services.<serviceName>.ports.<port>
变量,以便作业可以访问该变量。 例如, agent.services.redis.ports.6379
解析为主机上随机分配的端口。
卷
卷可用于在服务之间共享数据,或用于在作业的多个运行之间保留数据。
可以将卷装载指定为 的 volumes
数组。 卷可以命名为 Docker 卷、匿名 Docker 卷或主机上的绑定装载。
services:
my_service:
image: myservice:latest
volumes:
- mydockervolume:/data/dir
- /data/dir
- /src/dir:/dst/dir
卷采用 的形式 <source>:<destinationPath>
,其中 <source>
可以是主机上的命名卷或绝对路径,是 <destinationPath>
容器中的绝对路径。
注意
如果使用托管池,则不会在作业之间保留卷,因为在作业完成后会清理主机。
其他选项
服务容器与容器作业共享相同的容器资源。 这意味着可以使用相同的 附加选项。
Healthcheck
(可选)如果任何服务容器指定 了 HEALTHCHECK,则代理将等待容器正常运行,然后再运行作业。
包含服务的多个容器示例
在此示例中,有一个 Django Python Web 容器连接到两个数据库容器 - PostgreSQL 和 MySQL。 PostgreSQL 数据库是主数据库,其容器的名称 db
为 。 容器 db
使用卷 /data/db:/var/lib/postgresql/data
,并且有三个数据库变量通过 env
传递给容器。 容器 mysql
使用端口 3306:3306
,并且还有通过 env
传递的数据库变量。 容器 web
使用端口 8000
打开。 在步骤中, pip
安装依赖项,然后运行 Django 测试。 如果要设置一个工作示例,则需要使用 两个数据库设置 Django 站点。 此示例假定文件 manage.py
位于根目录中,而 Django 项目在该目录中。 可能需要更新 /__w/1/s/
中的 /__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
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈