自分たちで管理している Docker レジストリに対して、AWS EC2 から docker pull しています。
今回、処理速度向上およびネットワーク負荷低減を目的として、AWS ECR プルスルーキャッシュを導入しようと進めていました。
基本的に設定は正しくできているはずでしたが、なぜかプルスルーキャッシュ有効化後に docker pull がエラーになる問題が発生し、その原因調査の過程を備忘録するものです。
まず我々の運用の前提が以下です。
前提 #
- 管理している Docker レジストリでは、リクエスト元 IP アドレスの許可リストを用いてアクセス制御を行っている
- AWS EC2 のリクエストは NAT ゲートウェイを経由で行っていて、NAT ゲートウェイの IP アドレスはホワイトリストに登録されている
結論 #
最初に結論を書いてしまいます。
- プルスルーキャッシュを使わずに、EC2 上で docker pull した場合は NAT ゲートウェイ経由となるが、
- プルスルーキャッシュを使うと、AWS が管理している IP アドレスからリクエストとなる。
そのため、許可リストにマッチせずにエラーになる。
では対策は … AWS が管理している IP アドレスをすべて許可リストに追加するのはセキュリティ的に問題があり、今回の前提のもとだとプルスルーキャッシュは諦めたほうが良さそうということで別案で対応になりそうです。
過程の記録 #
ステップ 1: エラー発生 #
ECR のプルスルーキャッシュルールを設定し、docker pull するコマンドの向き先をプルスルーキャッシュのリポジトリ URI に変更して実行したところ、以下のようなエラーが発生。
Error response from daemon: unknown: failed to resolve reference "********.dkr.ecr.ap-northeast-1.amazonaws.com/********:latest" ...(中略)... : 403 Forbidden
これまで通り、プルスルーキャッシュではなく、管理している Docker レジストリの URI に向けて docker pull してみると、問題なく成功する。
つまりプルスルーキャッシュが起因していることがわかる。
ステップ 2: 別レジストリだとどうなるか? #
適当に用意した Docker レジストリに対してプルスルーキャッシュを設定してみるとどうなるかの確認。
適当な GitHub アカウントで GitHub Container Registry (GHCR) を作成して、そこに対してプルスルーキャッシュを設定する。

その後 EC2 から docker pull してみると、エラーにならず成功した。ECR 上にもイメージキャッシュ用のリポジトリができていて、そこにイメージが保存されていることも確認できた。
つまり ECR プルスルーキャッシュと Docker レジストリの組み合わせで発生する問題だとわかる。
ステップ 3: プルスルーキャッシュ時のリクエスト元 IP アドレスの確認 #
IP アドレス制限に引っかかっていることを疑う。プルスルーキャッシュ経由で docker pull されたときのリクエスト元 IP アドレスを確認することを試みた。
しかし GHCR だとそのログが見れそうになかった。
そのため、詳細なログが確認できる Azure Container Registry (ACR) を用意して、そこに対してプルスルーキャッシュを設定する方向で進めた。
Azure 触るの初だったためスクショ貼りながら備忘録。
Docker レジストリを作成する。Container registries ページに移動し、Create ボタンを押す。

内容を入力する。Resource group は未作成ならばこのタイミングで新規作成する。Review + create で確定する。

作成完了。Monitoring > Diagnostic settings からログの設定を行う。

Add diagnostic setting を押してログ設定を作成できるのだが … その前に Log Analytics workspace を作成しておく必要があるので、ここでは進まない。

Log Analytics workspace ページに移動し、Create ボタンを押す。

内容を入力する。Review + create で確定する。

Log Analytics workspace の作成が完了したら、再度レジストリの Diagnostic setting の画面に戻り、Add diagnostic setting を押す。
内容を入力する。
下記2つにチェックを入れ、
- RepositoryEvent logs
- Login Events
そして Send to Log Analytics workspace にチェックを入れて、先ほど作成した Log Analytics workspace を選択する。
Save を押して設定完了。

ちなみに私の場合は Save を押したら以下のエラーが出たが、何もせず、しばらく待ってから再度 Save を押したら成功した。
Azure で Add diagnostic setting をするのが初めてだったので、初回作成時には裏で何か処理が走る必要があり、そのタイミングによってはこのエラーになるのかもと予想。

ここまでレジストリの設定はひと通り完了。
このレジストリにログインするための認証情報は Settings > Access keys から確認できる。

ローカル PC からこのレジストリに適当なイメージをプッシュしておく。
プッシュされたイメージは Services > Repositories から確認できる。

ここまできたら AWS ECR のプルスルーキャッシュの設定を行う(手順や画像の掲載は省略)。
設定が終わったら ECR に対して docker pull する。そうするとプルスルーキャッシュが働いて、ACR に対してリクエストが飛ぶ。
ここまできたら、ACR のログを確認してみる。
レジストリの Monitoring > Logs に進み、Show registry events repo… の Run ボタンを押す。

以下のようにログがリスト表示される。今回は一度だけ docker pull したのだが、で、プルスルーキャッシュ経由で4回リクエストが飛んでいることがわかる。

プルダウンを開くと詳細が確認でき、CallerIpAddress という項目がリクエスト元の IP アドレスを表している。

たとえば上記画像だとリクエスト元 IP アドレスは 54.150.37.21 である。
これは AWS が管理している IP アドレスの一つであることがわかる。AWS が管理している IP アドレスは以下のページで公開されている。
- AWS IP address ranges - Amazon Virtual Private Cloud
- https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html
- ip-ranges.json: https://ip-ranges.amazonaws.com/ip-ranges.json
… ということで冒頭の結論の通り。