YAML 管線中的容器作業
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
本文說明 Azure Pipelines 中的容器作業。
根據預設,Azure Pipelines 作業 會直接在安裝代理程式的主計算機上執行。 裝載的代理程式作業很方便,需要很少的初始設定和基礎結構才能維護,而且非常適合基本專案。
如果您想要進一步控制工作內容,您可以在容器中定義和執行作業。 容器是主機操作系統的輕量抽象概念,可提供與主機的隔離。 當您在容器中執行作業時,您可以選取組建所需的確切作業系統、工具和相依性版本。
Linux 和 Windows 代理程式 可以直接在主機或容器上執行管線作業。 macOS 上無法使用容器作業。
針對容器作業,代理程式會先擷取並啟動容器。 然後作業的每個步驟都會在容器內執行。
如果您需要個別建置步驟層級的精細控制, 步驟目標 可讓您為每個步驟選擇容器或主機。
必要條件
- 使用 YAML 管線。 傳統管線不支援容器作業。
- 使用裝載的 Windows 或 Ubuntu 代理程式。 只有
windows-*
和ubuntu-*
代理程式支援執行中的容器。 代理macos-*
程式不支援執行容器。 - 您的代理程式已針對容器作業進行設定。
- Windows 和 Linux 代理程式必須已安裝 Docker,而且需要存取 Docker 精靈的許可權。
- 當代理程式已在容器內執行時,不支援容器。 您無法有巢狀容器。
其他容器需求
以 Linux 為基礎的容器具有下列需求。 如需因應措施,請參閱 Nonglibc 型容器。
- 已安裝Bash
- GNU C 連結庫 (glibc) 型
- 不
ENTRYPOINT
- 提供
USER
存取groupadd
權和其他特殊許可權命令,而不使用sudo
- 可以執行代理程式所提供的Node.js
注意
Node.js必須針對 Windows 主機上的 Linux 容器預安裝。
Docker Hub 上提供的一些已移除容器,特別是以 Alpine Linux 為基礎的容器,不符合這些需求。 具有的 ENTRYPOINT
容器可能無法運作,因為 Azure Pipelines docker create
且 docker exec
預期容器一律已啟動並執行。
單一作業範例
下列範例會定義單一作業的 Windows 或 Linux 容器。
下列簡單範例會定義 Linux 容器:
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
上述範例會指示系統擷取從 Docker Hub 標記的ubuntu
18.04
映像,然後啟動容器。 命令 printenv
會在 ubuntu:18.04
容器內執行。
多個作業
您可以使用容器在多個作業中執行相同的步驟。 下列範例會在多個版本的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 登錄容器初始化的結尾註銷。 後續容器作業的登錄映像提取可能會遭到 unauthorized authentication
拒絕,因為另一個以平行方式執行的作業已經註銷 Docker 組態檔。
解決方案是設定 Docker 環境變數 DOCKER_CONFIG
,這是裝載代理程式上所執行之每個代理程式集區特有的。 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 DevOps 搭配使用。 請先檢查,以查看您是否可以使用 container
屬性來完成相同的目標。
如需詳細資訊,請參閱 Azure DevOps YAML 架構參考中的 docker create 命令參考和 resources.containers.container 定義 。
可重複使用的容器定義
下列範例會定義 區段中的 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 需要其他用戶端工具,才能將 AWS 認證轉換成 Docker 可用來驗證的專案。
非glibc 型容器
Azure Pipelines 代理程式會提供一份Node.js複本,這是執行工作和腳本所需的複本。 若要瞭解託管代理程式的Node.js版本,請參閱 Microsoft裝載的代理程式。
Node.js版本會針對裝載雲端中使用的 C 運行時間進行編譯,通常是 glibc。 某些 Linux 變體會使用其他 C 運行時間。 例如,Alpine Linux 會使用 musl。
如果您想要使用非glibc 型容器,您需要:
- 提供您自己的Node.js複本。
- 將標籤新增至您的影像,告知代理程式在何處尋找Node.js二進位檔。
- 提供 Azure Pipelines 相依於的其他相依性:
bash
、sudo
、which
和groupadd
。
提供您自己的Node.js
如果您使用非glibc 型容器,您必須負責將節點二進位檔新增至容器。 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 特別沒有隨附數個所需的套件。 安裝 bash
、 sudo
和 shadow
以涵蓋基本需求。
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" ]