2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プライベートサブネットの ECS コンテナが ECR から pull できない問題と解決方法

2
Last updated at Posted at 2025-12-17

はじめに

パブリックサブネットのECSでコンテナが動いたので、次はセキュリティを考えてプライベートサブネットに配置してみよう。そう思って設定を変更したら、タスクが起動しなくなった...という話です。この記事では、その時の問題と解決方法を共有します。

やりたかったこと

AWSでWebサイトを公開する方法として、最初はS3の静的ホスティングを検討していました。しかし、せっかくなのでコンテナ技術を学びたいと思い、nginxコンテナを使うことにしました。

コンテナを選んだ理由:

  • コンテナ技術の学習: DockerやECSといったコンテナ技術を実際に触って学びたかった
  • 設定の自由度: nginxの設定ファイルを自分で書くことで、Webサーバーの動作を細かく制御できる
  • 今後の応用: 最初は静的コンテンツだけでも、将来的にバックエンドAPIを追加したり、認証機能を組み込んだりと拡張しやすい

なぜプライベートサブネットに配置したかったのか

最初はパブリックサブネットでコンテナを動かしていましたが、AWSのベストプラクティスやセキュリティの記事を読むうちに「アプリケーションはプライベートサブネットに置くべき」ということを知りました。

プライベートサブネットに置く理由:

  • コンテナに直接アクセスされるリスクを減らせる
  • ALB(ロードバランサー)経由でのみアクセスできるようにする

「よし、サブネットを変更するだけだから簡単だろう」と思っていたのですが...ここで問題が発生しました。

遭遇した問題

ECS タスクが起動しない

プライベートサブネットにECSタスクを配置してデプロイしたところ、さっきまで動いていたコンテナが突然起動しなくなりました。タスクは一瞬起動するものの、すぐに停止してしまいます。

サブネットを変えただけなのに、何が起きたのか...?

原因の特定プロセス

最初は何が問題なのか全く分かりませんでした。というのも、CloudWatch Logsにログが表示されない状態だったからです。

タスク定義ではログドライバーをawslogsに設定していたのに、CloudWatch Logsのコンソールを見ても何も表示されません。ログが確認できないので、エラーの詳細も分からず、原因の特定に時間がかかりました。

後で分かったのですが、これもプライベートサブネットからCloudWatch Logsにアクセスできないことが原因でした。

なんとかECSコンソールのstoppedタスクの詳細を確認したところ、以下のようなエラーメッセージが表示されていました:

CannotPullContainerError: pull image manifest has been retried 5 time(s): 
failed to resolve ref: failed to do request: 
Head "https://*****.dkr.ecr.ap-northeast-1.amazonaws.com/v2/my-nginx/manifests/latest": 
dial tcp *.*.*.*:443: i/o timeout

エラーメッセージを読み解いてみます:

  1. CannotPullContainerError → コンテナイメージを取得できない
  2. pull image manifest has been retried 5 time(s) → 5回リトライしても失敗
  3. dial tcp *.*.*.*:443: i/o timeout → 443番ポート(HTTPS)への接続がタイムアウト

つまり、ECRからコンテナイメージをダウンロードしようとしているが、接続できないということです。

ここで気づいたのが、「プライベートサブネットにはインターネットへの経路がない」という基本的な事実でした。

パブリックサブネットにいた時は、インターネット経由でECR(コンテナイメージの保管場所)にアクセスできていました。しかしプライベートサブネットには外への道がないので、ECRに接続できなくなってしまったのです。

同様に、CloudWatch Logsにもアクセスできないため、ログも送信できなかったというわけです。

解決方法

プライベートサブネットからECRにアクセスするには、VPCエンドポイントを使用する必要があります。

1. VPC エンドポイントの設定

ECSタスクがプライベートサブネットからECRのイメージをpullするには、以下の4つのVPCエンドポイントが必要です:

① ECR API用エンドポイント (com.amazonaws.ap-northeast-1.ecr.api)

  • ECRのAPIリクエストに使用
  • 認証や認可の処理を担当
  • タイプ: Interface型

② ECR Docker用エンドポイント (com.amazonaws.ap-northeast-1.ecr.dkr)

  • Dockerクライアントがイメージレイヤーをpullする際に使用
  • タイプ: Interface型

