ElasticIPAttachment¶
ElasticIPAttachmentは、ElasticIPをNetworkInterfaceへ関連付けるリソースです。
1つのElasticIPに対して有効なElasticIPAttachmentは最大1つです。 1つのNetworkInterfaceに対して有効なElasticIPAttachmentも最大1つです。
前提¶
- 対象のNetworkInterfaceはdefault以外のSubnetに属している必要があります。default SubnetのPodはElasticIPの対象にできません
- 対象Podが属するVpcのRouteTableに
type: internetGatewayのルートが必要です。無いと外部疎通が成立しません
セットアップ手順の全体像はBGPを使ってExternalNetworkを構築するを参照してください。
ElasticIPを直接持つNICとの関係¶
ElasticIPは、ElasticIPAttachmentでNATに使うか、PodのNICに直接持たせるか、どちらか一方にしか使えません。ElasticIPの2つの使い方を参照してください。
webhookは次のElasticIPAttachmentを拒否します。
- 参照しているElasticIPを、すでにNetworkInterfaceが直接持っている。エラーには持っているNetworkInterfaceの名前が出ます
- 対象のNetworkInterfaceが、ElasticIPを直接持つNICである。そのNICにはNATの変換先になるVpc内のアドレスがありません
削除中のNetworkInterfaceは、直接持っているものとして数えません。
逆向きの確認はPodのwebhookが行います。ElasticIPAttachmentが使っているElasticIPをNICから参照すると、Podの作成が拒否されます。削除中のElasticIPAttachmentは数えないので、ElasticIPAttachmentを消してから直接使うPodを作れば、NATから直接へ移せます。
2つを同時に作るとwebhookをすり抜けることがあります。そのときはElasticIPがPHASE: Error、reason Conflictになります。ElasticIPAttachmentはPendingになり、reason WaitingForElasticIPのmessageに、ElasticIPのConflictと同じ内容が出ます。NATは設定されません。どちらかを消すと、残った方が動き出します。
ElasticIPAttachmentがAttachedになるのは、ElasticIPのstatus.attachmentがそのElasticIPAttachmentを指してからです。どちらの使い方にするかはElasticIP controllerが決めます。
status.elasticIPは関連付け対象として解決されたElasticIPのアドレスです。 status.podIPは関連付け先NetworkInterfaceのPod側IPアドレスです。 status.nodeNameは関連付け先NetworkInterfaceが存在するノード名です。
Readyは、この関連付けを安全に扱える状態かを表します。 Ready=TrueならElasticIPとNetworkInterfaceが解決され、対応するNetworkEndpointも一意に定まり、関連付け済みです。 Ready=Falseなら依存リソース待ち、または不整合があります。
Phase¶
- Pending:依存リソースの割り当てや対応するNetworkEndpointの作成待ち。ElasticIPがこのElasticIPAttachmentを使い手に選ぶのを待っている間もここに入ります
- Attached:ElasticIPが1つのNetworkInterfaceへ正常に関連付けられている状態
- Error:参照先不整合や複数NetworkEndpoint一致などで正常に扱えない状態
ICMPの扱い¶
ElasticIPの1:1 NATは、外側のIPヘッダに加えて、ICMPエラーメッセージが内包している元パケットのヘッダも書き換えます。
Linuxは受信したICMPエラーを、内包されたヘッダのタプルだけで対応するソケットに結び付けます。内包の送信元がElasticIPのまま届くと、Pod内のカーネルはソケットを見つけられず、そのエラーを黙って捨てます。内包ヘッダを書き換えることで、次のものが成立します。
- Path MTU Discovery。
tcp_v4_errは内包の(送信元アドレス, 送信元ポート)でソケットを探すので、内包がPod自身のアドレスであればFragmentation Neededが該当ソケットに渡り、経路MTUがキャッシュされます traceroute。UDPモードとICMPモードのどちらでも途中のホップが表示されます- 到達不能な相手に対する
connect()の中断
内包ヘッダの書き換えの対象になるのは、Destination Unreachable、Time Exceeded、Source Quench、Redirect、Parameter Problemの5種類です。それ以外のICMPタイプは外側のIPヘッダだけが書き換わります。ICMPのIdentifierを持つEcho Request/Replyもこちらで、1:1 NATはIdentifierを変換しません。
1:1 NATがポートを変換しないのは内包ヘッダでも同じで、変わるのはアドレスだけです。内包しているパケットのプロトコルがTCP、UDP、ICMP Echoのいずれでもないエラーメッセージと、内包ヘッダが関連付けたElasticIP以外のアドレスを指しているエラーメッセージは、書き換えようがないので破棄されます。
書き換えはkubectl juneau traceでicmp error translatedとして記録されます。
Podが持つのが1つのアドレスだけで、外向きの通信しか必要ないのであれば、NATGatewayでも同じことができます。