こんにちは、 フォーカセル開発チーム所属の id:hano_tea です。
弊チームではアプリケーションを AWS ECR, ECS を利用して稼働させており、デプロイには CircleCI を利用しているのですが、 先日 CircleCI 周りの設定を見直した際に謎のエラーが発生、ビルドがコケて少しハマってしまいました :sob:
エラーメッセージから原因の特定がやや難しいタイプの問題で、同様の現象に遭遇したという記事、情報も特に見当たらなかったため、 記事として原因と対応方法を書き留めておこうと思います。
TL;DR
aws-ecr
Orb v8 から Multi-arch build がサポートされ、docker buildx
が使われるようになりました- 環境によって
docker buildx
が使えないことがあり、その場合分かりづらいエラーを吐いてビルドがコケます circleci
は古いイメージなのでcimg
リポジトリのイメージを使うようにしましょう- https://support.circleci.com/hc/ja/articles/360058095471-Remote-Docker-%E3%81%A7-Buildx-%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%9F%E3%81%84
もし、私たちの
cimg
イメージ以外の docker イメージを使用している場合は、そのイメージ内で buildx が使用可能であることを確認する必要があることに注意してください。
発生した現象
一言で言うと、「aws-ecr
Orb のバージョンを v6.12.2
から v8.2.1
に上げたらビルドが変なコケ方をするようになった」です。
改修前の設定
改修前の .circleci/config.yml
は以下のような状態になっていました。
(必要最低限の設定だけにしたものを掲載しています)
version: 2.1 orbs: aws-ecr: circleci/aws-ecr@6.12.2 jobs: build-image: docker: - image: circleci/golang:1.17.2 steps: - checkout - setup_remote_docker - aws-ecr/build-and-push-image: repo: "invalid-ecr-build-sample" workflows: main: jobs: - build-image: context: - test
設定内容をざっくりまとめると、
aws-ecr
Orb のバージョンは6.12.2
- 実行環境は Docker,
circleci/golang:1.17.2
aws-ecr/build-and-push-image
コマンドで Docker イメージをビルド、プッシュする
という感じになっています。
当然ですが、こちらの設定は改修前にデプロイに利用していたため、特に問題なくビルドが通ります。
ビルドがコケた設定
上述の設定に対し、 aws-ecr
Orb のバージョンアップをするような以下の修正を加えました。
diff --git a/.circleci/config.yml b/.circleci/config.yml index aa4031d..b306256 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - aws-ecr: circleci/aws-ecr@6.12.2 + aws-ecr: circleci/aws-ecr@8.2.1 jobs: build-image:
この状態で CI を走らせると aws-ecr/build-and-push-image
が以下のようなエラーを出してコケます。
(全部書くと量が多いので一部抜粋)
...(前略)... + docker buildx build -f ./Dockerfile -t *************************************************/invalid-ecr-build-sample:latest --platform linux/amd64 --progress plain --push . unknown shorthand flag: 'f' in -f See 'docker --help'. Usage: docker [OPTIONS] COMMAND ...(中略)... Exited with code exit status 125 CircleCI received exit code 125
unknown shorthand flag: 'f' in -f
というエラーメッセージが出ています。 f
フラグがない?というイマイチよく分からないエラーです。
当然ながら docker build でも docker buildx build でも -f
フラグは存在し、 Docker ファイルを指定するためのものになっているので、
f
フラグが無いと言われても…としばらく途方に暮れていました。
解決策
様々な調査を経て、結局以下のようにすれば良いということがわかりました。
diff --git a/.circleci/config.yml b/.circleci/config.yml index aa4031d..f1fe0c4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,12 +1,12 @@ version: 2.1 orbs: - aws-ecr: circleci/aws-ecr@6.12.2 + aws-ecr: circleci/aws-ecr@8.2.1 jobs: build-image: docker: - - image: circleci/golang:1.17.2 + - image: cimg/go:1.17.2 steps: - checkout - setup_remote_docker
何が変わったかというと、「実行環境となる Docker イメージ」が変わっています。
元々 circleci
リポジトリの Go 用イメージを使っていましたが、
それを cimg
リポジトリの Go 用イメージを使うようにしています。
原因
ざっくり言うと、
aws-ecr
Orb が v8 からdocker buildx
を使ってイメージをビルドするようになったcircleci
リポジトリのイメージだとdocker buildx
が使えない
という2つが組み合わさった結果発生したものでした。
CircleCI の docker image と buildx
CircleCI 上で buildx を使う際の資料としては以下の公式ブログ記事がありました。
色々書いてありますが、記事の末尾あたりに以下のような記述があります。
もし、私たちの
cimg
イメージ以外の docker イメージを使用している場合は、そのイメージ内で buildx が使用可能であることを確認する必要があることに注意してください。
buildx
を使う場合は cimg
系のイメージを使うか、あるいは buildx
が使えることがわかっているイメージを使わないと今回と同じようにハマる可能性が高そうです。
同じ CircleCI 公式イメージではありますが、 circleci
系イメージだと buildx
は対応していなさそうなので注意しましょう。
ちなみに cimg
は2020年初め頃に出た次世代イメージと呼ばれているもので、 circleci
はそれ以前からある古いイメージです。
今わざわざ circleci
系イメージを新規に使う理由はおそらく無いので、特段の事情がなければ cimg
を使うのが良さそうです。
まとめ
というわけで、 aws-ecr
Orb をアップデートしたら謎エラーが発生してハマったというお話でした。
原因自体は分かってしまえば簡単な話…でしたが、エラーメッセージから原因を推測するのが難しく、調査に結構な時間を使ってしまったのが辛いところです……
アプリケーションで使っているライブラリ、言語のバージョンアップは意識しやすいですが、 CI 上の環境についても日頃から意識して、こまめなメンテナンスやアップデートをしていかなければ…と思う出来事でした。