はじめに
CodePipelineのCodeBuildでの工程で、以下のエラーがたびたび発生しました。
toomanyrequests: You have reached your pull rate limit.
You may increase the limit by authenticating and upgrading:
https://www.docker.com/increase-rate-limit
DockerHubでは、匿名ユーザによるDockerHubからのコンテナイメージの呼び出し回数は、以下のような制限があります。
設定 | 意味 |
---|---|
無料プラン(匿名ユーザー) | 100 pull/6時間あたり |
無料プラン(認証ユーザー) | 200 pull/6時間あたり |
Pro | 無制限 |
Team | 無制限 |
匿名ユーザーは、 IP アドレス単位で回数制限がかかるため、CodeBuildからの実行では自分が行った回数に関係なく制限に引っかかってしまうため、今回のようなエラーが出ていました。
そのため、今回は、無料プランの認証ユーザーとして、DockerHubにログインすることで、Buildのエラーになる確率をぐっと減らしたいと思います。
実際の本番環境ですと、有料プランに入るべきですが。。
前提条件
- CodepipelineでCodeBuild作成済み
作成方法はこちらの記事を参考にしてください。
CodePipelineを利用したECSのローリングデプロイ
流れ
①DockerHubのアカウント作成
②SystemsManagerでパラメータ作成
③サービスロールにポリシーをアタッチ
④buildspec.ymlの修正
⑤CodeBuildに環境変数を追加
DockerHubのアカウント作成
こちらのリンクからDockerHubアカウントを作成します。
アカウント作成に必要なDockerID・メールアドレス・パスワードを設定します。
DockerID
は、ユーザ名に近い使い方をします。
Codebuildで必要な値は、以下の2つです。
DockerID
アカウントパスワード
Docker Hub で Two-Factor Authentication(MFA)を有効にしている場合は、アカウントパスワード
の代わりにアクセストークン
を使用する必要があります。
アカウント設定
に移動し、左タブSecurity
をクリックし、New Access Tokens
をクリックすると、アクセストークンが発行されます。
-
Access Token Description
:ForCodeBuild
-
Access permissions
:Read, Write, Delete
Generate
をクリックします。
SystemsManagerでパラメータ作成
以下の2つのパラメータを作成します。
DockerID
アカウントパスワード
SystemsManagerのマイパラメータに遷移し、パラメータの作成
をクリックします。
パラメータを作成をクリックします。
同様にアカウントパスワード用も作成します。
-
名前
:DOCKER_HUB_PASSWORD
(何でも可) -
利用枠
:標準
-
タイプ
:安全な文字列
-
KMSキーソース
:現在のアカウント
-
KMSキーID
:alias/aws/ssm
-
値
:Dockerアカウントのパスワードの値を入れます
サービスロールにポリシーをアタッチ
ビルドプロジェクトがSystems Managerのパラメータストアに保存されているパラメータを参照する場合、ビルドプロジェクトのサービスロールにssm:GetParameters
アクションを許可する必要があります。
サービスロールは、CodeBuild
コンソールのビルドプロジェクト→編集
→環境
から確認できます。
IAMのコンソールからサービスロールに遷移し、ポリシー名をクリックします。
さらにアクセス許可を追加する
をクリックします。
buildspec.ymlの修正
CodePipelineでのBuildステージにおいて、DockerHubにログインし、認証ユーザーとしてイメージをpullするために、以下の一行をbuildspec.yml
に加えます。
echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
version: 0.2
phases:
pre_build:
commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
+ - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
build:
commands:
CodeBuildに環境変数を追加
Buildステージに環境変数を追加する方法は、以下の2つあります。
・buildspec.ymlに環境変数を追加する。
・CodePipelineのCodeBuildのステージに環境変数を追加する。
方法①buildspec.ymlに環境変数を追加する
以下のenvにパラメータを入れます。
version: 0.2
+ env:
+ parameter-store:
+ DOCKER_USER: DOCKER_HUB_ID
+ DOCKER_PASSWORD: DOCKER_HUB_PASSWORD
phases:
pre_build:
commands:
- aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
- echo $DOCKER_PASSWORD | docker login -u $DOCKER_USER --password-stdin
commands:
DOCKER_HUB_ID
とDOCKER_HUB_PASSWORD
は、パラメータストアで設定した名前になります。
方法②CodePipelineのCodeBuildのステージに環境変数を追加する
こちらの方法で行う場合、DOCKER_HUB_ID
とDOCKER_HUB_PASSWORD
の名前は、/CodeBuild/
を頭につける必要があるため、あまりおすすめしません。
パラメータストアで作り直します。
DOCKER_HUB_ID
→ /CodeBuild/DOCKER_HUB_ID
DOCKER_HUB_PASSWORD
→ /CodeBuild/DOCKER_HUB_PASSWORD
環境変数の名前
と値
、タイプ
を以下のように追加します。
・DOCKER_USER
:/CodeBuild/DOCKER_HUB_ID
:パラメータ
・DOCKER_PASSWORD
:/CodeBuild/DOCKER_HUB_PASSWORD
:パラメータ
これによって、環境変数に設定した値
には、パラメーターストアで設定した値が入ります。
これで、ビルドで失敗する確率がぐっと下がりました。
ビルド時のエラー集①
サービスロールにSystems Manager
のssm:GetParameters
がアタッチされていない場合に発生します。
Phase context status code: Decrypted Variables Error Message: AccessDeniedException: User: arn:aws:sts::xxxxxxxxx:assumed-role/codebuild-wordpress-service-role/AWSCodeBuild-1b8f0170-e973-4b24-8b03-f61cfb95a403 is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:ap-northeast-1:xxxxxxxxxx:parameter/
ビルド時のエラー集②
環境変数の値が間違っています。
Phase context status code: Decrypted Variables Error Message: parameter does not exist:
ビルド時のエラー集③
CodeBuildに環境変数が設定されていない場合に発生します。
Error: Cannot perform an interactive login from a non TTY device
ビルド時のエラー集④
パラメータに設定しているユーザ名かパスワードが間違っています。
Error response from daemon: Get https://registry-1.docker.io/v2/: unauthorized: incorrect username or password
#参考
ビルドプロジェクトの設定の変更 (コンソール)
CodeBuildのIPガチャを回避
Docker Hub の Rate Limitに引っかかったのでdocker loginで対策