😽

ECS(EC2起動タイプ)aws-vpcモードで、コンテナに接続できずにハマった話 #初心者

2024/11/04に公開1

概要

ある時、ECSをEC2起動タイプ & aws-vpcモードで起動していたのだが、起動しているはずのコンテナにインターネット接続できなかった。

端的にまとめると、ネットワークモード「aws-vpc」には特有の動作があり、EC2とコンテナとENIの立ち上がりが少し特殊であることが原因であった。

本記事では、初めに状況と対処法を記載する。
その後、aws-vpcモードの動作を含め、原因の詳細を記載する。

結論

前提

下図のような構成(イメージ図)で、ECSのタスクを起動していた。

ECS構成サマリ

  • ECSのクラスタには、EC2(オートスケーリンググループ)を割り当てている。
  • EC2はパブリックサブネットにあり、パブリックIPアドレスも割り当てられている。
  • ECSのサービスを、ネットワークモードをaws-vpcに設定している。
  • タスク定義で、コンテナのポート(3000)をポートマッピングで設定している。

※セキュリティ的に良くないが、開発上の利便性からEC2をパブリックサブネットに配置していた。

現象

上記の図のnote部分に記載の通り。
タスクを起動しているEC2にパブリックIP経由でアクセスしようとすると接続できない(タイムアウトになる)
例)curl http://203.0.113.2:3000 の結果、タイムアウト

対処法

ECSの設定で、EC2起動タイプ & aws-vpcモードを使いたい場合と、それ以外でもよい場合で分けて対処法を記載する:

EC2起動タイプ & aws-vpcモードを使いたい場合

EC2起動タイプ & aws-vpcモードでコンテナに接続するには、以下の2通りを使用する必要がある。

  • 同じVPCに設置したロードバランサを経由させて、EC2にルーティングさせる。
    • ※サービスを作成する際に、オプションでロードバランサを設定できる。
  • 同じVPC内からプライベートIPアドレスで接続する。
    • IPアドレスは、ECSの起動しているタスクの設定ページ > ネットワーキングタブに行くと見つけられる。
    • ※原因の詳細で記載するが、EC2には複数のプライベートIPアドレスが割り当てられているので、タスクの設定ページを確認する必要がある。

※公式ドキュメントの以下の記載の通り。

インバウンドのネットワークアクセスは、プライベート IP アドレスを使用する VPC 内からのものか、その VPC からロードバランサーを経由させルーティングされたものである必要があります。

EC2起動タイプ & aws-vpcモード以外を使う場合

EC2起動タイプ & aws-vpcモードを前提としないなら、以下の方法もあり得る:

  • ネットワークモードとして、bridgeモードを使用する。
    • この場合、EC2のパブリックIPアドレス経由でコンテナに接続ができる。
    • ただし、AWSとしての推奨はaws-vpcモードなので注意。公式
  • EC2ではなく、Fargateを使用する。
    • サーバレスで、細かな設定は不要。
    • サービスを作成する際、ネットワーキングのオプションからパブリックIPを有効化できる。

対処法の軽い補足

  • 初歩的なミスとして、セキュリティグループとネットワークACLの許可ポリシーが正しいことも確認するとよい(問題なければ、一度に全て許可すると問題の切り分けがしやすい)。

原因の詳細

aws-vpcモードとは?

以下の記事に、他のネットワークモードとの比較と合わせてわかりやすく記載されている:
https://zenn.dev/fdnsy/articles/43b7f4d745ed1f

以下では、本事象に関連するIPアドレスあたりをもう少し詳しく記載する。
※「aws-vpcモードでは、1つのコンテナに1つのENIが割り当てられる」ということを最低限理解していることを前提にします。

ENIとEC2とコンテナの関係

今回の現象が起きた際のネットワーク構成図を以下に示す。

ネットワーク構成

※セキュリティの観点で、ECS(EC2)自体をプライベートサブネットに配置したほうがよい。
 色々試すうえで、簡単にインターネット接続できた方がよかったので、上記の配置にしていた。

なお、aws-vpcモードで作成されるENIはプライベートサブネットしかサポートされていないらしい(公式
※FargateならパブリックIPを有効化できる

原因まとめ

結局、ENI 1とENI 2が別々に存在することが原因だった。
ENI 1があるため、EC2(コンテナ)にインターネット接続できるように見えるが、実際にはコンテナに繋がっているENI 2に接続する必要があり、ENI 2がプライベートなので接続できなかったのである。

GitHubで編集を提案

Discussion

MeguriMeguri

突然のコメント失礼します。ECSのaws-vpcモードの複雑な動作に関する詳細な説明が非常に役立ちます。ENIの仕組みと接続の問題についての理解が重要であることに共感します。もし、ネットワーク設定やAPIのテストでお困りでしたら、ECHOAPIというツールはオフラインでもAPIの動作を確認でき、開発プロセスがスムーズになるのでおすすめです