クラシコムアドベントカレンダー7日目は @ryosukes です。
最近、検証用のWebアプリをAWSが提供しているコンテナオーケストレーションサービスであるECSを使い構築しました。
そのときに、ECSのネットワークモードとしてコンテナ用に用意されている awsvpc
を選択したのですが、curl
がコンテナ上から行えず少しハマってしまいました。
TL;DR
- ネットワークモードで
awsvpc
を使う場合はプライベートサブネットを使いましょう
何が起きていたのか
Webアプリを起動した段階では、ブラウザでURLを叩くとレスポンスが返ってくる状態になっていました。しかし、curl
を使い外部とのやり取りを行うライブラリが実行されると、まったくレスポンスが返ってこないことに気づきます。
このとき、ログからはタイムアウトが起きてることしか読み取れませんでした。そのため、外部のエンドポイントの問題なのか、ネットワークの設定の問題なのか、それとも別の問題なのか判別してから対処する必要がありました。
事象調査
判別するのに、ECSのデータプレーンであるEC2上で curl
コマンドをCLI上で実行。これは問題なかった。
次に、コンテナ内に実際に入ってみて、 curl
コマンドを実行。このときに、外部のエンドポイントからまったくレスポンスが返ってこないことに気づきます。
このときに、ネットワークの設定の問題だということにあたりがつきます。
原因調査
あたりがついたところで、改めてECSのドキュメントを読み直しました。
このページの、8.c〜eらへんがどうやら怪しそう・・・。
8.dで、
[Subnet] で、使用するサブネットを選択するか、アベイラビリティーゾーンであらかじめ選択されるデフォルトのサブネットを使用します
とあります。デフォルトを僕は選択していました。
次。 8.e。ここに書いてある 自動割り当てパブリック IP
ですが、 ブラウザのAWSコンソール上からは DISABLED
しか選択できない状態になっています。ここだ。きっとこのあたりが原因だ…!
続いて読むと、 注記 があります。その中にこう書かれています。
コンテナインスタンスにパブリック IP アドレスがない場合は、NAT (ネットワークアドレス変換) を使用してこのアクセスを提供する必要があります。
こいつだ!
というわけで、プライベートサブネットを使用していなかったのが原因でした。
対応
プライベートサブネットを作成するためには、NATゲートウェイとルートテーブルの作成が必要です。
作成は非常に簡単。
- AWSのコンソール上から、VPCというサービスを選択
- サブネットを用意(新規・既存どちらでも)
- Elastic IPを用意(新規・既存どちらでも)
- NATゲートウェイを新規作成。2, 3で用意したサブネットIDとElastic IPを指定。
- 今作ったNATゲートウェイをターゲットにしたルートテーブルを作成
- プライベートサブネット用にサブネットを用意
- 6のサブネットのルートテーブルを、5で作ったルートテーブルにする
ここで作ったサブネットを使用するようにしたことで、今回のハマりポイントは解消しました。
まとめ
VPCやサブネットなどネットワークまわりは、AWSを初めて触るときや久しぶりに触るときは少しハマりやすいポイントかもしれません。
僕の場合は、以前VPCやプライベートサブネットに関してまとめたスライドを作ったことがあります。
これを思い出して、すぐ対応することができました。
VPCやサブネットに関してより詳しく知りたいといった場合、AWSのドキュメントがあるので、この辺を読めば理解できるかと思います。
おさえておきたいところですね。
以上、ECSを利用するときに地味にハマってしまったところでした(ドキュメントはよく読みましょう…)。
明日のアドベントカレンダー、担当は @kim_kou です!