CodeBuild で Docker Image をビルドするときにはまる罠
こんにちは。Build サービス推進チームで Solution Architect として活動している t_maru です。 今回は AWS CodeBuild を使用して Docker Image をビルドする際に遭遇することのあるエラーについて書いてみたいと思います。
AWS CodeBuild とは?
AWS CodeBuild はソースコードのコンパイルやテストなどを実行するためのマネージドサービスです。基本的にはどのようなビルド処理を行うのかを buildspec と呼ばれる専用の設定を書くことで、その内容に従ったコンテナが自動生成され、そのコンテナ上でソースコードのビルドやテストが実行されます。
通常は VPC 外部の共有リソースが使われるためネットワークを用意する必要もありませんが、オプションとして VPC に NAT Gateway または NAT Instance を設定することにより、 VPC 内部のリソースにアクセスしたり、 NAT Gateway の IP Address を経由して外部のサービスにアクセスできるようになります。
CodeBuild 上で Docker Image をビルドする時にどこで困るのか?
本題です。とりあえずビルド時に遭遇したエラーのログを見てみます。
※ 上記画像内の処理実行日時と image 名はマスクしています。
これは、 CodeBuild の処理の中で、 docker build コマンドを使用したときに発生し、ログの 164 行目に記載のあるように toomanyrequests: You have reached your pull rate limit.、つまり、 image を pull するとき制限に引っかかったよ、ということです。
Docker Hub では、 2020/11/1 より image pull に回数制限が設けられ、匿名ユーザー (docker login していないユーザー) の場合は 6 時間で 100 pull まで という制限に引っかかった事により生じているエラーになります。
下記が、参考にした Docker 関連のページです。
この制限の値だけ見ると、6 時間で 100 回も image pull しないから大丈夫 と思われるかもしれませんが、 CodeBuild はマネージドサービスというところに罠が潜んでいます。
Managed サービスの罠
冒頭でも説明したように CodeBuild は標準状態で使用する限りは、ビルドに使うコンテナが動作するホストリソースはユーザー間で共有するモデルになっています。
ここで、先程も出た Docker Hub の pull 回数制限ですが、未認証ユーザーに関しては Docker の blog に以下のような記載があります。
つまり、未認証ユーザーの場合は、image を pull した際に利用された IP Address によって先の Rate limit が適応されることになりますので、もし起動された CodeBuild のコンテナが利用している IP Address で、他のユーザーが DockerHub から image を pull しており、その総計が 6 時間あたり 100 回を超えているとエラーになるわけです。
日によって、時間によっても変わると思いますが、私が検証をしていた時間帯では 5 回ビルドすると 2 回程度このエラーで失敗するくらいの頻度で遭遇しました。
回避する方法はあるのか?
この制限を回避する方法として以下のようなものが考えられると思います。
1 つ目の Free plan のまま docker login して使う方法では、 6 時間あたり 200 pull までという制限は docker login に使ったアカウント単位でカウントされるため、 CodeBuild のコンテナが (IP Address が) 共用されていても問題ありません。
2 つ目の有料プランを使うパターンですが、1 日あたり 200 回以上 image の pull が必要になる場合には検討しても良いかもしれません。価格については以下の公式ページを参照してください。
3 つ目の ECR に image を置いておく方法ですが、これは Docker Hub の Rate limit からは開放されるものの、 image を最新の状態に保つための仕組みや運用が必要になるため、あまりおすすめしたい方法ではありません。
最後の VPC に接続して使う方法ですが、VPC の設定と NAT Gateway または NAT Instance が必要になるため、手間と費用の観点であまり得策ではないと思います。
NAT Gateway の価格を東京リージョンで見てみると、この記事執筆時点では 0.062 USD / hour となっているので、1 ヶ月を 30 日で計算すると 44.64 USD となります。この料金はデータ処理の料金を含んでいないため、もう少し高くなると思いますので、わざわざ VPC, NAT Gateway の設定してまでこの価格で 100 pull / 6 hour の制限で使いたいか?と言われると正直微妙だと思います。
ただし、 Docker Hub のアカウント作成や支払い手続きが社内ルール的に難しくて・・・といったような場合では出番があるかもしれないですので、選択肢の一つとして頭の片隅に置いておいて損は無いと思います。
まとめ
今回は CodeBuild で Docker Image をビルドした際に、 Docker Hub の pull image Rate limit に遭遇したこと、その回避方法などを説明しました。
手軽でおすすめなのは Free plan で docker login して使う 方法ですが、皆様の置かれた状況によって選択が変わってくると思いますので、用途・状況に応じて皆様に合った選択をしていただければと思います。