【入門編】 UDPプロキシおよびDNSフォワーディングにおけるNATセッション管理 – クラウド&コンテナネットワーク実践ガイド

こんにちは!クラウドの裏側でうねるパケットの流れを想像するのが大好きなSREの筆者です。

インフラの世界へ足を踏み入れたばかりの頃、「あれっ、TCPだと問題ないのに、なぜかUDP(特にDNSやSyslog)を使うと、時々通信が途切れるんだよなぁ…」と首を傾げた経験はありませんか?

TCPは通信の開始と終了の挨拶(ハンドシェイク)をしっかり行い、相手が受け取ったかを確認しながら進む「お行儀の良い優等生」ですが、UDPは「細かいことは気にすんな!とにかく投げるぜ!」という、ちょっとお気楽でパワフルな一匹狼です。

今回は、このステートレス(状態を持たない)なUDPトラフィックが、AWSやGCPといったパブリッククラウドの「NATゲートウェイ」を通過する際、裏側でどう扱われているのか。そして、パケットロスが起きたときにどんなドラマが起きているのかを、身近な例えを交えながら一歩ずつ紐解いていきましょう!

—

1. 郵便配達で例える「UDP」と「NATゲートウェイ」の仕組み

まずは、パケットの動きをイメージしやすくするために、私たちの身近な「郵便配達」に置き換えて考えてみましょう。

UDPパケットは「一言メモのポスティング」

TCP通信が「お互いに電話をつないで会話する(セッションを維持する)」のに対し、UDP通信(例えばDNSの問い合わせなど)は、街頭のアンケートBOXに「〇〇の住所を教えて!」と書いたメモ用紙をポロリと投函するようなものです。
メモを投げたら、相手がそれを読んだかどうか、投げた側はその場では確認していません。「返事が来たらラッキー、来なかったらもう一回投げればいっか!」という世界観です。

クラウドのNATゲートウェイは「街の優秀な郵便局の窓口」

プライベートサブネット(外の世界から直接見えない隠れ家エリア)にある私たちのサーバーやコンテナが、インターネット上の外の世界と通信するためには、クラウドの「NATゲートウェイ」という共通の窓口を通る必要があります。

プライベート空間から外へ向けてUDPのメモ(パケット)が発射されると、NATゲートウェイはこう記録します。

> 「おっと、プライベートIPアドレス 10.0.1.100 のサーバーから、外のDNSサーバー 8.8.8.8 宛てにUDPのメモが投げられたぞ。返事が返ってきたときに元の差出人へ戻せるように、NATゲートウェイ自身のIPアドレス 203.0.113.50 の一時的な窓口(ポート番号)を割り当てておこう!」

この一時的な「メモの控え(マッピング情報)」が、インフラの世界でいう「NATセッション」です。

—

2. なぜUDPのNATセッションは「忘れっぽい」のか?

ここで大きなポイントがあります。TCPであれば、通信が終了するときに「お疲れ様でした!」と終わりの挨拶(FINパケット)が飛ぶため、NATゲートウェイは「あ、このセッションはもう用済みだから、控えのメモを捨てよう」と綺麗に片付けることができます。

しかし、UDPはステートレス(状態を持たない)なので、「これで会話が終わったよ」という終了の合図がありません。

そのため、クラウドのNATゲートウェイは、次のようなルールでセッションの控えを管理しています。

  • 「最後にこのメモのやり取りがあってから、一定時間(タイムアウト時間)何も通信がなかったら、もうこの用事は終わったとみなして、窓口の控えをシュレッダーにかけちゃおう!」

このタイムアウト時間が、パブリッククラウドによってあらかじめ決まっています。
例えば、一般的なクラウド環境のUDPセッションタイムアウトは、おおむね 30秒 から 180秒 程度に設定されていることが多いです。

タイムアウトが引き起こす「悲劇」

もし、あなたのアプリケーションが「たまにしかDNSの名前解決をしない(数分おき)」、あるいは「Syslogをポツリポツリとしか送らない」という設定だったとしましょう。

1. 1回目にUDPパケットを投げる $\rightarrow$ NATゲートウェイにセッションが作られて無事に届く。
2. そのまま4分間、全く通信を行わない。
3. NATゲートウェイは「うーん、もう何もないみたいだから、この窓口の控えは処分しよっと(タイムアウト)」とセッションを削除する。
4. 4分後に、2回目のUDPパケットを投げる。

さあ、4番目の瞬間、何が起きるでしょうか?
外の世界から返ってきた返事(あるいは新しく送ったパケット)がNATゲートウェイに届いたとき、「あれっ? この宛先の控え、さっきシュレッダーにかけたぞ…誰宛てだったっけ?」となり、NATゲートウェイはパケットをどこに飛ばせばいいか分からず、無慈悲にドロップ(破棄)してしまいます。

