相关文章推荐
失恋的牙膏  ·  从终端运行python程序 ...·  11 月前    · 
笑点低的松球  ·  爆!Windows ...·  1 年前    · 
焦虑的脸盆  ·  oracle ...·  1 年前    · 
有胆有识的鼠标垫  ·  how can I translate ...·  1 年前    · 

Azure DevOps Services

如果管道需要一个或多个服务的支持,则可能需要创建、连接到每个作业并清理每个作业的服务。 例如,管道可能会运行集成测试,这些测试需要访问管道中每个作业的新创建的数据库和内存缓存。

容器 提供了一种简单且可移植的方式来运行管道所依赖的服务。 使用服务容器 ,可以自动创建、网络和管理容器化服务的生命周期。 每个服务容器只能访问 需要它的作业 。 服务容器适用于任何类型的作业,但最常与容器作业 一起使用

  • 服务容器必须定义 CMD ENTRYPOINT 。 管道针对提供的容器运行 docker run ,没有任何参数。

  • Azure Pipelines 可以运行 Linux 或 Windows 容器 。 可以将托管的 Ubuntu 容器池用于 Linux 容器,也可以使用适用于 Windows 容器的托管 Windows 池。 托管的 macOS 池不支持运行容器。

    经典管道不支持服务容器。

    单容器作业

    以下示例 YAML 管道定义显示了单个容器作业。

    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 中心提取nginx容器,buildpack-deps然后启动容器。 容器联网,因此容器可以通过其 services 名称相互访问。

    在此作业容器内部, nginx 主机名使用 Docker 网络解析为正确的服务。 网络上的所有容器会自动向对方公开所有端口。

    单个非容器作业

    还可以在没有作业容器的情况下使用服务容器,如以下示例所示。

    resources:
      containers:
      - container: nginx
        image: nginx
        ports:
        - 8080:80
          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 容器。 由于作业未在容器中运行,因此没有自动名称解析。 相反,可以使用 < a0/a0> 访问服务 localhost。 该示例显式提供 8080:80 端口。

    另一种方法是在运行时动态分配随机端口。 然后,可以使用变量访问这些动态端口。 这些变量采用以下格式:agent.services.<serviceName>.ports.<port>。 在 Bash 脚本中,可以使用进程环境访问变量。

    在前面的示例中, 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 解析为主机上随机分配的端口。

    卷可用于在服务之间共享数据,或者用于在作业的多个运行之间保存数据。 将卷装载指定为窗体<source>:<destinationPath>volumes数组,其中<source>可以是主机上的命名卷或绝对路径,并且<destinationPath>是容器中的绝对路径。 卷可以命名为 Docker 卷、匿名 Docker 卷或在主机上绑定装载。

    services:
      my_service:
        image: myservice:latest
        volumes:
        - mydockervolume:/data/dir
        - /data/dir
        - /src/dir:/dst/dir
    

    如果使用Microsoft托管池,则卷不会保留在作业之间,因为主机在完成每个作业后会清理。

    服务容器与容器作业共享相同的容器资源。 这意味着可以使用相同的 启动选项

    运行状况检查

    如果任一 服务容器指定 HEALTHCHECK,代理可以选择等到容器运行作业前保持正常。

    包含服务的多个容器示例

    以下示例包含连接到 PostgreSQL 和 MySQL 数据库容器的 Django Python Web 容器。

  • 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/manage.py test更新/__w/1/s/路径。

    resources:
      containers:
        - container: db
          image: postgres
          volumes:
              - '/data/db:/var/lib/postgresql/data'
            POSTGRES_DB: postgres
            POSTGRES_USER: postgres
            POSTGRES_PASSWORD: postgres
        - container: mysql
          image: 'mysql:5.7'
          ports:
             - '3306:3306'
            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
    
  • 在管道中指定作业
  • 在 YAML 管道中使用容器作业
  •