以前Amazon ECS,Nginxを利用したプロキシサーバを構築した際、ポート枯渇にハマった時の話を共有したいと思います。
下記の構成でオンプレの機器からインターネット接続するためのプロキシサーバをAWSに構築していたいました。
元々下記のAWS公式サイトを参考にNAT gatewayで宛先IPアドレス一つにつき、同時接続数55000の制限があることを認識していたのですが、
https://repost.aws/ja/knowledge-center/vpc-resolve-port-allocation-errors
システム全体で処理できる同時接続数(Network Load BalancerのActiveflowcount)が元々の想定よりも大幅少ない約14000程で通信エラーが多発するという問題が発生しました。
調査の中で、VPCフローログを確認したところ、Amazon ECSとNAT gateway間の通信で使用してるsrcポートが想定よりも少ないことが分かりました。
Amazon ECSのTask一つ当たりで利用するsrcポートが元々1-65535を想定していたのですが、32768-60998の偶数ポートのみ約14000程度しか使用されてないことを確認しました。
VPCフローログの確認結果
interface-id | srcaddr | dstaddr | srcport | dstport |
---|---|---|---|---|
eni-XXX | Amazon ECSTaskのIPアドレス | NAT gatewayのIPアドレス | 32768 | 443 |
eni-XXX | Amazon ECSTaskのIPアドレス | NAT gatewayのIPアドレス | 32768 | 443 |
~ | ~ | ~ | ~ | ~ |
eni-XXX | Amazon ECSTaskのIPアドレス | NAT gatewayのIPアドレス | 60998 | 443 |
調査をしたところ、IPv4のTCP通信の仕様で、srcIPとdetIPの組み合わせ一つにつき使用できるポート数が限られており、
今回dstportが443で固定だったため、srcportを使い切ってポート枯渇が発生してしまったことが原因でした。
XXX.XXX.XXX.XXX:srcprt1 ⇒ YYY.YYY.YYY.YYY:443
XXX.XXX.XXX.XXX:srcprt2 ⇒ YYY.YYY.YYY.YYY:443
~
こちらの問題の解決策として、Amazon ECSのTaskの数を増やしてsrcIPを増やすことでポート枯渇を防ぐことにしました。
AAA.AAA.AAA.AAA:srcprt1 ⇒ YYY.YYY.YYY.YYY:443
AAA.AAA.AAA.AAA:srcprt2 ⇒ YYY.YYY.YYY.YYY:443
BBB.BBB.BBB.BBB:srcprt1 ⇒ YYY.YYY.YYY.YYY:443
BBB.BBB.BBB.BBB:srcprt2 ⇒ YYY.YYY.YYY.YYY:443
~
システム全体のAWSコストはなるべく抑えるようにTask一つあたりのCPU/メモリは元々よりも減らしてます。
※NAT gatewayを増やす方法でも実装できますが、NAT gatewayは費用が高く、
コストパフォーマンスが悪すぎるので、Amazon ECSのTask数を増やす方針にしました。
構成変更をした後、再度動作確認をしたところ、Amazon ECSのTaskの数増加に伴って、
システム全体で処理できる同時接続数を拡張していくことができることを確認できました。
※3/14追記
Amazon ECSのオートスケーリングについても検討しましたが、AWSの監視運用機能をAWSサービスではなく、別の製品で実装していたため、
Amazon ECSのTask数が変わる度に、監視製品側のconfig修正もやらないといけない仕様になっていたため、オートスケーリングの実装は断念しました。
(頑張れば実装できたかもしれませんでしたが、スケジュール優先で断念しました)
また、システム全体で処理できる同時接続数については、CloudWatchでNetwork Load BalancerメトリクスのActiveFlowCountを確認しています。
CloudWatchアラームで、Network Load BalancerのActiveFlowCountの値を超えると通知が来る設定を入れておき、
通知が来たらAmazon ECSのTask数増設を実施するという運用にしています。
■まとめ
srcIP,destIPの組み合わせ一つにつき利用できるポート数に上限がある。
ポート枯渇が発生しないようにシステム内のIPアドレスの数を増やす設計検討が必要
Amazon ECSのTask数を増やして、IPアドレスを増やすことでシステム全体の同時接続数上限を増やすことができます。