NATGateway¶
NATGatewayは、Vpcに属するPodがVpc外へ通信する際のNAPT (N:1のソースNAT) 出口を表すリソースです。 Vpc内の複数のPodが共通のソースIPアドレスで外部に出ていく構成を作るときに利用します。
spec.vpcはこのNATGatewayが属するVpcの名前です。 spec.externalNetworkは出口となるExternalNetworkの名前です。 NAPT時のソースIPアドレスは、参照したExternalNetworkに紐づくAddressPoolから払い出されます。
spec.vpcとspec.externalNetworkは作成後に変更できません。
RouteTable との連携¶
NATGatewayをVpc外への経路として利用するには、対象VpcのRouteTableにvia.type: natGatewayのルートを追加し、via.natGatewayでNATGateway名を参照します。 たとえば0.0.0.0/0のデフォルトルートをこのNATGateway経由に向けることで、Vpc内のPodがクラスタ外へ通信できるようになります。
詳しくはRouteTableを参照してください。
Node ごとのソースIP¶
NATGatewayを作成すると、対象ExternalNetworkに紐づくNodeごとのExternalNetworkAttachmentが自動的に作成され、Nodeごとに1つずつNAPTソースIPアドレスが払い出されます。 Pod がVpc外へ出るとき、そのPodが配置されているNodeに対応するソースIPアドレスが利用されます。
戻り通信が正しいNodeへ届くよう、払い出したソースIPアドレスはExternalNetworkのspec.typeに応じた方法で外部へ知らせます。 bgpならExternalNetworkAttachmentのcontrollerがそのNodeを指定した/32のBGPAdvertisementを、arpなら同じくそのNodeを指定したARPAdvertisementを作成します。
arpの場合、Nodeが増えるたびにAddressPoolから1つずつアドレスを消費します。 AddressPoolの範囲がNode数より狭いと、あぶれたNodeのExternalNetworkAttachmentはReady=False(reason: NoAddress)のままになり、そのNode上のPodはNATGateway経由で外部に出られません。
対応プロトコル¶
NAPTの対象はTCP、UDP、ICMPの3つです。それ以外のプロトコルはNATGateway経由で外部に出ることができません。
ICMPで扱うのはEcho Requestとその応答であるEcho Replyです。ICMPにはポートが無いため、ICMPヘッダのIdentifierをポート相当として払い出します。Echo ReplyはRequestと同じIdentifierを返すので、払い出した値から元のPodを引き当てることができます。これによりNATGateway配下のPodやVMからpingが通ります。
Echo以外では、Destination Unreachable、Time Exceeded、Source Quench、Redirect、Parameter Problemの5種類のICMPエラーメッセージを扱います。これらは経路上のルータが送るものなので、外側のIPヘッダを見てもどのフローに対する応答なのか分かりません。ICMPエラーメッセージが内包している元パケットのヘッダからconntrackのエントリを引き当て、外側と内包の両方を書き換えます。Podのカーネルは内包されたヘッダを見て対応するソケットを探すため、この書き換えが無いとエラーメッセージは捨てられます。NATGateway配下でtracerouteとPath MTU Discoveryが動くのはこの仕組みによります。Pod側から外部に向けて送るICMPエラーメッセージも、同じように内包ヘッダごと書き換えます。
EchoとICMPエラーメッセージ以外のICMPタイプ (Timestampなど) は破棄されます。IPフラグメントも対象外です。
ICMPのconntrackエントリは、最後にパケットが通ってから30秒でGCの対象になります。TCPのように終了を示すものが無いためです。
ICMPエラーメッセージの書き換えはkubectl juneau traceでicmp error translatedとして記録されます。表示されるタプルは、ICMPエラーメッセージ自体ではなく、そのエラーが報告している元のフローです。
default NATGateway¶
defaultという名前のNATGatewayが存在し、Readyになっている場合、default Vpcのメインルートテーブルには0.0.0.0/0へのルートがvia.type: natGatewayとして自動的に追加されます。 これにより明示的にRouteTableを構成しなくても、default Vpc内のPodがクラスタ外へ通信できるようになります。
status¶
status.conditionsのReadyは、NATGatewayが正常に利用可能かを表します。 Ready=Trueになるまでは、このNATGatewayを参照するRouteTableのルートも有効にはなりません。