これが、ステートレスなUDPトラフィックで突如として通信が途切れる、現場でよくある原因の正体です。

—

3. パケットロス発生時の再送制御メカニズム

では、もし運悪くパケットロスやNATセッションのタイムアウトに遭遇してしまったとき、アプリケーションやネットワークはどのようにリカバリーするのでしょうか?

ここでもう一度、DNSやSyslogの世界を覗いてみましょう。

アプリケーション層での「力技の再送」

UDP自体には、TCPのような「届いたよ!」という確実な確認応答(ACK)や、順番がバラバラになったときの並び替え機能がありません。
そのため、パケットロスが起きたときの再送制御は、UDPの上で動いているアプリケーション自身が責任を持ちます。

例えば、代表的なDNSクライアントライブラリやシステム(glibc の resolv.conf など)の挙動を見てみましょう。

1. DNSサーバーへ「このドメインのIPは?」とUDPで質問を投げる。
2. もし、タイムアウト(例えば 5秒 や 2秒 など、OSやライブラリの設定による)の間に返事が来ない。
3. クライアントは「おっと、途中で郵便配達員が落としちゃったかな?」と判断し、全く同じUDPパケットをもう一度同じ宛先へ投げ直す(再送)。

この再送が行われた瞬間、NATゲートウェイ側では「お、新しい(あるいは再送の)通信が来たぞ!」と認識され、新しく新鮮なNATセッション(窓口の控え)が再作成されます。これにより、めでたくだんまり状態から復旧するというわけです。

—

4. 現場で使える!実務での対策とチューニング設定例

「じゃあ、たまに通信が途切れる問題を防ぐには、どうすればいいの?」
ここからは、SREとして現場のインフラを構築・運用する際に役立つ、具体的な対策と設定例をご紹介します。

対策1: クライアント側のタイムアウトとリトライを見直す

DNSなどのクライアント側(アプリケーションやOSの設定)で、リトライ間隔を短くしたり、再送回数を適切に設定することで、パケットロス発生時の復旧をスピーディーに行うことができます。

例えば、Linuxのネットワーク名前解決の設定ファイルである /etc/resolv.conf では、次のようなパラメータを調整できます。

# /etc/resolv.conf の設定例
# 応答待ちのタイムアウト秒数(タイムアウトしたら再送する)を「2秒」に指定
options timeout:2

# 失敗したときの最大リトライ回数を「3回」に指定
options attempts:3

対策2: アプリケーション側で「キープアライブ(定期的な死活確認)」を入れる

Syslogや独自のUDPプロキシを構築している場合、完全に通信がない静かな時間をなくすため、一定間隔(例えばNATのタイムアウト時間より短い 30秒 ごとなど)で、意味のないダミーデータやハートビートパケットを流し、NATセッションを常に「現役バリバリの状態」に維持するアプローチが有効です。

対策3: クラウド側のインフラ設計を工夫する

もしAWSを利用しているのであれば、NATゲートウェイの仕様(UDPセッションタイムアウトは固定で 180秒 など)を前提に設計する必要があります。
どうしても長時間のUDPセッション維持や、パケットロスを極限まで減らしたい要件がある場合は、NATゲートウェイを介さずに、インスタンスに直接グローバルIP(Elastic IP)を付与してパケットの経路をシンプルにする、あるいはTCPベースのプロトコルに置き換える(DNS over TCPやSyslog over TCPの検討)というアーキテクチャの選択も、ベテランSREとしての重要な引き出しになります。

—

まとめ

いかがでしたでしょうか?
今回は、UDPプロキシやDNSフォワーディングにおけるNATセッションの管理と、パケットロス時の再送制御について、身近な郵便配達の例えを交えて解説しました。

  • UDPはステートレスであり、TCPのような「終了の挨拶」がない。
  • クラウドのNATゲートウェイは、一定時間通信がないとセッションの控えをシュレッダーにかけてしまう(タイムアウト)。
  • セッションが消えた後に届いたパケットは迷子になって捨てられてしまうため、アプリ側の再送メカニズムが重要になる。

インフラやネットワークの世界は、一見すると冷たくて複雑なルールの塊に見えますが、こうして「郵便配達の仕組み」に置き換えてみると、パケットたちがどんな気持ちでネットワークを駆け巡っているのかが少し見えてきませんか?

日々のトラブルシューティングや設計の現場で、「あ、今NATのセッションが切れたんだな!」とピンと来る瞬間が増えれば幸いです。
それでは、快適なクラウドネットワークライフを!

コメント

タイトルとURLをコピーしました