DockerのPull rate limitに引っかかるときはAmazon ECR Public Galleryを使おう
この記事では、AWS CodeBuildなどのCI/CDでDocker HubのPull rate limitに引っかかるときの対応策として、ベースイメージを取得するリポジトリをAmazon ECR Public Galleryに切り替える方法について紹介します。
背景
AWS CodeBuildを用いてデプロイを行っているのですが、デプロイの度にイメージビルドを行っています。そのため、Docker Hubに存在するベースイメージ(go, node, alpineなど)へのpullが多発し、制限に引っかかることが増えてきました。
具体的には次のようなエラーが発生してデプロイに失敗してしまいます。
TOOMANYREQUESTS: You have reached your pull rate limit. You may increase the limit by authenticating and upgrading: https://www.docker.com/increase-rate-limit
このプロジェクトではCodeBuild専用のDocker無料アカウントを作成して認証してからpullしています。しかし、無料アカウントであるため、 200 pulls / 6 hours
の制限があります。
プロダクトの開発が進むにつれて、CI/CDのデプロイ頻度が増えているため、この制限に引っかかることが増えてきました。本番デプロイができなくなるという重大な問題につながるため、対策が必要です。
Amazon ECR Public Galleryとは
そこで、Docker Hubの代わりにAmazon ECR Public Galleryを利用することにしました。
Amazon ECR Public Galleryは、Docker Hubの代替として利用できるコンテナレジストリです。AmazonによりDocker Hubのイメージが複製され公開されています。
ECR Public Galleryのレート制限と料金について
Amazon ECR Public GalleryのPull制限や料金はDocker Hubと比較してかなり緩くなっています。特に、AWSリージョン内からであれば 10 pulls / second
以外の制限がなく無料で利用でき、CodeBuildなどのCI/CDによるPullが圧倒的に多い場合かなり魅力的です。
- 認証していない場合、IPアドレスごとに
-
10 pulls / second
のレート制限 -
500 GB / month
の転送量制限
-
- 認証している場合、アカウントごとに
-
10 pulls / second
のレート制限 -
5 TB / month
まで無料 -
5 TB / month
を超えた場合は0.09 USD / GB
- AWSリージョン内からであれば転送量加算なし
-
2024年3月11日現在。ドキュメントから最新の情報を確認してください。
Docker HubからECR Public Galleryに切り替える方法
Amazon ECR Public Galleryを利用するためには、次の手順でベースイメージを取得するリポジトリをAmazon ECR Public Galleryに切り替える必要があります。
例えば次のようなFROM句を使っているDockerfileがあるとします。
FROM node:21.7.0-alpine3.19
node
はDocker Hubの公式イメージです。これをAmazon ECR Public Galleryのイメージに切り替えるためには、public.ecr.aws/docker/
を追加し次のように書き換えます。
FROM public.ecr.aws/docker/library/node:21.7.0-alpine3.19
注意点として、Docker Hub公式イメージの場合は、その後ろに library/
を付ける必要があります。つけ忘れると別のイメージを参照してしまうことがあるため、注意が必要です。念の為、下記から正しいイメージ名を確認してください。
これで、Amazon ECR Public Galleryのイメージを参照するようになります。
ECR Public Galleryを利用するための認証・権限
IPアドレスごとの500GB/月までの転送量制限の影響を受けないためには、認証が必要です。
IAMポリシーの設定
ECR Public Galleryを利用するためには、 ecr-public:GetAuthorizationToken
及び sts:GetServiceBearerToken
の権限が必要です。次のようなポリシーを作成し、IAMユーザーにアタッチします。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AmazonECRPublicGalleryPull",
"Effect": "Allow",
"Action": [
"ecr-public:GetAuthorizationToken",
"sts:GetServiceBearerToken"
],
"Resource": "*"
}
]
}
ローカル環境
認証していない場合、IPアドレスごとに500GB/月までの転送量制限がかかります。そのため、ローカル環境で参照する場合は、事前に次の手順でアカウントを認証します。
aws ecr-public get-login-password --region us-west-2 | docker login --username AWS --password-stdin public.ecr.aws
AWS CodeBuild
AWS CodeBuildでAmazon ECR Public Galleryのイメージを参照する場合は、CodeBuildの buildspec.yml
で認証をします。例えば次のように buildspec.yml
に記述します。
version: 0.2
env:
variables:
DOCKER_BUILDKIT: 1
phases:
pre_build:
commands:
- aws ecr-public get-login-password --region us-west-2 | docker login --username AWS --password-stdin public.ecr.aws
ハマりポイント
認証する際に、次のようなエラーが発生しました。
Could not connect to the endpoint URL: "https://api.ecr-public.ap-northeast-1.amazonaws.com/"
Error: Cannot perform an interactive login from a non TTY device
このエラーは、何らかの理由でAWSからDockerに認証情報が渡されなかったため発生します。私の場合は、 --region
を指定しなかったことで、規定のリージョンである ap-northeast-1
に接続しようとしていました。
ECR Publicは us-east-1
または us-west-2
でしか利用できないため、 --region
を用いてどちらを指定する必要があります。今回、 ap-northeast-1
からより近い us-west-2
を指定しました。
まとめ
Docker HubのPull rate limitに引っかかるとき、Amazon ECR Public Galleryに切り替える方法について紹介しました。
特に、AWSリージョン内からであれば、ほぼ無制限に無料で利用できるため、CodeBuildによるPullが多い場合はとても便利です。
同様のトラブルを防ぐために、他のプロジェクトでもAmazon ECR Public Galleryを切り替えることを検討していきます。
Discussion