最初に押さえるポイント
喫茶店のたとえで理解する
NAT ゲートウェイのタイムアウトは「喫茶店の席管理」にそっくりです。席に座ったまま何も注文せず放置すると、店員が強制的に席を片付ける仕組みです。
| 喫茶店のたとえ | AWS の実際 |
|---|---|
| 喫茶店の店員(席管理係) | NAT ゲートウェイ |
| お客さん(席に座っている人) | TCP 接続(クライアント) |
| 注文や会話がない放置時間 | アイドル状態(データ転送なし) |
| 「5分50秒ルール」(放置制限時間) | 350秒のアイドルタイムアウト |
| 「お会計をどうぞ」(丁寧に退店を促す) | FIN パケット(正常切断) |
| 「退店してください!」(強制的に追い出す) | RST パケット(強制リセット) |
| 定期的にコーヒーを追加注文する | TCP Keepalive(定期的な生存確認パケット) |
NAT ゲートウェイのタイムアウト動作
NAT ゲートウェイは、プライベートサブネットのリソースがインターネットに通信する際の出口となるサービスです。内部的に接続の追跡テーブル(コネクショントラッキング)を維持しますが、リソース管理のために350秒間データ転送がない接続を自動的に終了させます。
FIN パケット vs RST パケット
TCP 接続の終了には2種類の方法があります。喫茶店のたとえに置き換えると、その違いが明確になります。
「お会計をどうぞ」
店員がお客さんに丁寧にお会計を促す。お客さんは荷物をまとめ、支払いを済ませてから退店。双方合意のうえで接続を閉じる、正常な手順。
「退店してください!」
店員がテーブルを片付けてお客さんを強制退店させる。お客さんは荷物を取りに戻ることもできない。NATゲートウェイのタイムアウト後はこちらが送信される。
TCP 接続のライフサイクル
TCP 接続は4つの段階を経て進行します。NAT ゲートウェイのタイムアウトは「③ アイドル状態」で発生します。
TCP Keepalive で接続を維持する
TCP Keepalive は、アイドル状態の接続を維持するためにTCPプロトコルに組み込まれた仕組みです。一定間隔で小さな「生存確認」パケットを送信し、ネットワーク機器に「この接続はまだ使っています」と伝えます。
数値で見る問題と対策
具体的な対策と設定方法
TCP Keepalive を有効化
一定間隔でKeepaliveパケットを送信し、NATゲートウェイに対して接続がアクティブであることを通知します。
間隔を300秒以下に設定
NAT GW のタイムアウト(350秒)よりも短い間隔に設定することで、タイムアウト前にアイドルタイマーをリセットします。
Linux(sysctl)での設定
# TCP Keepalive を300秒で有効化(NAT GW 350秒タイムアウト対策) # アイドル状態からKeepaliveを送信するまでの時間 net.ipv4.tcp_keepalive_time = 300 # Keepalive応答がない場合の再送間隔(秒) net.ipv4.tcp_keepalive_intvl = 60 # 応答がない場合に諦めるまでの再送回数 net.ipv4.tcp_keepalive_probes = 5
# 即時反映する場合 sudo sysctl -w net.ipv4.tcp_keepalive_time=300 sudo sysctl -w net.ipv4.tcp_keepalive_intvl=60 sudo sysctl -w net.ipv4.tcp_keepalive_probes=5 # 永続化する場合は /etc/sysctl.conf に追記して sudo sysctl -p
アプリケーションレベルでの設定(Python / boto3)
import socket # ソケットを作成してKeepaliveを有効化 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP Keepalive を有効にする sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # Keepalive 送信開始までのアイドル時間(秒) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 300) # Keepalive パケットの再送間隔(秒) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 60) # 応答なしで切断するまでの再送回数 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5)
よくある質問
いいえ、NAT ゲートウェイのアイドルタイムアウト(350秒)はAWSによって固定されており、ユーザーが変更することはできません。そのため、クライアント側で TCP Keepalive を有効にしてタイムアウトを回避する必要があります。
Amazon CloudWatch の「NATGateway」名前空間で確認できます。IdleTimeoutCount メトリクスが上昇している場合、タイムアウトが発生していることを示しています。CloudWatch アラームを設定して監視することを推奨します。
はい。EC2 からプライベートサブネット経由で RDS に接続しており、NAT ゲートウェイを経由する構成の場合、長時間実行クエリ中にタイムアウトが発生する可能性があります。ただし、VPC内の通信(同一VPC内のRDS接続など)はNATゲートウェイを通らないため、影響を受けないケースも多いです。外部DB接続時に特に注意が必要です。
はい。NAT ゲートウェイは UDP の場合は120秒のアイドルタイムアウトが適用されます。TCPの350秒よりも短いため、UDP通信ではさらに注意が必要です。
ALB(Application Load Balancer)にもアイドルタイムアウト(デフォルト60秒、変更可能)がありますが、こちらはユーザーが値を調整できます。NLB(Network Load Balancer)は350秒の固定タイムアウトです。NATゲートウェイと同様に、NLBではクライアント側でのKeepalive設定が重要になります。
まとめ
| 項目 | 内容 |
|---|---|
| タイムアウト値 | 350秒(固定・変更不可) |
| タイムアウト時の挙動 | RST パケットを送信(接続の再利用不可) |
| 監視メトリクス | CloudWatch の IdleTimeoutCount |
| 対策 | TCP Keepalive を 350秒未満に設定 |
| 推奨 Keepalive 間隔 | 300秒(tcp_keepalive_time = 300) |
| Linux デフォルト値 | 7200秒(そのままでは対策にならない) |