YAML パイプライン内のコンテナー ジョブ
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
この記事では、Azure Pipelines のコンテナー ジョブについて説明します。
既定では、Azure Pipelines jobs エージェントがインストールされているホスト マシンで直接実行されます。 ホストされるエージェント ジョブは便利で、初期セットアップと保守のためのインフラストラクチャはほとんど必要なく、基本的なプロジェクトに適しています。
タスク コンテキストをより詳細に制御する場合は、コンテナーでジョブを定義して実行できます。 コンテナーは、ホストから分離を提供するホスト オペレーティング システムに対する軽量の抽象化です。 コンテナーでジョブを実行する場合は、ビルドに必要なオペレーティング システム、ツール、依存関係の正確なバージョンを選択できます。
Linux および Windows agents は、ホストまたはコンテナーでパイプライン ジョブを直接実行できます。 コンテナー ジョブは macOS では使用できません。
コンテナー ジョブの場合、エージェントは最初にコンテナーをフェッチして開始します。 その後、ジョブの各ステップがコンテナー内で実行されます。
個々のビルド ステップ レベルできめ細かな制御が必要な場合は、 ステップ ターゲット 各ステップのコンテナーまたはホストを選択できます。
要件と制限
Azure Pipelines エージェントのホストまたはコンテナーには、次の要件と制限が適用されます。
エージェント ホスト
windows-*
とubuntu-*
のイメージのみがコンテナーの実行をサポートします。macos-*
イメージでは、コンテナーの実行はサポートされていません。- コンテナーを実行するには、Windows および Linux エージェント ホストに Docker がインストールされていて、Docker デーモンにアクセスするためのアクセス許可が必要です。
- エージェントがコンテナー内で既に実行されている場合、コンテナーはサポートされません。 入れ子になったコンテナーを使用することはできません。
Containers
Linux ベースのコンテナーには、次の要件があります。 回避策については、 Nonglibc ベースのコンテナーを参照してください。
- Bash がインストールされている
- GNU C ライブラリ (glibc) ベース
ENTRYPOINT
なし- を使用せずに、
groupadd
やその他の特権コマンドへのアクセスをUSER
に提供するsudo
- エージェントが提供するNode.jsを実行できます
Note
Node.jsは、Windows ホスト上の Linux コンテナー用にプレインストールする必要があります。
Docker Hub で使用できる一部の削除されたコンテナー (特に Alpine Linux に基づくコンテナー) は、これらの要件を満たしていません。 Azure Pipelines がdocker create
し、コンテナーが常に稼働docker exec
想定しているため、ENTRYPOINT
を持つコンテナーが機能しない可能性があります。
単一ジョブの例
次の例では、1 つのジョブの Windows または Linux コンテナーを定義します。
次の簡単な例では、Linux コンテナーを定義します。
pool:
vmImage: 'ubuntu-latest'
container: ubuntu:18.04
steps:
- script: printenv
前の例では、Docker Hub から18.04
タグ付けされたubuntu
イメージをフェッチしコンテナーを開始するようにシステムに指示します。 printenv
コマンドは、ubuntu:18.04
コンテナー内で実行されます。
複数のジョブ
コンテナーを使用して、複数のジョブで同じ手順を実行できます。 次の例では、複数のバージョンの Ubuntu Linux で同じ手順を実行します。 1 つのジョブのみが定義されているため、 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
1 つのエージェント ホスト上のエージェント プールを持つ複数のジョブ
コンテナー ジョブは、基になるホスト エージェントの Docker 構成ファイルを使用して、イメージ レジストリの承認を行います。 このファイルは、Docker レジストリ コンテナーの初期化の最後にサインアウトします。 並列で実行されている別のジョブが既に Docker 構成ファイルをサインアウトしているため、後続のコンテナー ジョブのレジストリ イメージ プルが unauthorized authentication
に対して拒否される可能性があります。
解決策は、ホストされているエージェントで実行されている各エージェント プールに固有の Docker 環境変数 DOCKER_CONFIG
を設定することです。 各エージェント プールのrunsvc.sh スクリプトのDOCKER_CONFIG
を次のようにエクスポートします。
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
Note
Azure Pipelines は Amazon Elastic Container Registry (ECR) のサービス接続を設定できません。Amazon ECR では、AWS の資格情報を Docker が認証に使用できるものに変換するために他のクライアント ツールが必要であるためです。
非glibc ベースのコンテナー
Azure Pipelines エージェントは、タスクとスクリプトを実行するために必要な Node.js のコピーを提供します。 ホステッド エージェントの Node.js のバージョンを確認するには、「Microsoft ホステッド エージェント」を参照してください。
Node.jsのバージョンは、ホストされたクラウド (通常は glibc) で使用される C ランタイムに対してコンパイルされます。 一部の Linux バリアントでは、他の C ランタイムが使用されます。 たとえば、Alpine Linux は musl を使用します。
非glibc ベースのコンテナーを使用する場合は、次の手順を実行する必要があります。
- Node.jsの独自のコピーを指定します。
- Node.js バイナリを検索する場所をエージェントに伝えるラベルをイメージに追加します。
- Azure Pipelines が依存するその他の依存関係 (
bash
、sudo
、which
、groupadd
) を提供します。
独自の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 には必要なパッケージがいくつかありません。 基本的なニーズに対応するために、 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" ]
関連するコンテンツ
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示