共用方式為


服務容器

Azure DevOps 服務

本文說明如何在 Azure Pipelines 中使用 服務容器 。 如果您的流水線需要一個或多個服務的支援,您可能需要建立、連線及清除每個 作業的服務。 例如,您的管線可能會執行整合測試,這些測試需要存取管線中每個作業的新建立資料庫和記憶體快取。

服務容器提供簡單且可攜式的方式,在管線中執行服務。 服務儲存器只能供需要它的工作存取。

服務容器可讓您自動建立、網路和管理管線所依賴的服務生命週期。 服務容器可與任何類型的作業搭配使用,但最常與容器作業搭配使用。

注意

傳統管線不支援服務容器。

條件和限制

  • 服務容器必須定義 CMDENTRYPOINT。 管線在運行提供的容器時不傳入引數。

  • Azure Pipelines 可以執行 Linux 或 Windows 容器。 您可以使用 Linux 容器的託管 Ubuntu 資源池,或 Windows 容器的託管 Windows 資源池。 裝載的 macOS 集區不支援執行容器。

  • 服務容器與容器任務共用相同的容器資源,因此它們可以使用相同的 啟動選項

  • 如果服務儲存器指定 HEALTHCHECK,則代理程式可以選擇性地等到儲存器狀況良好,再執行工作。

單一容器作業

下列範例 YAML 管線會定義使用服務容器的單一容器作業。 管線會從buildpack-deps擷取nginx容器,然後啟動所有容器。 容器是網路化的,因此它們可以透過名稱 services 相互聯繫。

在工作容器內, nginx 主機名稱透過 Docker 網路解析成正確的服務。 網路上的所有容器都會自動向彼此公開所有埠。

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

單一非容器作業

您也可以在非容器工作中使用服務容器。 管線會啟動最新的容器,但由於作業不會在容器中執行,因此沒有自動名稱解析。 相反地,您可以使用 localhost 來存取服務。 下列範例管線會明確指定 8080:80 的連接埠 nginx

另一種方法是在運行時動態分配隨機端口。 若要允許工作存取埠,管線會建立一個變數,其形式為agent.services.<serviceName>.ports.<port>。 您可以在 Bash 指令碼中使用此 環境變數 來存取動態埠。

在下列管線中, redis 取得主機上的隨機可用埠,而變數包含 agent.services.redis.ports.6379 埠號。

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

多個作業

針對相同服務的多個版本執行相同步驟,服務容器也很有用。 在下列範例中,相同的步驟會針對多個 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 存取服務容器。 如果您的作業在容器中執行,則不需要指定 ports ,因為根據預設,相同 Docker 網路上的容器會自動彼此公開所有埠。

埠會採用表單 <hostPort>:<containerPort> ,或只是 <containerPort> 結尾的選擇性 /<protocol> 。 例如, 6379/tcp 透過 tcp6379公開 ,系結至主計算機上的隨機埠。

當您叫用容器資源或內嵌容器時,可以指定要在容器上公開的陣列 ports ,如下列範例所示。

resources:
  containers:
  - container: my_service
    image: my_service:latest
    ports:
    - 8080:80
    - 5432

services:
  redis:
    image: redis
    ports:
    - 6379/tcp

對於系結至主計算機上的隨機埠的埠,管線會建立窗體 agent.services.<serviceName>.ports.<port> 的變數,讓作業可以存取埠。 例如, agent.services.redis.ports.6379 解析為主計算機上的隨機指派埠。

磁碟區

磁碟區適用於在服務之間共享數據,或用於在作業的多個執行之間保存數據。 您可以將磁碟區掛載指定為volumes的陣列。

每一個磁區都採用 <source>:<destinationPath>的形式 ,其中 <source> 是主機上的具名磁區或絕對路徑,並且 <destinationPath> 是容器中的絕對路徑。 磁碟區可以命名為 Docker 磁碟區、匿名 Docker 磁碟區,或系結裝載在主機上。

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

注意

Microsoft 託管的集區不會在各個作業間持續保留磁碟區,因為執行主機會在每次作業之後進行清理。

具有服務範例的多個容器

下列範例管線具有連線至 PostgreSQL 和 MySQL 資料庫容器的 Django Python Web 容器。

  • PostgreSQL 資料庫是主資料庫,其容器名為 db
  • 容器使用 db/data/db:/var/lib/postgresql/data,並透過 env將三個資料庫變數傳遞給容器。
  • 容器使用 mysql port 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