こんにちは、 フォーカセル開発チーム所属の
id:hano_tea です。
弊チームではアプリケーションを AWS ECR, ECS を利用して稼働させており、デプロイには CircleCI を利用しているのですが、 先日 CircleCI 周りの設定を見直した際に謎のエラーが発生、ビルドがコケて少しハマってしまいました :sob:
エラーメッセージから原因の特定がやや難しいタイプの問題で、同様の現象に遭遇したという記事、情報も特に見当たらなかったため、 記事として原因と対応方法を書き留めておこうと思います。
TL;DR
aws-ecrOrb 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-ecrOrb のバージョンは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-ecrOrb が 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 上の環境についても日頃から意識して、こまめなメンテナンスやアップデートをしていかなければ…と思う出来事でした。