理系学生日記

おまえはいつまで学生気分なのか

Azure Pipelinesでalpineベースのコンテナを使うとエラーになる

AzureでCIを行う場合はAzure Pipelinesを使うことになります。 また、最近のCIは都度同じ環境でCIを動かせるようにコンテナの上で実行するのがスタンダードです。

このため、開発しているプロダクトではalpineベースのコンテナでCIジョブを動作させていました。たとえば以下の通り、hashicorp/terraformはAlpineベースのイメージです。

$ docker run --rm -it --entrypoint head hashicorp/terraform:1.0.0 -1 /etc/os-release
NAME="Alpine Linux"

このようなイメージをAzure Pipelinesで動かした場合、CIジョブが起動しないという問題に遭遇しました。 Azure PipelinesのInitialize containersのログを見ると、以下のようなエラーが出力されています。

/usr/bin/docker exec 3ba25f3ee0c4f689807bc4dc44c307c1bd21896b228221502ac11bf017dfcfe1 \
sh -c "command -v bash"
cannot exec in a stopped state: unknown
##[error]Docker exec fail with exit code 126
Finishing: Initialize containers

原因

Azure Pipelinesでは、Linuxベースのコンテナには以下のような要件が課されます。

The Azure Pipelines system requires a few things in Linux-based containers:

  • Bash
  • glibc-based
  • Can run Node.js (which the agent provides)
  • Does not define an ENTRYPOINT
  • USER has access to groupadd and other privileges commands without sudo

Define container jobs (YAML)

Alpineベースのコンテナイメージでは、これらの要件を満たせません。 実際に先ほどのInitialize containersのログを見ると以下のようにbashが使えるかをAzure Pipelinesが確認しています。これが正常終了しないとコンテナの初期化を失敗させてしまいます。

$ /usr/bin/docker exec 3ba25f3ee0c4f689807bc4dc44c307c1bd21896b228221502ac11bf017dfcfe1 sh -c "command -v bash"

対策

alpineにこだわる場合は、Non glibc-based containersにしたがって対応すれば良いでしょう。

ぼくはalpineにこだわる理由もなかったので、ベースイメージをdebianベースに変更しました。