共用方式為


YAML 管線中的容器作業

Azure DevOps 服務 |Azure DevOps Server |Azure DevOps Server 2022

本文說明 Azure Pipelines 中的容器作業。 容器是來自主機作業系統的輕量型抽象概念,可提供在特定環境中執行工作所需的所有元素。

根據預設,Azure Pipelines 作業會 直接在主機電腦上安裝 的代理程式 上執行。 託管代理程式作業很方便,幾乎不需要初始設定或基礎設施維護,並且非常適合基本專案。 若要進一步控制工作內容,您可以在容器中定義和執行管線作業,以取得您想要的作業系統、工具和相依性的確切版本。

對於容器作業,代理程式會先擷取並啟動容器,然後在容器內執行作業的每個步驟。 如果您需要更精細地控制個別建置步驟,您可以使用 步驟目標 為每個步驟選擇容器或主機。

容器工作的需求

  • 以 YAML 為基礎的管線。 傳統管線不支援容器作業。
  • Windows 或 Ubuntu 託管代理程式。 MacOS 代理程式不支援容器。 若要使用非 Ubuntu Linux 代理程式,請參閱 Nonglibc 型容器
  • Docker 安裝在代理程式上,並具有存取 Docker 常駐程式的許可權。
  • 代理程式直接在主機上執行,尚未在容器內執行。 不支援巢狀容器。

基於 Linux 的容器也有以下要求:

  • 已安裝 Bash。
  • 基於 GNU C 函式庫 (glibc)。 Nonglibc 容器需要新增設定。 如需詳細資訊,請參閱 非 glibc 型容器
  • 不。ENTRYPOINT 具有 的 ENTRYPOINT 容器可能無法運作,因為 docker exec 預期容器一律在執行中。
  • USER 提供存取 groupadd 權和其他特權命令,而無需使用 sudo
  • 能夠執行代理程式提供的 Node.js。

    注意

    必須預先安裝 Node.js 適用於 Windows 主機上的 Linux 容器。

Docker Hub 上提供的一些已移除容器,特別是以 Alpine Linux 為基礎的容器,不符合這些需求。 如需詳細資訊,請參閱 非 glibc 型容器

單一工作

下列範例定義 Windows 或 Linux 單一作業容器。

此範例會告知系統ubuntu18.04 擷取標記的映像檔,然後啟動容器。 命令 printenv 會在 ubuntu:18.04 容器內執行。

pool:
  vmImage: 'ubuntu-latest'

container: ubuntu:18.04

steps:
- script: printenv

多個作業

您可以使用容器在多個作業中執行相同的步驟。 下列範例會在多個版本的UbuntuLinux中執行相同的步驟。 您不必使用 jobs 關鍵字,因為只定義了單一工作。

pool:
  vmImage: 'ubuntu-latest'

strategy:
  matrix:
    ubuntu16:
      containerImage: ubuntu:16.04
    ubuntu18:
      containerImage: ubuntu:18.04
    ubuntu20:
      containerImage: ubuntu:20.04

container: $[ variables['containerImage'] ]

steps:
- script: printenv

單一代理程式主機上的多個工作

容器作業會使用基礎主機代理程式的 Docker 組態檔進行映射登錄授權。 此檔案會在 Docker 登錄容器初始化結束時登出。

如果代理程式上平行執行的另一個工作已登出 Docker 組態檔,則容器工作的登錄映像提取可能會因未經授權的驗證而被拒絕。 解決方案是針對託管代理程式上執行的每個代理程式集區設定呼叫 DOCKER_CONFIG 的 Docker 環境變數。

DOCKER_CONFIG匯出到每個代理程式集區的 runsvc.sh 腳本,如下所示:

export DOCKER_CONFIG=./.docker

啟動選項

您可以使用內容 options 來指定儲存器啟動的選項。

container:
  image: ubuntu:18.04
  options: --hostname container-test --ip 192.168.0.1

steps:
- script: echo hello

執行以 docker create --help 取得您可以傳遞至 Docker 調用的選項清單。 並非所有這些選項都保證可與 Azure Pipelines 搭配使用。 請先檢查您是否可以將某個 container 屬性用於相同目的。

如需詳細資訊,請參閱 Docker 容器建立命令參考和 Azure Pipelines 的 YAML 架構參考中的 resources.containers.container 定義。

可重複使用的容器定義

下列 YAML 範例會定義區 resources 段中的容器,然後依其指派的別名來參考它們。 jobs為了清楚起見,使用關鍵字。

resources:
  containers:
  - container: u16
    image: ubuntu:16.04

  - container: u18
    image: ubuntu:18.04

  - container: u20
    image: ubuntu:20.04

jobs:
- job: RunInContainer
  pool:
    vmImage: 'ubuntu-latest'

  strategy:
    matrix:
      ubuntu16:
        containerResource: u16
      ubuntu18:
        containerResource: u18
      ubuntu20:
        containerResource: u20

  container: $[ variables['containerResource'] ]

  steps:
  - script: printenv

服務端點

您可以在公用 Docker Hub 以外的登錄上託管容器。 若要在 Azure Container Registry 或其他私人容器登錄上裝載映像,包括私人 Docker Hub 登錄,請新增服務連線以存取登錄。 然後,您可以在容器定義中參考端點。

私人 Docker Hub 連線:

container:
  image: registry:ubuntu1804
  endpoint: private_dockerhub_connection

Azure Container Registry 連線:

container:
  image: myprivate.azurecr.io/windowsservercore:1803
  endpoint: my_acr_connection

注意

Azure Pipelines 無法設定 Amazon Elastic Container Registry (ECR) 的服務連線,因為 Amazon ECR 需要其他用戶端工具來轉換 Amazon Web Services (AWS) 認證,以用於 Docker 驗證。

非基於glibc的容器

裝載的 Azure Pipelines 代理程式會提供 Node.js,這是執行工作和腳本所必需的。 Node.js 版本會針對託管雲端中使用的 C 執行階段進行編譯,通常是 glibc。 某些 Linux 變體會使用其他 C 運行時間。 例如,Alpine Linux 使用 musl. 如需詳細資訊,請參閱 Microsoft 裝載的代理程式

如果您想要在管線中使用非glibc型容器,您必須:

  • 提供您自己的Node.js複本。
  • 在圖像中添加一個標籤,指向 Node.js 二進制文件的位置。
  • 提供 bash、 、 sudowhichgroupadd Azure Pipelines 相依性。

提供您自己的Node.js

如果您使用非glibc型容器,則必須將Node二進位檔新增至容器。 Node.js 18 是一個安全的選擇。 從 node:18-alpine 映像開始。

將客服專員引導至 Node.js

代理程式會讀取容器標籤 "com.azure.dev.pipelines.handler.node.path"。 如果此標籤存在,它必須是Node.js二進位檔的路徑。

例如,在以node:18-alpine為基礎的映像中,將下列這一行新增至您的 Dockerfile:

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

新增必要套件

Azure Pipelines 需要以 Bash 為基礎的系統,才能安裝常見的系統管理套件。 Alpine Linux 沒有幾個所需的軟件包。 安裝 bashsudoshadow 以滿足基本需求。

RUN apk add bash sudo shadow

如果您依賴任何內建或 Marketplace 工作,也請提供它們所需的二進位檔。

完整的 Dockerfile 範例

FROM node:18-alpine

RUN apk add --no-cache --virtual .pipeline-deps readline linux-pam \
  && apk add bash sudo shadow \
  && apk del .pipeline-deps

LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node"

CMD [ "node" ]