このページの改善にご協力ください
このユーザーガイドに貢献するには、すべてのページの右側のペインにある「GitHub でこのページを編集する」リンクを選択してください。
ハイブリッドノード向けネットワークトラフィックフロー
このページでは、EKS ハイブリッドノード向けネットワークトラフィックフローについて、いくつかのトラフィックタイプ別にエンドツーエンドでネットワークパスの図を示しながら詳しく説明します。
以下のトラフィックフローを取り上げます。
ハイブリッドノード kubelet から EKS コントロールプレーンまでのフロー
[リクエスト]
1kubelet. がリクエストを開始する
ハイブリッドノード上の kubelet が EKS コントロールプレーンと通信する必要がある場合 (例えば、ノードステータスを報告するため、あるいはポッドの仕様を取得するため) には、ノード登録時に提供された kubeconfig ファイルが使用されます。この kubeconfig には、ダイレクト IP アドレスではなく、API サーバーエンドポイント URL (Route53 DNS 名) が記載されています。
kubelet がエンドポイントに対して DNS ルックアップを実行します (例: https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com)。パブリックアクセスクラスターでは、これは AWS で実行中の EKS サービスに属するパブリック IP アドレス (例: 54.239.118.52) に解決されます。次に kubelet は、このエンドポイントへの安全な HTTPS リクエストを作成します。初期パケットは以下のようになります。
+--------------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.80.0.2 | Src: 52390 (random) | | | Dst: 54.239.118.52 | Dst: 443 | | +--------------------+---------------------+-----------------+
2. ローカルルーターのルーティング
宛先 IP はパブリック IP アドレスであり、ローカルネットワークの一部ではないため、kubelet はこのパケットをそのデフォルトゲートウェイ (ローカルオンプレミスルーター) に送信します。ルーターは、宛先 IP を確認して、パブリック IP アドレスであると判断します。
パブリックトラフィックの場合、ルーターは通常、パケットをインターネットゲートウェイ、つまりインターネットへのアウトバウンドトラフィックを処理するボーダールーターに転送します。図では、これを省略しています。実際の転送は、オンプレミスネットワークがどのように設定されているかによって異なります。パケットは、オンプレミスのネットワークインフラストラクチャを通っていき、最終的にインターネットサービスプロバイダーのネットワークに到達します。
3. EKS コントロールプレーンまでの配信
パケットは、パブリックインターネットとトランジットネットワークを横断していき、AWS のネットワークに到達します。AWS のネットワークは、パケットを適切なリージョンの EKS サービスエンドポイントにルーティングします。EKS サービスに到達したパケットは、クラスターの実際の EKS コントロールプレーンに転送されます。
これはパブリックインターネットを通るルーティングであり、他のトラフィックフローで見られるようなプライベート VPC をルーティングされていくパスとは異なります。その主な違いは、パブリックアクセスモードを使用した場合、ポッドからではなくオンプレミスの kubelet から EKS コントロールプレーンへのトラフィックが VPC を経由せず、代わりにグローバルインターネットインフラストラクチャを使用することです。
[応答]
EKS コントロールプレーンは、kubelet リクエストを処理してレスポンスを返します。
3. EKS コントロールプレーンがレスポンスを送信する
EKS コントロールプレーンはレスポンスパケットを作成します。このパケットには、ソースとしてパブリック IP、送信先としてハイブリッドノードの IP が含まれています。
+--------------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 54.239.118.52 | Src: 443 | | | Dst: 10.80.0.2 | Dst: 52390 | | +--------------------+---------------------+-----------------+
2. インターネットでのルーティング
レスポンスパケットは、インターネットサービスプロバイダーが決定したルーティングパスをたどってインターネット経由で戻り、オンプレミスネットワークのエッジルーターに到達します。
1. ローカルでの配信
オンプレミスのルーターは、パケットを受信し、宛先 IP (10.80.0.2) がローカルネットワークに属していると認識します。次に、受信したパケットをローカルネットワークインフラストラクチャ経由で転送します。パケットがターゲットのハイブリッドノードに到達すると、kubelet がレスポンスを受信して処理します。
ハイブリッドノード kube-proxy から EKS コントロールプレーンまでのフロー
クラスターのパブリックエンドポイントアクセスを有効にすると、戻りのトラフィックはパブリックインターネットを使用します。このトラフィックは、ハイブリッドノードの kube-proxy から EKS コントロールプレーンへと進み、kubelet から EKS コントロールプレーンへのトラフィックと同じパスを通ります。
EKS コントロールプレーンからハイブリッドノード (kubelet サーバー) までのフロー
[リクエスト]
1. EKS Kubernetes API サーバーがリクエストを開始する
EKS Kubernetes API サーバーは、ノードオブジェクトのステータスからノードの IP アドレス (10.80.0.2) を取得します。次に、送信先 IP が設定済みのリモートノード CIDR (10.80.0.0/16) に属しているため、このリクエストを VPC 内の ENI 経由でルーティングします。初期パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.0.0.132 | Src: 67493 (random) | | | Dst: 10.80.0.2 | Dst: 10250 | | +-----------------+---------------------+-----------------+
2. VPC ネットワークでの処理
パケットは、ENI を出て VPC ネットワーキングレイヤーに入り、さらにルーティングするためにサブネットのゲートウェイ宛てに送信されます。
3. VPC ルートテーブルのルックアップ
EKS コントロールプレーン ENI が含まれているサブネット用の VPC ルートテーブルには、リモートノード CIDR に固有のルート (図の 2 番目のルート) が登録されています。このルーティングルールに基づいて、パケットが VPC-to-onprem ゲートウェイに向けて送信されます。
4. 境界を越えて移動する
ゲートウェイは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えてオンプレミスネットワークにパケットを転送します。
5. オンプレミスネットワークでの受信
パケットは、ハイブリッドノードが配置されているサブネット宛てのトラフィックを処理するローカルオンプレミスルーターに到達します。
6. 最後の配信
ローカルルーターは、宛先 IP (10.80.0.2) アドレスが自身に直接接続されているネットワークに属しているかどうかを識別して、ターゲットのハイブリッドノードに直接パケットを転送し、そこで kubelet がリクエストを受信して処理します。
[応答]
ハイブリッドノードの kubelet は、リクエストを処理してレスポンスを返します。レスポンスは、同じパスを逆方向にたどります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.80.0.2 | Src: 10250 | | | Dst: 10.0.0.132 | Dst: 67493 | | +-----------------+---------------------+-----------------+
6. kubelet レスポンスを送信する
ハイブリッドノード (10.80.0.2) 上の kubelet は、送信元の IP を宛先としてレスポンスパケットを作成します。その宛先はローカルネットワークに属していないため、パケットはホストのデフォルトゲートウェイ、つまりローカルルーターに送信されます。
5. ローカルルーターのルーティング
ルーターは、宛先 IP (10.0.0.132) が 10.0.0.0/16 に属していると判断します。ここには、AWS に接続しているゲートウェイを指すルートがあります。
4. 境界を越えて戻る
パケットは、同じオンプレミスを通って VPC 接続 (Direct Connect や VPN など) まで戻り、クラウド境界を逆方向に横断します。
3. VPC でのルーティング
パケットが VPC に到達すると、ルートテーブルは宛先 IP が VPC CIDR に属しているかどうかを識別します。パケットは VPC 内にルーティングされます。
2. VPC ネットワークでの配信
VPC ネットワーキングレイヤーは、EKS コントロールプレーン ENI (10.0.0.132) を備えたサブネットにパケットを転送します。
1. ENI での受信
パケットは、Kubernetes API サーバーにアタッチされている EKS コントロールプレーン ENI に到達します。これでラウンドトリップは完了です。
ハイブリッドノードで実行されているポッドから EKS コントロールプレーンまでのフロー
CNI NAT なし
[リクエスト]
ポッドは一般に、kubernetes サービスを介して Kubernetes API サーバーと対話します。サービス IP がクラスターのサービス CIDR の最初の IP となります。この規約により、CoreDNS が使用可能になる前に稼働する必要があるポッドが API サーバー (例えば、CNI) に到達できるようになります。リクエストは、サービス IP を宛先としてポッドを出ていきます。例えば、サービス CIDR が 172.16.0.0/16 である場合、サービス IP は 172.16.0.1 になります。
1. ポッドがリクエストを開始する
ポッドは、ランダムな送信元ポートから API サーバーポート (443) 上の kubernetes サービス IP (172.16.0.1) にリクエストを送信します。パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.85.1.56 | Src: 67493 (random) | | | Dst: 172.16.0.1 | Dst: 443 | | +-----------------+---------------------+-----------------+
2. CNI での処理
CNI は、宛先 IP が自身の管理するポッド CIDR に属していないことを検出します。送信 NAT が無効になっているため、CNI はパケットを変更せずにホストネットワークスタックに渡します。
3. ノードネットワークでの処理
パケットはノードのネットワークスタックに入り、そこで netfilter フックが kube-proxy によって設定された iptables ルールをトリガーします。以下の順序でルールがいくつか適用されます。
-
パケットはまず
KUBE-SERVICESチェーンをヒットします。ここには、各サービスの ClusterIP とポートに対応するルールが含まれています。 -
その対応するルールは、
kubernetesサービスのKUBE-SVC-XXXチェーンにジャンプします (172.16.0.1:443宛てのパケット)。ここには、ロードバランシングルールが含まれています。 -
ロードバランシングルールは、コントロールプレーン ENI IP (
10.0.0.132または10.0.1.23) 用にKUBE-SEP-XXXチェーンのいずれかをランダムに選択します。 -
選択した
KUBE-SEP-XXXチェーンには実際のルールがあり、それにより宛先 IP はサービス IP から選択されている IP に変更されます。これは、Destination Network Address Translation (宛先ネットワークアドレス変換、DNAT) と呼ばれます。
選択されている EKS コントロールプレーン ENI の IP を 10.0.0.132 とした場合、これらのルールが適用されると、パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.85.1.56 | Src: 67493 (random) | | | Dst: 10.0.0.132 | Dst: 443 | | +-----------------+---------------------+-----------------+
宛先 IP がローカルネットワーク内にないため、ノードはパケットをデフォルトゲートウェイに転送します。
4. ローカルルーターのルーティング
ローカルルーターは、宛先 IP (10.0.0.132) が VPC CIDR (10.0.0.0/16) に属していると判断して、AWS に接続しているゲートウェイに転送します。
5. 境界を越えて移動する
パケットは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えて VPC に移動します。
6. VPC ネットワークでの配信
VPC ネットワーキングレイヤーは、EKS コントロールプレーン ENI (10.0.0.132) が存在する適切なサブネットにパケットをルーティングします。
7. ENI での受信
パケットは、Kubernetes API サーバーにアタッチされている EKS コントロールプレーン ENI に到達します。
[応答]
EKS コントロールプレーンは、リクエストを処理してポッドにレスポンスを返します。
7. API サーバーがレスポンスを送信する
EKS Kubernetes API サーバーは、送信元の IP を宛先としてレスポンスパケットを作成します。パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.0.0.132 | Src: 443 | | | Dst: 10.85.1.56 | Dst: 67493 | | +-----------------+---------------------+-----------------+
宛先 IP が設定済みのリモートポッド CIDR (10.85.0.0/16) に属しているため、パケットはサブネットのルーターを次のホップとして VPC 内の ENI 経由で送信されます。
6. VPC でのルーティング
VPC ルートテーブルにはリモートポッド CIDR (10.85.0.0/16) のエントリがあるため、このトラフィックは VPC-to-onprem ゲートウェイ宛てに送信されます。
5. 境界を越えて移動する
ゲートウェイは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えてオンプレミスネットワークにパケットを転送します。
4. オンプレミスネットワークでの受信
パケットは、ローカルオンプレミスルーターに到達します。
3. ノードへの配信
ルーターのテーブルには 10.80.0.2 を次のホップとした 10.85.1.0/24 のエントリがあるため、パケットはノードに配信されます。
2. ノードネットワークでの処理
パケットがノードのネットワークスタックによって処理されると、conntrack (netfilter の一部) はポッドが最初に確立した接続とパケットを照合します。DNAT が最初に適用されたため、conntrack はソース IP を EKS コントロールプレーン ENI の IP から kubernetes サービス IP に書き換えることで DNAT を元に戻します。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 172.16.0.1 | Src: 443 | | | Dst: 10.85.1.56 | Dst: 67493 | | +-----------------+---------------------+-----------------+
1. CNI での処理
CNI は、宛先 IP が自身のネットワーク内のポッドに属しているかどうかを識別して、適切なポッドネットワーク名前空間にパケットを配信します。
このフローは、なぜリモートポッド CIDR を VPC から各ポッドをホストする特定のノードに至るまで正しくルーティングできなければならないかを示しています。戻りパス全体は、クラウドとオンプレミスの両方のネットワーク全体にわたってポッド IP が適切にルーティングされるかどうかによって異なります。
CNI NAT あり
このフローは、CNI NAT がないものと非常によく似ていますが、重要な違いが 1 つあります。CNI は、パケットに送信元 NAT (SNAT) を適用してから、ノードのネットワークスタックにパケットを送信します。これにより、パケットの送信元 IP がノードの IP に変更されるため、追加でルーティングを設定することなく、ノードにパケットをルーティングできます。
[リクエスト]
1. ポッドがリクエストを開始する
ポッドは、ランダムな送信元ポートから EKS Kubernetes API サーバーポート (443) 上の kubernetes サービス IP (172.16.0.1) にリクエストを送信します。パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.85.1.56 | Src: 67493 (random) | | | Dst: 172.16.0.1 | Dst: 443 | | +-----------------+---------------------+-----------------+
2. CNI での処理
CNI は、宛先 IP が自身の管理するポッド CIDR に属していないことを検出します。送信 NAT が有効になっているため、CNI は SNAT をパケットに適用して送信元 IP をノードの IP に変更してから、パケットをノードのネットワークスタックに渡します。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.80.0.2 | Src: 67493 (random) | | | Dst: 172.16.0.1 | Dst: 443 | | +-----------------+---------------------+-----------------+
注: この例ではわかりやすくするために CNI と iptables をそれぞれ別のブロックに分けていますが、実際には iptables を使用して NAT を適用する CNI もあります。
3. ノードネットワークでの処理
ここでは、kube-proxy によって設定された iptables ルールが前の例と同じように動作して、パケットを EKS コントロールプレーン ENI のいずれかに負荷分散します。これでパケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.80.0.2 | Src: 67493 (random) | | | Dst: 10.0.0.132 | Dst: 443 | | +-----------------+---------------------+-----------------+
宛先 IP がローカルネットワーク内にないため、ノードはパケットをデフォルトゲートウェイに転送します。
4. ローカルルーターのルーティング
ローカルルーターは、宛先 IP (10.0.0.132) が VPC CIDR (10.0.0.0/16) に属していると判断して、AWS に接続しているゲートウェイに転送します。
5. 境界を越えて移動する
パケットは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えて VPC に移動します。
6. VPC ネットワークでの配信
VPC ネットワーキングレイヤーは、EKS コントロールプレーン ENI (10.0.0.132) が存在する適切なサブネットにパケットをルーティングします。
7. ENI での受信
パケットは、Kubernetes API サーバーにアタッチされている EKS コントロールプレーン ENI に到達します。
[応答]
EKS コントロールプレーンは、リクエストを処理してポッドにレスポンスを返します。
7. API サーバーがレスポンスを送信する
EKS Kubernetes API サーバーは、送信元の IP を宛先としてレスポンスパケットを作成します。パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.0.0.132 | Src: 443 | | | Dst: 10.80.0.2 | Dst: 67493 | | +-----------------+---------------------+-----------------+
宛先 IP が設定済みのリモートノード CIDR (10.80.0.0/16) に属しているため、パケットはサブネットのルーターを次のホップとして VPC 内の ENI 経由で送信されます。
6. VPC でのルーティング
VPC ルートテーブルにはリモートノード CIDR (10.80.0.0/16) のエントリがあるため、このトラフィックは VPC-to-onprem ゲートウェイ宛てに送信されます。
5. 境界を越えて移動する
ゲートウェイは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えてオンプレミスネットワークにパケットを転送します。
4. オンプレミスネットワークでの受信
パケットは、ローカルオンプレミスルーターに到達します。
3. ノードへの配信
ローカルルーターは、宛先 IP (10.80.0.2) アドレスが自身に直接接続されているネットワークに属しているかどうかを識別して、ターゲットのハイブリッドノードに直接パケットを転送します。
2. ノードネットワークでの処理
パケットがノードのネットワークスタックによって処理されると、conntrack (netfilter の一部) はパケットをポッドが最初に確立した接続と照合します。元々 DNAT が適用されていたため、送信元 IP を EKS コントロールプレーン ENI の IP から kubernetes サービス IP に書き換えることで元に戻します。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 172.16.0.1 | Src: 443 | | | Dst: 10.80.0.2 | Dst: 67493 | | +-----------------+---------------------+-----------------+
1. CNI での処理
CNI は、このパケットが以前に SNAT が適用された接続に属しているかどうかを識別します。これにより、SNAT が逆方向に適用されるため、宛先 IP がポッドの IP に戻ります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 172.16.0.1 | Src: 443 | | | Dst: 10.85.1.56 | Dst: 67493 | | +-----------------+---------------------+-----------------+
CNI は、宛先 IP が自身のネットワーク内のポッドに属していることを検出して、適切なポッドネットワーク名前空間にパケットを配信します。
このフローは、CNI NAT の適用により、追加でポッド CIDR のルーティングを行うことなくパケットをノードにルーティングできるようにすることで、設定をどのように簡素化できるかを示しています。
EKS コントロールプレーンからハイブリッドノードで実行されているポッドまでのフロー (ウェブフック)
このトラフィックパターンはウェブフックで最もよく見られるものであり、ウェブフックではハイブリッドノード上のポッドで実行されているウェブフックサーバーへの接続を EKS コントロールプレーンが直接開始する必要があります。例えば、アドミッションウェブフックを検証して変更するといった場合、このウェブフックはリソースの検証と変更のプロセス中に API サーバーによって呼び出されます。
[リクエスト]
1. EKS Kubernetes API サーバーがリクエストを開始する
クラスターに設定されたウェブフックが関連する API オペレーションによってトリガーされた場合、EKS Kubernetes API サーバーはそのウェブフックサーバーポッドに直接接続する必要があります。API サーバーはまず、そのウェブフックに関連付けられているサービスリソースまたはエンドポイントリソースでポッドの IP アドレスを検索します。
IP が 10.85.1.23 のハイブリッドノード上でウェブフックポッドが実行されている場合、EKS Kubernetes API サーバーはウェブフックエンドポイントへの HTTPS リクエストを作成します。10.85.1.23 という宛先 IP は設定済みのリモートポッド CIDR (10.85.0.0/16) に属しているため、初期パケットは VPC の EKS コントロールプレーン ENI を介して送信されます。パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.0.0.132 | Src: 41892 (random) | | | Dst: 10.85.1.23 | Dst: 8443 | | +-----------------+---------------------+-----------------+
2. VPC ネットワークでの処理
パケットは、EKS コントロールプレーン ENI を出て、サブネットのルーターを次のホップとする VPC ネットワーキングレイヤーに入ります。
3. VPC ルートテーブルのルックアップ
EKS コントロールプレーン ENI が含まれているサブネット用の VPC ルートテーブルには、リモートポッド CIDR (10.85.0.0/16) に固有のルートが登録されています。このルーティングルールにより、パケットは VPC-to-onprem ゲートウェイ (例えば、Direct Connect や VPN 接続の場合は仮想プライベートゲートウェイ) 宛てに送信されます。
Destination Target 10.0.0.0/16 local 10.85.0.0/16 vgw-id (VPC-to-onprem gateway)
4. 境界を越えて移動する
ゲートウェイは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えてオンプレミスネットワークにパケットを転送します。パケットがこの接続を通過するとき、パケットの送信元 IP アドレスと宛先 IP アドレスは元のまま維持されます。
5. オンプレミスネットワークでの受信
パケットは、ローカルオンプレミスルーターに到達します。ルーターは、自身のルーティングテーブルに問い合わせて、10.85.1.23 アドレスに到達する方法を決定します。そのためにオンプレミスネットワークには、適切なハイブリッドノード宛てにトラフィックを送信するポッド CIDR へのルートが必要です。
この例の場合、ルーターのルートテーブルには IP が 10.80.0.2 のハイブリッドノード経由で 10.85.1.0/24 サブネットに到達できることを示すエントリが登録されています。
Destination Next Hop 10.85.1.0/24 10.80.0.2
6. ノードへの配信
ルーターは、ルーティングテーブルのエントリに基づいて、パケットをハイブリッドノード (10.80.0.2) に転送します。ノードに到達したとき、パケットは EKS Kubernetes API サーバーから送信されたときと同じままで、宛先 IP は依然としてポッドの IP です。
7. CNI での処理
ノードのネットワークスタックは、パケットを受信し、宛先 IP がノード自体の IP でないことを確認して、さらに処理するために CNI に渡します。CNI は、宛先 IP がこのノードでローカルに実行されているポッドに属しているかどうかを識別し、適切な仮想インターフェイス経由で適切なポッドにパケットを転送します。
Original packet -> node routing -> CNI -> Pod's network namespace
ポッド内のウェブフックサーバーは、リクエストを受信して処理します。
[応答]
ウェブフックポッドは、リクエストを処理してレスポンスを返します。レスポンスは、同じパスを逆方向にたどります。
7. ポッドがレスポンスを送信する
ウェブフックポッドは、自身の IP を送信元とし、元のリクエスタ (EKS コントロールプレーン ENI) を宛先として、レスポンスパケットを作成します。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.85.1.23 | Src: 8443 | | | Dst: 10.0.0.132 | Dst: 41892 | | +-----------------+---------------------+-----------------+
CNI は、このパケットが外部ネットワーク (ローカルポッドではない) に送信され、パケットが、元のソース IP を保持したままノードのネットワークスタックに渡されたことを確認します。
6. ノードネットワークでの処理
ノードは、宛先 IP (10.0.0.132) がローカルネットワーク内にないと判断して、自身のデフォルトゲートウェイ (ローカルルーター) にパケットを転送します。
5. ローカルルーターのルーティング
ローカルルーターは、自身のルーティングテーブルに問い合わせて、宛先 IP (10.0.0.132) が VPC CIDR (10.0.0.0/16) に属していると判断します。次に、AWS に接続しているゲートウェイにパケットを転送します。
4. 境界を越えて移動する
パケットは、同じオンプレミスを通って VPC 接続まで戻り、クラウド境界を逆方向に横断します。
3. VPC でのルーティング
パケットが VPC に到達すると、ルートテーブルは宛先 IP が VPC 内のサブネットに属しているかどうかを識別します。それに応じて、パケットは VPC 内にルーティングされます。
2. と 1. EKS コントロールプレーン ENI での受信
パケットは、Kubernetes API サーバーにアタッチされている ENI に到達します。これでラウンドトリップは完了です。API サーバーは、ウェブフックレスポンスを受信し、このレスポンスに基づいて元の API リクエストの処理を続行します。
このトラフィックフローは、なぜリモートポッド CIDR を正しく設定してルーティングする必要があるかを示しています。
-
VPC には、オンプレミスゲートウェイを指すリモートポッド CIDR のルートが登録されている必要があります。
-
オンプレミスネットワークには、そうしたポッドをホストしている特定のノード宛てにトラフィックを送信するポッド CIDR のルートが登録されている必要があります。
-
このルーティング設定がないと、ハイブリッドノード上のポッドで実行されているウェブフックやその他の同じようなサービスに EKS コントロールプレーンから到達できなくなります。
ハイブリッドノードで実行されているポッド間
このセクションでは、異なるハイブリッドノード上で実行されているポッド同士がどのように通信しているかについて説明します。この例では、CNI がカプセル化に VXLAN を使用しているものとします。これは、Cilium や Calico などの CNI でよく見られることです。プロセス全体は、Geneve や IP-in-IP など、他のカプセル化プロトコルに似ています。
[リクエスト]
1. ポッド A が通信を開始する
ノード 1 上のポッド A (10.85.1.56) が、ノード 2 上のポッド B (10.85.2.67) にトラフィックを送信しようとしています。初期パケットは以下のようになります。
+------------------+-----------------+-------------+-----------------+ | Ethernet Header | IP Header | TCP/UDP | Payload | | Src: Pod A MAC | Src: 10.85.1.56 | Src: 43721 | | | Dst: Gateway MAC | Dst: 10.85.2.67 | Dst: 8080 | | +------------------+-----------------+-------------+-----------------+
2. CNI がパケットをインターセプトして処理する
ポッド A のパケットが自身のネットワーク名前空間を出ると、CNI がそのパケットをインターセプトします。CNI は自身のルーティングテーブルに問い合わせて、宛先 IP (10.85.2.67) はポッド CIDR に属している、この IP はローカルノードではなくノード 2 (10.80.0.3) に属している、パケットは VXLAN でカプセル化する必要がある、と判断します。
カプセル化するという判断は重要です。基盤となる物理ネットワークが、ノード IP 間のトラフィックをルーティングする方法は認識しているものの、ポッド CIDR を直接ルーティングする方法は認識していないためです。
CNI は、元のパケット全体を VXLAN フレーム内にカプセル化します。これにより、「パケット内のパケット」が次のような新しいヘッダー付きで効果的に作成されます。
+-----------------+----------------+--------------+------------+---------------------------+ | Outer Ethernet | Outer IP | Outer UDP | VXLAN | Original Pod-to-Pod | | Src: Node1 MAC | Src: 10.80.0.2 | Src: Random | VNI: 42 | Packet (unchanged | | Dst: Router MAC | Dst: 10.80.0.3 | Dst: 8472 | | from above) | +-----------------+----------------+--------------+------------+---------------------------+
このカプセル化の重要なポイントは、外側のパケットにはノード 1 (10.80.0.2) からノード 2 (10.80.0.3) までのアドレスが指定されること、UDP ポート 8472 は Cilium がデフォルトで使用する VXLAN ポートであること、VXLAN Network Identifier (VNI) はこのパケットが属するオーバーレイネットワークを識別すること、元のパケット (ポッド A の IP を送信元とし、ポッド B の IP を宛先とする) 全体が内側でもそのまま保持されることです。
これで、カプセル化されたパケットは、ノード 1 の通常のネットワークスタックに入って、他のパケットと同じ方法で処理されます。
-
ノードネットワークでの処理: ノード 1 のネットワークスタックは、宛先 (
10.80.0.3) に基づいてパケットをルーティングします。 -
ローカルネットワークでの配信:
-
両方のノードが同じレイヤー 2 ネットワークにある場合、パケットはノード 2 に直接送信されます。
-
それぞれ別のサブネットにある場合、パケットはまずローカルルーターに転送されます。
-
-
ルーターでの処理: ルーターは、自身のルーティングテーブルに基づいてパケットを転送して、ノード 2 に配信します。
3. 受信側のノードでの処理
カプセル化されたパケットがノード 2 (10.80.0.3) に到達すると、次のようになります。
-
ノードのネットワークスタックは、パケットを受信し、VXLAN パケット (UDP ポート
4789) であると識別します。 -
パケットは、さらに処理するために CNI の VXLAN インターフェイスに渡されます。
4. VXLAN カプセル化解除
ノード 2 上の CNI は、次のように VXLAN パケットを処理します。
-
外側のヘッダー (イーサネット、IP、UDP、VXLAN) を取り除きます。
-
内側の元のパケットを抽出します。
-
これで、パケットは元の形式に戻ります。
+------------------+-----------------+-------------+-----------------+ | Ethernet Header | IP Header | TCP/UDP | Payload | | Src: Pod A MAC | Src: 10.85.1.56 | Src: 43721 | | | Dst: Gateway MAC | Dst: 10.85.2.67 | Dst: 8080 | | +------------------+-----------------+-------------+-----------------+
ノード 2 上の CNI は、宛先 IP (10.85.2.67) を確認して、次の処理を行います。
-
この IP がローカルポッドに属しているかどうかを識別します。
-
適切な仮想インターフェイス経由でパケットをルーティングします。
-
ポッド B のネットワーク名前空間にパケットを配信します。
[応答]
ポッド B がポッド A に応答するときは、プロセス全体が逆方向になります。
-
ポッド B がポッド A (
10.85.1.56) にパケットを送信します。 -
ノード 2 の CNI は、そのパケットを VXLAN でカプセル化し、宛先をノード 1 (
10.80.0.2) に設定します。 -
カプセル化されたパケットがノード 1 に配信されます。
-
ノード 1 の CNI は、パケットをカプセル化解除し、元のレスポンスをポッド A に配信します。
クラウドノード上のポッドからハイブリッドノード上のポッドまでのフロー (東西トラフィック)
[リクエスト]
1. ポッド A が通信を開始する
EC2 ノード上のポッド A (10.0.0.56) がハイブリッドノード上のポッド B (10.85.1.56) にトラフィックを送信しようとしています。初期パケットは以下のようになります。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.0.0.56 | Src: 52390 (random) | | | Dst: 10.85.1.56 | Dst: 8080 | | +-----------------+---------------------+-----------------+
VPC CNI では、ポッド A に VPC CIDR からの IP があるため、ポッド A は EC2 インスタンス上の ENI に直接アタッチされます。ポッドのネットワーク名前空間は VPC ネットワークに接続されているため、パケットは VPC ルーティングインフラストラクチャに直接入ります。
2. VPC でのルーティング
VPC ルートテーブルにはリモートポッド CIDR (10.85.0.0/16) に固有のルートが登録されているため、このトラフィックは VPC-to-onprem ゲートウェイ宛てに送信されます。
Destination Target 10.0.0.0/16 local 10.85.0.0/16 vgw-id (VPC-to-onprem gateway)
このルーティングルールに基づいて、パケットはオンプレミスネットワークに接続しているゲートウェイに向けて送信されます。
3. 境界を越えて移動する
ゲートウェイは、確立済みの接続 (Direct Connect や VPN など) 経由でクラウド境界を越えてオンプレミスネットワークにパケットを転送します。このトランジットを全体を通して、パケットの送信元 IP アドレスと宛先 IP アドレスは元のまま維持されます。
4. オンプレミスネットワークでの受信
パケットは、ローカルオンプレミスルーターに到達します。ルーターは、自身のルーティングテーブルに問い合わせて、10.85.1.56 アドレスに到達するための次のホップを決定します。オンプレミスルーターには、適切なハイブリッドノード宛てにトラフィックを送信するポッド CIDR へのルートが必要です。
ルーターのルートテーブルには IP 10.80.0.2 のハイブリッドノード経由で 10.85.1.0/24 サブネットに到達できることを示すエントリが登録されています。
Destination Next Hop 10.85.1.0/24 10.80.0.2
5. ノードネットワークでの処理
ルーターは、パケットをハイブリッドノード (10.80.0.2) に転送します。パケットがノードに到達したとき、パケットのポッド A の IP は送信元のまま、ポッド B の IP は宛先のままです。
6. CNI での処理
ノードのネットワークスタックは、パケットを受信し、宛先 IP が自身のものでないことを確認して、さらに処理するために CNI に渡します。CNI は、宛先 IP がこのノードでローカルに実行されているポッドに属しているかどうかを識別し、適切な仮想インターフェイス経由で適切なポッドにパケットを転送します。
Original packet -> node routing -> CNI -> Pod B's network namespace
ポッド B は、パケットを受信し、必要に応じて処理します。
[応答]
6. ポッド B がレスポンスを送信する
ポッド B は、自身の IP を送信元、ポッド A の IP を宛先として、レスポンスパケットを作成します。
+-----------------+---------------------+-----------------+ | IP Header | TCP Header | Payload | | Src: 10.85.1.56 | Src: 8080 | | | Dst: 10.0.0.56 | Dst: 52390 | | +-----------------+---------------------+-----------------+
CNI は、このパケットが外部ネットワーク宛てかどうかを識別して、ノードのネットワークスタックに渡します。
5. ノードネットワークでの処理
ノードは、宛先 IP (10.0.0.56) がローカルネットワークに属していないと判断し、自身のデフォルトゲートウェイ (ローカルルーター) にパケットを転送します。
4. ローカルルーターのルーティング
ローカルルーターは、自身のルーティングテーブルに問い合わせて、宛先 IP (10.0.0.56) が VPC CIDR (10.0.0.0/16) に属していると判断します。次に、AWS に接続しているゲートウェイにパケットを転送します。
3. 境界を越えて移動する
パケットは、同じオンプレミスを通って VPC 接続まで戻り、クラウド境界を逆方向に横断します。
2. VPC でのルーティング
パケットが VPC に到達すると、ルーティングシステムは宛先 IP が VPC 内のサブネットに属しているかどうかを識別します。パケットは、ポッド A をホストしている EC2 インスタンスに向けて、VPC ネットワーク経由でルーティングされます。
1. ポッド A がレスポンスを受信する
パケットは、EC2 インスタンスに到達し、そこにアタッチされている ENI 経由でポッド A に直接配信されます。VPC CNI は VPC 内のポッドにオーバーレイネットワーキングを使用しないため、別途カプセル化解除は必要なく、パケットは元のヘッダーのまま届きます。
この東西トラフィックフローは、なぜリモートポッド CIDR を正しく設定して、両方向からルーティング可能にする必要があるかを示しています。
-
VPC には、オンプレミスゲートウェイを指すリモートポッド CIDR のルートが登録されている必要があります。
-
オンプレミスネットワークには、そうしたポッドをホストしている特定のノード宛てにトラフィックを送信するルートがポッド CIDR で登録されている必要があります。