概要
AWSのECS構築をしようとしていた時のつまずきメモです。
プライベートサブネット内のインスタンスからVPCエンドポイント経由でECRと疎通しようとしたら、コマンド入力後に固まってタイムアウトになってしまう状況に陥りました。
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
aws ecr --region ap-northeast-1 get-login-password | docker login --username AWS \
--password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/[リポジトリ名]
# ... しばらく反応なし ...
# Connect timeout on endpoint URL: "https://api.ecr.ap-northeast-1.amazonaws.com/"
# Error: Cannot perform an interactive login from a non TTY device
Google検索のサジェストに
「ECR 反応ない」「ECR 返ってこない」
とか出てきたので、同じように困っている人に向けて解決の軌跡を残しておきます。
前提
まずプライベートサブネットからECRと通信するためには、インタフェース型のVPCエンドポイント2種類が必要になります。
com.amazonaws.region.ecr.dkr
このエンドポイントは、Docker Registry API に使用されます。push や pull などの Docker クライアントコマンドでは、このエンドポイントが使用されます。
com.amazonaws.region.ecr.api
このエンドポイントは、Amazon ECR API への呼び出しに使用されます。DescribeImages や CreateRepository などの API アクションは、このエンドポイントに移動します。
加えてEC2インスタンスにECRと疎通するためのポリシーのアタッチが必要になります。
上記は設定済みとして話を進めます。もしまだの方は設定をしてみて下さい。
結論
通信をするインスタンスとVPCエンドポイントとの間で、適切なセキュリティグループが設定されていなかったのが原因でした。
インスタンス⇔ECRとの間ではhttpsで通信を行うため、互いのセキュリティグループのインバウンドルールで443番ポートを受け入れるようにしておく必要があります。
この設定を忘れると通信が到達できずに、今回のように原因究明困難なタイムアウトとなってしまいます。
設定後、無事に疎通できるようになりました。
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
aws ecr --region ap-northeast-1 get-login-password | docker login --username AWS \
--password-stdin https://${AWS_ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/[リポジトリ名]
# Login Succeeded
おまけ
パプリックサブネットからECRと通信をする場合はVPCエンドポイントを通る必要はありませんが、
既にエンドポイントがVPC内に作成されている場合はそちらを経由する動きになります。
パブリックサブネットなのにECRと通信ができない!という場合は、VPC内にECRへのエンドポイントが作成済みでないか見直してみるといいでしょう。