🐟

AWSのNAT Gatewayに複数IPを付与した際の負荷分散

2023/02/11に公開

はじめに

いきなりですが、みなさんは2023/02/01にNAT Gateway(NAT GW)に最大8つのIPアドレスが付与できるアップデートが発表されたのをご存じでしょうか?
従前まではNAT GWには1つのIPアドレスしか付与できず、一意の宛先(※)に対して同時に55,000接続までしかできない制限がありました。
※一意の宛先 = 送信先IPアドレス、送信先ポート、プロトコル(TCP/UDP/ICMP)の一意の組み合わせ

アップデート詳細については以下を参照いただければと思います。

参考記事

注意点

  • 内容には最新の注意を払っていますが、今回の検証結果はあくまで参考としてください。
  • NAT GWにはPrivate IPをNATする機能もありますが、今回はPubric IPをNATする機能で検証しました。

モチベーション

今回のアップデートを見た際、まず初めに NAT GWに複数IPつけた際にどのように負荷分散されるのだろう・・・? と思いました。
しかし、AWS 公式ドキュメントを見ても1コネクションの定義についての記載はありましたが、負荷分散についての詳細は記載が無かったため実際に検証してみることにしました。

検証方法

実際にNAT GWでどのような負荷分散が行われているのか、以下条件で測定します。

  • VPC AとVPC Xを作成する
  • VPC AにはPublic SubnetとPrivate Subnetを作成する
  • VPC AのPublic SubnetにはNAT GWを作成し、2個のEIPを付与する(Primary:1個, Secondary:1個)
  • VPC AのPrivate SubnetにはEC2を1台作成する
  • VPC XにはPublic Subnetを作成する
  • VPC XのPublic SubnetにはEC2を1台作成する
  • VPC A EC2 --> VPC X EC2 に対し、NAT GW経由でTCP/UDP/ICMPのパケットを1万回投げる
  • VPC X EC2でtcpdumpコマンドでパケットキャプチャし、送信元IPを基に負荷分散されているか確認する

検証環境図

検証方法を見ただけではパッとわからないと思うので、簡単な環境構成図を記載しました。
今回の検証では赤矢印の経路で、 VPC A EC2 --> VPC X EC2に対してTCP/UDP/ICMPのパケットを1万回投げます。

検証をやってみた

検証結果については*.pcapファイルとして保存しておき、grepコマンドを用いて、どのように負荷分散が行われたか確認します。
検証は以下ステップでやりました。

  1. パケットキャプチャ(VPC X EC2)
  2. TCP/UDP/ICMP各パケットを投げる(VPC A EC2)
  3. 負荷分散確認(VPC X EC2)

なお、検証には、tcpdump, ncatコマンドの事前インストールが必要です。

TCPパケット

パケットキャプチャ時にはSYNフラグが設定されたパケットのみ収集します。
TCPパケットはtcpdumpコマンドで投げつけます。

パケットキャプチャ(VPC X EC2)

$ sudo tcpdump dst port 80 and "tcp[13] & 2 != 0" -w tcp_80.pcap

TCPパケット投げつけ(VPC A EC2)

$ for a in `seq 1 10000`;do (curl 15.152.167.195 > /dev/null 2>&1 & ); done

負荷分散確認(VPC X EC2)

$ tcpdump -r tcp_80.pcap | grep 52.199.221.82 | wc -l
reading from file tcp_80.pcap, link-type EN10MB (Ethernet)
    5043
$ tcpdump -r tcp_80.pcap | grep 13.113.211.199 | wc -l
reading from file tcp_80.pcap, link-type EN10MB (Ethernet)
    4957

UDPパケット

UDPパケットはncatコマンドで投げつけます。

パケットキャプチャ(VPC X EC2)

$ sudo tcpdump dst port 29292 -w udp_29292.pcap

UDPパケット投げつけ(VPC A EC2)

for a in `seq 1 10000`;do (ncat -uz 15.152.167.195 29292 > /dev/null 2>&1 & ); done

負荷分散確認(VPC X EC2)

$ tcpdump -r udp_29292.pcap | grep 52.199.221.82 | wc -l 
reading from file udp_29292.pcap, link-type EN10MB (Ethernet)
    5031
$ tcpdump -r udp_29292.pcap | grep 13.113.211.199 | wc -l 
reading from file udp_29292.pcap, link-type EN10MB (Ethernet)
    4969

ICMPパケット

パケットキャプチャ時にはエコー要求(タイプ:8)パケットのみ収集します。
ICMPパケットはpingコマンドで投げつけます。なお、-c 10000のように指定した場合はICMPパケット(エコー要求)のidが同一になり、負荷分散が行われないため、-c 1としています。

パケットキャプチャ(VPC X EC2)

$ sudo tcpdump 'icmp[0] == 8' -w icmp.pcap

ICMPパケット投げつけ(VPC A EC2)

$ for a in `seq 1 10000`;do (ping -c 1 15.152.167.195 > /dev/null 2>&1 & ); done

負荷分散確認(VPC X EC2)

$ tcpdump -r icmp.pcap | grep 52.199.221.82 | wc -l       
reading from file icmp.pcap, link-type EN10MB (Ethernet)
    5062
$ tcpdump -r icmp.pcap | grep 13.113.211.199 | wc -l      
reading from file icmp.pcap, link-type EN10MB (Ethernet)
    4938

検証サマリ

TCP/UDP/ICMPの各パケットを1万回ずつNAT GW経由で投げた際の負荷分散結果は以下の通りになりました。

プロトコル Primary
52.199.221.82
Secondary
13.113.211.199
TCP 5043 4957
UDP 5031 4969
ICMP 5062 4938

少しPrimaryのIPにパケットが多く振り分けられているように見えますが、おおむね均等に負荷分散しているようです。

今回は2つのEIPを付与する形で検証しましたが、おそらく3つ以上のEIPを付与したとしてもおおむね均等に負荷分散を行ってくれると思います。
また、AWS公式ドキュメントに記載の通り、2023/02/01の機能リリース時点ではNAT GWに3つ以上のEIPを付与するためにはクオータ上限増加のリクエストが必要です(AWS Quotasからの申請は対応しておらず、AWS Support経由での申請が必要)

You are limited to associating 2 Elastic IP addresses to your public NAT gateway by default. You can increase this limit by requesting a quota adjustment. For more information, see Elastic IP addresses.

まとめ

AWS公式ドキュメントからでは読みきれないNAT GWの負荷分散について検証を行いました。
実際に手を動かすことで知識の定着や新しい気づきを得られることは多いと思います。

今回の記事を読んでくださった方が少しでもAWSに興味を持ってくださったら幸いです。

ここまで読んでくださってありがとうございました。

Discussion