③ S3用ゲートウェイエンドポイント (com.amazonaws.ap-northeast-1.s3)

  • ECRはイメージレイヤーの実体をS3に保存しているため、S3へのアクセスも必要
  • タイプ: Gateway型(コスト: 無料)

④ CloudWatch Logs用エンドポイント (com.amazonaws.ap-northeast-1.logs)

  • ECSタスクのログをCloudWatch Logsに送信するために必要
  • これがないとログが見れず、デバッグが困難になる
  • タイプ: Interface型

設定手順:

  1. VPCコンソールで「エンドポイント」を選択
  2. 「エンドポイントの作成」をクリック
  3. 上記4つのサービス名をそれぞれ選択して作成
  4. ECR用とCloudWatch Logs用の3つはプライベートサブネットを選択
  5. S3用はルートテーブルを選択

2. セキュリティグループの設定

VPCエンドポイント(Interface型)には、適切なセキュリティグループの設定が必要です。

VPCエンドポイント用セキュリティグループ

インバウンドルール:

Type: HTTPS
Protocol: TCP
Port: 443
Source: ECSタスクのセキュリティグループ

ECSタスク用セキュリティグループ

アウトバウンドルール:

Type: HTTPS
Protocol: TCP
Port: 443
Destination: VPCエンドポイントのセキュリティグループ

この設定により、ECSタスクからVPCエンドポイント経由でECRへ安全に通信できるようになります。

3. 最終構成図

Internet
    |
    v
  [ALB] (パブリックサブネット)
    |
    v
[ECS Task - nginx] (プライベートサブネット)
    |
    +---> [VPC Endpoint: ECR API]
    +---> [VPC Endpoint: ECR Docker]
    +---> [VPC Endpoint: S3 Gateway]
    +---> [VPC Endpoint: CloudWatch Logs]
          |
          v
        [ECR / CloudWatch Logs] (AWSサービス)

ユーザーからのリクエストはALB経由でnginxコンテナに到達し、コンテナのイメージpullはVPCエンドポイント経由でECRから行われます。また、コンテナのログはCloudWatch Logsに送信されます。

ハマったポイント

VPCエンドポイントの種類

最初、ECR用のエンドポイントを2つ作成する必要があることを知らず、ecr.apiだけを作成してしまい、同じエラーが継続しました。ECRではAPIとDockerの両方のエンドポイントが必須なので注意が必要です。

S3エンドポイントの見落とし

ECRがS3にイメージレイヤーを保存していることを最初は知らず、S3のゲートウェイエンドポイントを設定し忘れていました。ECR用の2つのエンドポイントだけでは不十分で、S3も必要になります。

CloudWatch Logsエンドポイントの見落とし

ECRからのpullは成功したのに、なぜかタスク定義のログ設定で指定したログが見れない...ということがありました。これもCloudWatch Logs用のVPCエンドポイントが必要でした。ログが見れないとデバッグが大変なので、最初から設定しておくことをおすすめします。

セキュリティグループの設定漏れ

VPCエンドポイントを作成しただけでは通信できず、適切なセキュリティグループの設定が必要でした。特に、ECSタスクからVPCエンドポイントへのHTTPS(443)通信を許可する設定を忘れがちです。

まとめ

学んだこと

  • プライベートサブネットからAWSサービスにアクセスするには、VPCエンドポイントが必要
  • ECRからイメージをpullするには、ECR API、ECR Docker、S3の3つのエンドポイントが必要
  • ログを確認するには、CloudWatch Logs用のVPCエンドポイントも必要(デバッグに必須!)
  • VPCエンドポイントにも適切なセキュリティグループの設定が必要
  • ネットワーク構成を理解することで、セキュアなアーキテクチャを構築できる

コスト面の考慮点

  • Interface型VPCエンドポイント: 約0.01 USD/時間 × 3 = 約22 USD/月
    • ECR API、ECR Docker、CloudWatch Logs
  • Gateway型VPCエンドポイント(S3): 無料
  • データ転送料: 0.01 USD/GB

頻繁にデプロイを行わない場合、VPCエンドポイントのコストは比較的低く抑えられます。一方で、セキュリティ向上のメリットは大きいため、本番環境では導入を推奨します。

おわりに

プライベートサブネット構成は最初は複雑に感じるかもしれませんが、一度理解すればセキュアで拡張性の高いインフラを構築できます。同じ問題で困っている方の助けになれば幸いです。

質問やフィードバックがあれば、コメント欄でお気軽にどうぞ!

参考資料

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?