

 **協助改進此頁面** 

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

若要為本使用者指南貢獻內容，請點選每個頁面右側面板中的**在 GitHub 上編輯此頁面**連結。

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 混合節點的概念
<a name="hybrid-nodes-concepts"></a>

使用 *Amazon EKS 混合節點*，您可以將內部部署或邊緣環境中執行的實體或虛擬機器加入 AWS 雲端中執行的 Amazon EKS 叢集。這種方法可帶來許多好處，但同時也會為熟悉在單一網路環境中執行 Kubernetes 叢集的使用者引進新的聯網概念和架構。

以下章節將深入探討 EKS 混合節點的 Kubernetes 和聯網概念，並詳細說明流量如何流經混合式架構。這些章節會要求您熟悉基本的 Kubernetes 網路知識，例如 Pod、節點、服務、Kubernetes 控制平面、kubelet 和 kube-proxy 的概念。

我們建議您按照順序閱讀這些頁面，即從 [混合節點的聯網概念](hybrid-nodes-concepts-networking.md) 開始，接著是 [混合節點的 Kubernetes 概念](hybrid-nodes-concepts-kubernetes.md)，最後是 [混合節點的網路流量流程](hybrid-nodes-concepts-traffic-flows.md)。

**Topics**
+ [

# 混合節點的聯網概念
](hybrid-nodes-concepts-networking.md)
+ [

# 混合節點的 Kubernetes 概念
](hybrid-nodes-concepts-kubernetes.md)
+ [

# 混合節點的網路流量流程
](hybrid-nodes-concepts-traffic-flows.md)

# 混合節點的聯網概念
<a name="hybrid-nodes-concepts-networking"></a>

本節詳細說明設計 EKS 混合節點的網路拓撲時，必須考量的核心聯網概念和限制條件。

## EKS 混合節點的聯網概念
<a name="_networking_concepts_for_eks_hybrid_nodes"></a>

![\[高階混合節點網路圖\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-highlevel-network.png)


 **VPC 作為網路集線器** 

所有跨雲端邊界路由的流量都會通過您的 VPC。這包括在 中執行的 EKS 控制平面或 Pod AWS 與在其上執行的混合節點或 Pod 之間的流量。您可以將叢集的 VPC 視為混合節點與叢集其餘部分之間的網路集線器。此架構可讓您完全控制流量及其路由，但也可要求您須負責正確設定 VPC 的路由、安全群組和防火牆。

 **EKS 控制平面到 VPC** 

EKS 控制平面會將**彈性網路介面 (ENI)** 連接至您的 VPC。這些 ENI 會處理進出 EKS API 伺服器的流量。您可以在設定叢集時控制 EKS 控制平面 ENI 的置放，因為 EKS 會將 ENI 連接到您在叢集建立期間傳遞的子網路。

EKS 會將安全群組與 EKS 連接到子網路的 ENI 建立關聯。這些安全群組允許流量透過 ENI 進出 EKS 控制平面。這對 EKS 混合節點很重要，因為您必須允許流量從混合節點和在其上執行的 Pod 進入 EKS 控制平面 ENI。

 **遠端節點網路** 

遠端節點網路，特別是遠端節點 CIDR，是指派給您用作混合節點的機器的 IP 範圍。當您佈建混合節點時，它們位於您的內部部署資料中心或邊緣節點，這是與 EKS 控制平面和 VPC 不同的網路網域。每個混合節點都有來自遠端節點 CIDR 的 IP 位址或地址，而該 CIDR 與您 VPC 中的子網路不同。

您可以使用這些遠端節點 CIDR 設定 EKS 叢集，以便 EKS 知道透過叢集 VPC 路由所有以混合節點 IP 為目標的流量，例如請求到 kubelet API。API 的連線`kubelet`用於 `kubectl attach`、`kubectl cp`、`kubectl logs`、 `kubectl exec`和 `kubectl port-forward`命令。

 **遠端 Pod 網路** 

遠端 Pod 網路是指派給在混合節點上執行的 Pod 的 IP 範圍。一般而言，您可以使用這些範圍設定 CNI，而 CNI 的 IP 位址管理 (IPAM) 功能會負責將這些範圍的配量指派給每個混合節點。當您建立 Pod 時，CNI 會從配置給已排程 Pod 的節點的配量，將 IP 指派給 Pod。

您可以使用這些遠端 Pod CIDR 設定 EKS 叢集，因此 EKS 控制平面知道透過叢集的 VPC 路由所有以混合節點上執行的 Pod 為目標的流量，例如與 Webhook 的通訊。

![\[遠端 Pod 網路\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-remote-pod-cidrs.png)


 **內部部署到 VPC** 

您用於混合節點的內部部署網路必須路由到您用於 EKS 叢集的 VPC。若要將內部部署網路連接到 VPC，有數個[網路到 Amazon VPC 連線選項](https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/network-to-amazon-vpc-connectivity-options.html)可用。您也可以使用自己的 VPN 解決方案。

請務必在 VPC 和內部部署網路的 AWS 雲端端正確設定路由，以便兩個網路透過兩個網路的連線路由正確的流量。

在 VPC 中，所有流向遠端節點和遠端 Pod 網路的流量都必須透過連線路由至內部部署網路 (稱為「閘道」)。如果您的部分子網路具有不同的路由表，則您必須使用混合節點的路由和在其上執行的 Pod 來設定每個路由表。對於連接 EKS 控制平面 ENI 的子網路，以及包含必須與混合節點通訊的 EC2 節點或 Pod 的子網路而言，都是如此。

在內部部署網路中，您必須設定網路，以允許進出 EKS 叢集 VPC 的流量，以及混合節點 AWS 所需的其他服務。EKS 叢集的流量可雙向周遊閘道。

## 聯網限制條件
<a name="_networking_constraints"></a>

 **完全路由的網路** 

主要限制條件是 EKS 控制平面和所有節點 (雲端或混合節點) 需要形成一個**完全路由的**網路。這表示所有節點都必須能夠透過 IP 位址在第三層彼此連接。

由於 EKS 控制平面和雲端節點位於平面網路 (VPC) 中，因此它們可以彼此連接。不過，混合節點會位於不同的網路網域中。因此，您需要在 VPC 和內部部署網路中設定額外的路由，以在混合節點和叢集的其餘部分之間路由流量。如果混合節點可從彼此和 VPC 連接，則您的混合節點可以位於單一平面網路或多個分段網路中。

 **可路由的遠端 Pod CIDR** 

若要讓 EKS 控制平面與在混合節點 (例如 Webhook 或指標伺服器) 上執行的 Pod 通訊，或讓在雲端節點上執行的 Pod 與在混合節點上執行的 Pod 通訊 (工作負載東西通訊)，您的遠端 Pod CIDR 必須可從 VPC 路由。這表示 VPC 必須能夠透過閘道將流量路由至內部部署網路的 Pod CIDR，並且您的內部部署網路必須能夠將 Pod 的流量路由至正確的節點。

請務必注意 VPC 和內部部署中 Pod 路由要求之間的差異。VPC 只需要知道任何流向遠端 Pod 的流量均應通過閘道。如果您只有一個遠端 Pod CIDR，則僅需一個路由。

此要求適用於您內部部署網路中的所有躍點，直到與您的混合節點位於相同子網路的本機路由器為止。這是唯一需要了解指派給每個節點的 Pod CIDR 配量的路由器，從而確保特定 Pod 的流量會交付至已排程 Pod 的節點。

您可以選擇將這些內部部署 Pod CIDR 的路由從本機內部部署路由器傳播到 VPC 路由表，但這並非必要。如果您的內部部署 Pod CIDR 經常變更，且您的 VPC 路由表需要更新以反映不斷變化的 Pod CIDR，我們建議您將內部部署 Pod CIDR 傳播至 VPC 路由表，不過這並不常見。

請注意，將內部部署 Pod CIDR 設為可路由的限制條件為選用項。如果您不需要在混合節點上執行 Webhook，或讓雲端節點上的 Pod 與混合節點上的 Pod 通訊，則您無需為內部部署網路上的 Pod CIDR 設定路由。

 *為什麼內部部署 Pod CIDR 需要使用混合節點進行路由？* 

將 EKS 與雲端節點的 VPC CNI 搭配使用時，VPC CNI 會將 IP 直接從 VPC 指派給 Pod。這表示不需要任何特殊路由，因為雲端 Pod 和 EKS 控制平面都可以直接連接 Pod IP。

當在內部部署執行 (以及與雲端中的其他 CNI 一起執行) 時，Pod 通常會在隔離的覆蓋網路中執行，而 CNI 則負責在 Pod 之間交付流量。這通常透過封裝來完成：CNI 會將 pod 至 pod 流量轉換為節點至節點流量，並負責兩端的封裝和解封裝。如此一來，就節點和路由器上就不需要額外的組態。

與混合節點的聯網是唯一的，因為它會提供兩種拓撲的組合：EKS 控制平面和雲端節點 (使用 VPC CNI) 預期包括節點和 Pod 的平坦網路，而混合節點上執行的 Pod 則位於覆蓋網路 (預設位於 Cilium)中，可透過使用 VXLAN 進行封裝。在混合節點上執行的 Pod 可以連接在雲端節點上執行的 EKS 控制平面和 Pod，前提是內部部署網路可路由到 VPC。不過，如果沒有內部部署網路上的 Pod CIDR 的路由，而且網路不知道如何連接至覆蓋網路以及路由到正確的節點，則最終會捨棄任何返回內部部署 Pod IP 的流量。

# 混合節點的 Kubernetes 概念
<a name="hybrid-nodes-concepts-kubernetes"></a>

此頁面詳細說明支援 EKS 混合節點系統架構的重要 Kubernetes 概念。

## VPC 中的 EKS 控制平面
<a name="hybrid-nodes-concepts-k8s-api"></a>

EKS 控制平面 ENI 的 IP 會存放在 `default` 命名空間的 `kubernetes` `Endpoints` 物件中。當 EKS 建立新的 ENI 或移除較舊的 ENI 時，EKS 會更新此物件，以便 IP 清單永遠是保持最新。

您可以透過 `kubernetes` 服務使用這些端點，也可以在 `default` 命名空間中使用這些端點。此服務為 `ClusterIP` 類型，且一律會獲指派叢集服務 CIDR 的第一個 IP。例如，對於服務 CIDR `172.16.0.0/16`，服務 IP 將為 `172.16.0.1`。

一般而言，這就是 Pod (無論是在雲端還是在混合節點中執行) 存取 EKS Kubernetes API 伺服器的方式。Pod 使用服務 IP 最為目的地 IP，且其會轉譯為其中一個 EKS 控制平面 ENI 的實際 IP。主要例外狀況是 `kube-proxy`，因為它會設定轉譯。

## EKS API 伺服器端點
<a name="hybrid-nodes-concepts-k8s-eks-api"></a>

`kubernetes` 服務 IP 並非存取 EKS API 伺服器的唯一方式。當您建立叢集時，EKS 也會建立一個 Route53 DNS 名稱。這是呼叫 EKS `DescribeCluster` API 動作時 EKS 叢集的 `endpoint` 欄位。

```
{
    "cluster": {
        "endpoint": "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com",
        "name": "my-cluster",
        "status": "ACTIVE"
    }
}
```

在公有端點存取或公有和私有端點存取叢集中，根據預設，您的混合節點會將此 DNS 名稱解析為公有 IP，且可透過網際網路路由。在私有端點存取叢集中，DNS 名稱會解析為 EKS 控制平面 ENI 的私有 IP。

這是 `kubelet` 和 `kube-proxy` 存取 Kubernetes API 伺服器的方式。如果您希望所有 Kubernetes 叢集流量流經 VPC，您需要以私有存取模式設定叢集，或修改內部部署 DNS 伺服器，以將 EKS 叢集端點解析為 EKS 控制平面 ENI 的私有 IP。

## `kubelet` 端點
<a name="hybrid-nodes-concepts-k8s-kubelet-api"></a>

`kubelet` 會公開數個 REST 端點，從而允許系統的其他部分與每個節點互動並收集資訊。在大多數叢集中，前往 `kubelet` 伺服器的大多數流量都來自控制平面，但某些監控代理程式也可能會與其互動。

透過此介面，`kubelet` 會處理各種請求：擷取日誌 (`kubectl logs`)、在容器內執行命令 (`kubectl exec`) 以及連接埠轉送流量 (`kubectl port-forward`)。其中每個請求皆會透過 `kubelet` 與基礎容器執行時期互動，而對叢集管理員和開發人員來說，這似乎是無縫的。

此 API 最常見的取用者是 Kubernetes API 伺服器。當您使用上述任何 `kubectl` 命令時，`kubectl` 會向 API 伺服器發出 API 請求，然後呼叫執行 Pod 的節點的 `kubelet` API。這就是需要從 EKS 控制平面連接至節點 IP，以及即使您的 Pod 正在執行，如果節點路由設定錯誤，您也無法存取其日誌或 `exec` 的主要原因。

 **節點 IP** 

當 EKS 控制平面與節點通訊時，其會使用以 `Node` 物件狀態 (`status.addresses`) 回報的其中一個地址。

使用 EKS 雲端節點時，kubelet 通常會在節點註冊期間將 EC2 執行個體的私有 IP 報告為 `InternalIP`。然後，雲端控制器管理員 (CCM) 會驗證此 IP，進而確保其屬於 EC2 執行個體。此外，CCM 通常會將執行個體的公有 IP (例如 `ExternalIP`) 和 DNS 名稱 (`InternalDNS` 和 `ExternalDNS`) 新增至節點狀態。

不過，混合節點沒有 CCM。當您向 EKS 混合節點 CLI (`nodeadm`) 註冊混合節點時，它會將 kubelet 設定為在節點狀態中直接報告機器的 IP，且不需要 CCM。

```
apiVersion: v1
kind: Node
metadata:
  name: my-node-1
spec:
  providerID: eks-hybrid:///us-west-2/my-cluster/my-node-1
status:
  addresses:
  - address: 10.1.1.236
    type: InternalIP
  - address: my-node-1
    type: Hostname
```

如果您的機器具有多個 IP，則 kubelet 會依照其自己的邏輯選取其中一個 IP。您可以使用 `--node-ip` 旗標來控制選取的 IP，而您可以在 `spec.kubelet.flags` 中的 `nodeadm` 組態內傳遞該旗標。只有 `Node` 物件中報告的 IP 需要來自 VPC 的路由。您的機器可能擁有無法從雲端連線的其他 IP。

## `kube-proxy`
<a name="hybrid-nodes-concepts-k8s-kube-proxy"></a>

 `kube-proxy` 負責在每個節點的網路層實作服務抽象。它可作為通往 Kubernetes Services 的流量的網路代理和負載平衡器。透過持續監看 Kubernetes API 伺服器中是否存在與服務和端點相關的變更，`kube-proxy` 會動態更新基礎主機的聯網規則，進而確保流量導向正確無誤。

在 `iptables` 模式中，`kube-proxy` 會設定數個 `netfilter` 鏈結來處理服務流量。這些規則可組成下列階層：

1.  **KUBE-SERVICES 鏈結**：所有服務流量的進入點。它具有與每個服務的 `ClusterIP` 和連接埠相符的規則。

1.  **KUBE-SVC-XXX 鏈結**：服務特定鏈結針對每個服務都設有負載平衡規則。

1.  **KUBE-SEP-XXX 鏈結**：端點特定鏈結設有實際 `DNAT` 規則。

讓我們檢查 `default` 命名空間中服務 `test-server` 的情況：\$1 服務 ClusterIP：`172.16.31.14` \$1 服務連接埠：`80` \$1 支援 Pod：`10.2.0.110`、`10.2.1.39` 和 `10.2.2.254` 

當我們檢查 `iptables` 規則時 (使用 `iptables-save 0 grep -A10 KUBE-SERVICES`)：

1. 在 **KUBE-SERVICES** 鏈結中，我們可找到與服務相符的規則：

   ```
   -A KUBE-SERVICES -d 172.16.31.14/32 -p tcp -m comment --comment "default/test-server cluster IP" -m tcp --dport 80 -j KUBE-SVC-XYZABC123456
   ```
   + 此規則與目的地為 172.16.31.14:80 的封包相符
   + 該註解指出此規則的用途：`default/test-server cluster IP`
   + 相符的封包會跳至 `KUBE-SVC-XYZABC123456` 鏈結

1. **KUBE-SVC-XYZABC123456** 鏈結設有機率型負載平衡規則：

   ```
   -A KUBE-SVC-XYZABC123456 -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-POD1XYZABC
   -A KUBE-SVC-XYZABC123456 -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-POD2XYZABC
   -A KUBE-SVC-XYZABC123456 -j KUBE-SEP-POD3XYZABC
   ```
   + 第一項規則：33.3% 的機會跳至 `KUBE-SEP-POD1XYZABC` 
   + 第二項規則：50% 的剩餘流量 (總計的 33.3%) 會跳至 `KUBE-SEP-POD2XYZABC` 
   + 最後一項規則：所有剩餘的流量 (總計的 33.3%) 會跳至 `KUBE-SEP-POD3XYZABC` 

1. 個別 **KUBE-SEP-XXX** 鏈結會執行 DNAT (目的地 NAT)：

   ```
   -A KUBE-SEP-POD1XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.0.110:80
   -A KUBE-SEP-POD2XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.1.39:80
   -A KUBE-SEP-POD3XYZABC -p tcp -m tcp -j DNAT --to-destination 10.2.2.254:80
   ```
   + 這些 DNAT 規則會重寫目的地 IP 和連接埠，以將流量導向特定的 Pod。
   + 每項規則可處理大約 33.3% 的流量，以便在 `10.2.0.110`、`10.2.1.39` 和 `10.2.2.254` 之間提供均勻的負載平衡。

此多層級鏈結結構讓 `kube-proxy` 能夠透過核心層級封包操作高效實作服務負載平衡和重新導向，而不需要資料路徑中的代理。

### 對 Kubernetes 操作的影響
<a name="hybrid-nodes-concepts-k8s-operations"></a>

節點上中斷的 `kube-proxy` 可防止該節點正常路由服務流量，進而導致依賴叢集服務的 Pod 逾時或連線失敗。首次註冊節點時，這尤其會造成干擾。在設定任何 Pod 聯網之前，CNI 需要與 Kubernetes API 伺服器通訊以取得資訊，例如節點的 Pod CIDR。為此，它會使用 `kubernetes` 服務 IP。不過，如果 `kube-proxy` 無法啟動或無法設定正確的 `iptables` 規則，則傳送至 `kubernetes` 服務 IP 的請求不會轉譯為 EKS 控制平面 ENI 的實際 IP。因此，CNI 將進入損毀循環，而且任何 Pod 都無法正常執行。

我們知道 Pod 會使用 `kubernetes` 服務 IP 與 Kubernetes API 伺服器通訊，但 `kube-proxy` 需要先設定 `iptables` 規則才能讓其運作。

`kube-proxy` 如何與 API 伺服器通訊？

必須將 `kube-proxy` 設定為使用 Kubernetes API 伺服器的實際 IP 或解析為它們的 DNS 名稱。若為 EKS，則 EKS 會將預設的 `kube-proxy` 設定為指向 EKS 在您建立叢集時建立的 Route53 DNS 名稱。您可以在 `kube-system` 命名空間的 `kube-proxy` ConfigMap 中看到此值。此 ConfigMap 的內容是注入 `kube-proxy` Pod 中的 `kubeconfig`，因此請尋找 `clusters0.cluster.server` 欄位。此值將與您 EKS 叢集的 `endpoint` 欄位相符 (呼叫 EKS `DescribeCluster` API 時)。

```
apiVersion: v1
data:
  kubeconfig: |-
    kind: Config
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        server: https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.gr7.us-west-2.eks.amazonaws.com
      name: default
    contexts:
    - context:
        cluster: default
        namespace: default
        user: default
      name: default
    current-context: default
    users:
    - name: default
      user:
        tokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
kind: ConfigMap
metadata:
  name: kube-proxy
  namespace: kube-system
```

## 可路由的遠端 Pod CIDR
<a name="hybrid-nodes-concepts-k8s-pod-cidrs"></a>

此 [混合節點的聯網概念](hybrid-nodes-concepts-networking.md) 頁面會詳細說明在混合節點上執行 Webhook 或讓在雲端節點上執行的 Pod 與在混合節點上執行的 Pod 進行通訊的需求。關鍵要求是，內部部署路由器需要知道哪個節點負責特定的 Pod IP。有幾種方法可以實現這一點，包括邊界閘道協定 (BGP)、靜態路由和位址解析通訊協定 (ARP) 代理。詳細方法請參閱下列各節。

 **邊界閘道協定 (BGP)** 

如果您的 CNI 對其提供支援 (例如 Cilium 和 Calico)，您可以使用 CNI 的 BGP 模式，以將路由傳播到每個節點的 Pod CIDR (從節點到本機路由器)。使用 CNI 的 BGP 模式時，您的 CNI 可作為虛擬路由器，因此您的本機路由器會認為 Pod CIDR 屬於不同的子網路，而您的節點是該子網路的閘道。

![\[混合節點 BGP 路由\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-bgp.png)


 **靜態路由** 

或者，您可以在本機路由器中設定靜態路由。這是將內部部署 Pod CIDR 路由至 VPC 的最簡單方法，但這也是最容易出錯且難以維護的方法。您需要確保路由始終與現有節點及其指派的 Pod CIDR 保持同步。如果您的節點數量很小且基礎結構為靜態，則此方案可行，並且不需要路由器中的 BGP 支援。如果您選擇此方案，那麼建議您使用要指派給每個節點的 Pod CIDR 配量來設定 CNI，而不是讓其 IPAM 決定。

![\[混合節點靜態路由\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-static-routes.png)


 **位址解析通訊協定 (ARP) 代理** 

ARP 代理是讓內部部署 Pod IP 可路由的另一種方法，並且當您的混合節點與本機路由器位於相同的第 2 層網路上時，特別有用。啟用 ARP 代理後，節點會回應其託管的 Pod IP 的 ARP 請求，即使這些 IP 屬於不同的子網路。

當您本機網路上的裝置嘗試連接 Pod IP 時，會先傳送 ARP 請求，並詢問「誰有此 IP？」。託管該 Pod 的混合節點將以其自己的 MAC 位址回應，表示「我可以處理該 IP 的流量」。這會在本機網路上的裝置與 Pod 之間建立一條直接路徑，而無需路由器組態。

若要使其運作，您的 CNI 必須支援代理 ARP 功能。Cilium 內建對代理 ARP 的支援，並且您可以透過組態將其啟用。關鍵考量是，Pod CIDR 不得與您環境中的任何其他網路重疊，因為這可能會導致路由衝突。

此方法有多個優點：\$1 無需使用 BGP 設定路由器或維護靜態路由 \$1 適用於您無法控制路由器組態的環境

![\[混合節點 ARP 代理\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-arp-proxy.png)


## Pod 至 Pod 封裝
<a name="hybrid-nodes-concepts-k8s-pod-encapsulation"></a>

在內部部署環境中，CNI 通常會使用封裝通訊協定來建立可在實體網路上運行的覆蓋網路，而無需重新設定。本節說明此封裝如何運作。請注意，某些詳細資訊可能會因您使用的 CNI 而有所不同。

封裝會將原始 Pod 網路封包包裝在另一個可透過基礎實體網路路由的網路封包內。這可讓 Pod 跨執行相同 CNI 的節點進行通訊，而不需要實體網路知道如何路由這些 Pod CIDR。

與 Kubernetes 搭配使用的最常見封裝通訊協定是虛擬局域網擴展 (VXLAN)，但視您的 CNI 而定，也可使用其他通訊協定 (例如 `Geneve`)。

### VXLAN 封裝
<a name="_vxlan_encapsulation"></a>

VXLAN 將第 2 層乙太網路訊框封裝在 UDP 封包內。當 Pod 將流量傳送至不同節點上的另一個 Pod 時，CNI 會執行下列動作：

1. CNI 攔截來自 Pod A 的封包

1. CNI 將原始封包包裝在 VXLAN 標頭中

1. 然後，此已包裝的封包會透過節點的一般網路堆疊傳送至目的地節點

1. 目的地節點上的 CNI 會取消包裝封包並將其交付至 Pod B

以下是 VXLAN 封裝期間封包結構的相關情況：

原始 Pod 至 Pod 封包：

```
+-----------------+---------------+-------------+-----------------+
| Ethernet Header | IP Header     | TCP/UDP     | Payload         |
| Src: Pod A MAC  | Src: Pod A IP | Src Port    |                 |
| Dst: Pod B MAC  | Dst: Pod B IP | Dst Port    |                 |
+-----------------+---------------+-------------+-----------------+
```

VXLAN 封裝後：

```
+-----------------+-------------+--------------+------------+---------------------------+
| Outer Ethernet  | Outer IP    | Outer UDP    | VXLAN      | Original Pod-to-Pod       |
| Src: Node A MAC | Src: Node A | Src: Random  | VNI: xx    | Packet (unchanged         |
| Dst: Node B MAC | Dst: Node B | Dst: 4789    |            | from above)               |
+-----------------+-------------+--------------+------------+---------------------------+
```

VXLAN 網路識別符 (VNI) 可區分不同的覆蓋網路。

### Pod 通訊案例
<a name="_pod_communication_scenarios"></a>

 **相同混合節點上的 Pod** 

當相同混合節點上的 Pod 彼此通訊時，通常不需要封裝。CNI 會設定本機路由，而該路由可透過節點的內部虛擬介面來引導 Pod 之間的流量：

```
Pod A -> veth0 -> node's bridge/routing table -> veth1 -> Pod B
```

封包永遠不會離開節點，並且也不需要封裝。

 **不同混合節點上的 Pod** 

不同混合節點上的 Pod 之間的通訊需要封裝：

```
Pod A -> CNI -> [VXLAN encapsulation] -> Node A network -> router or gateway -> Node B network -> [VXLAN decapsulation] -> CNI -> Pod B
```

這可讓 Pod 流量周遊實體網路基礎結構，而無需實體網路來了解 Pod IP 路由。

# 混合節點的網路流量流程
<a name="hybrid-nodes-concepts-traffic-flows"></a>

此頁面詳細說明 EKS 混合節點的網路流量流程，其中各圖表會顯示不同流量類型的端到端網路路徑。

涵蓋下列流量流程：
+  [混合節點 `kubelet` 到 EKS 控制平面](#hybrid-nodes-concepts-traffic-flows-kubelet-to-cp) 
+  [EKS 控制平面到混合節點 (`kubelet` 伺服器)](#hybrid-nodes-concepts-traffic-flows-cp-to-kubelet) 
+  [在混合節點上執行的 Pod 到 EKS 控制平面](#hybrid-nodes-concepts-traffic-flows-pods-to-cp) 
+  [EKS 控制平面到混合節點上執行的 Pod (Webhook)](#hybrid-nodes-concepts-traffic-flows-cp-to-pod) 
+  [在混合節點上執行的 Pod 到 Pod](#hybrid-nodes-concepts-traffic-flows-pod-to-pod) 
+  [雲端節點上的 Pod 到混合節點上的 Pod (東西流量)](#hybrid-nodes-concepts-traffic-flows-east-west) 

## 混合節點 `kubelet` 到 EKS 控制平面
<a name="hybrid-nodes-concepts-traffic-flows-kubelet-to-cp"></a>

![\[混合節點 kubelet 到 EKS 控制平面\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-kubelet-to-cp-public.png)


### 請求
<a name="_request"></a>

 **1`kubelet`. 啟動請求** 

當混合節點上的 `kubelet` 需要與 EKS 控制平面進行通訊時 (例如，報告節點狀態或取得 Pod 規格)，它會使用節點註冊期間提供的 `kubeconfig` 檔案。該 `kubeconfig` 具有 API 伺服器端點 URL (Route53 DNS 名稱)，而不是直接 IP 位址。

`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` (儘管並非從 Pod) 到 EKS 控制平面的流量不會經過您的 VPC，而是會使用全球網際網路基礎結構。

### 回應
<a name="_response"></a>

在 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 控制平面
<a name="_hybrid_node_kube_proxy_to_eks_control_plane"></a>

如果您啟用叢集的公有端點存取，則傳回流量會使用公有網際網路。此流量源自混合節點上的 `kube-proxy` 且通往 EKS 控制平面，因此須遵循與從 `kubelet` 到 EKS 控制平面的流量相同的路徑。

## EKS 控制平面到混合節點 (`kubelet` 伺服器)
<a name="hybrid-nodes-concepts-traffic-flows-cp-to-kubelet"></a>

![\[EKS 控制平面到混合節點\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-cp-to-kubelet.png)


### 請求
<a name="_request_2"></a>

 **1。EKS Kubernetes API 伺服器啟動請求** 

EKS Kubernetes API 伺服器會從節點物件的狀態擷取節點的 IP 位址 (`10.80.0.2`)。然後，它會透過 VPC 中的 ENI 路由此請求，因為目的地 IP 屬於已設定的遠端節點 CIDR (`10.80.0.0/16`)。初始封包如下所示：

```
+-----------------+---------------------+-----------------+
| 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 的特定路由 (圖表中的第二個路由)。根據此路由規則，該封包會導向至 VPC-to-onprem 閘道。

 **4. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。

 **5. 內部部署網路接收** 

該封包會抵達本機內部部署路由器，以處理混合節點所在的子網路的流量。

 **6. 最終交付** 

本機路由器會識別目的地 IP (`10.80.0.2`) 位址屬於其直接連接的網路，並將封包直接轉送至目標混合節點，而 `kubelet` 會在其中接收和處理請求。

### 回應
<a name="_response_2"></a>

在混合節點的 `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，以便完成往返。

## 在混合節點上執行的 Pod 到 EKS 控制平面
<a name="hybrid-nodes-concepts-traffic-flows-pods-to-cp"></a>

![\[在混合節點上執行的 Pod 到 EKS 控制平面\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-pod-to-cp.png)


### 不使用 CNI NAT
<a name="_without_cni_nat"></a>

### 請求
<a name="_request_3"></a>

Pod 通常會透過 `kubernetes` 服務與 Kubernetes API 伺服器進行通訊。服務 IP 是叢集的服務 CIDR 的第一個 IP。此慣例允許需要在 CoreDNS 可用之前執行的 Pod，以便連接 API 伺服器，例如 CNI。請求以服務 IP 作為目的地離開 Pod。例如，如果服務 CIDR 為 `172.16.0.0/16`，則服務 IP 將為 `172.16.0.1`。

 **1。Pod 啟動請求** 

Pod 會從隨機來源連接埠傳送請求至 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 不屬於其管理的任何 Pod CIDR。由於**傳出 NAT 已停用**，CNI 會將該封包傳遞至主機網路堆疊，而且不會進行修改。

 **3. 節點網路處理** 

該封包會進入節點的網路堆疊，其中 `netfilter` 勾點會觸發由 kube-proxy 設定的 `iptables` 規則。按下列順序依次適用數條規則：

1. 該封包會先命中 `KUBE-SERVICES` 鏈結，其中包含與每個服務的 ClusterIP 和連接埠相符的規則。

1. 該相符規則會跳至 `kubernetes` 服務的 `KUBE-SVC-XXX` 鏈結 (以 `172.16.0.1:443` 為目的地的封包)，其中包含負載平衡規則。

1. 該負載平衡規則會隨機選取控制平面 ENI IP (`10.0.0.132` 或 `10.0.1.23`) 的其中一個 `KUBE-SEP-XXX` 鏈結。

1. 選取的 `KUBE-SEP-XXX` 鏈結具有實際規則，可將目的地 IP 從服務 IP 變更為選取的 IP。這就是所謂的目的地網路位址轉譯 (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。

### 回應
<a name="_response_3"></a>

在 EKS 控制平面處理請求後，它會傳送回應至 Pod：

 **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 屬於已設定的遠端 Pod CIDR (`10.85.0.0/16`)，因此它會透過其在 VPC 中的 ENI 傳送，並將子網路的路由器作為下一個躍點。

 **6. VPC 路由** 

VPC 路由表包含遠端 Pod CIDR (`10.85.0.0/16`) 的項目，並且會將此流量導向 VPC-to-onprem 閘道。

 **5. 跨邊界傳輸** 

閘道會透過您已建立的連線 (例如 Direct Connect 或 VPN)，將封包跨雲端邊界傳輸到您的內部部署網路。

 **4. 內部部署網路接收** 

封包送達本機內部部署路由器。

 **3. 交付至節點** 

路由器的資料表有一個 `10.85.1.0/24` 的項目，其中 `10.80.0.2` 將作為下一個躍點，負責將封包交付至我們的節點。

 **2. 節點網路處理** 

當封包由節點的網路堆疊處理時，`conntrack` (`netfilter` 的一部分) 會將封包與 Pod 最初建立的連線進行比對。由於最初套用了 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 屬於其網路中的 Pod，並將封包交付至正確的 Pod 網路命名空間。

此流程展示為什麼遠端 Pod CIDR 必須能夠從 VPC 一直正確路由到託管每個 Pod 的特定節點，整個傳回路徑取決於跨雲端和內部部署網路的適當 Pod IP 路由。

### 使用 CNI NAT
<a name="_with_cni_nat"></a>

此流程與*不使用 CNI NAT* 的流程非常相似，但有一個重要差異：CNI 會先將來源 NAT (SNAT) 套用至封包，然後再將其傳送至節點的網路堆疊。這樣一來，即會將封包的來源 IP 變更為節點的 IP，從而允許封包路由回節點，而不需要額外的路由組態。

### 請求
<a name="_request_4"></a>

 **1。Pod 啟動請求** 

Pod 會從隨機來源連接埠傳送請求至 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 不屬於其管理的任何 Pod 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` 會顯示為獨立的區塊，但實際上，有些 CNI 可能會使用 `iptables` 來套用 NAT。

 **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。

### 回應
<a name="_response_4"></a>

在 EKS 控制平面處理請求後，它會傳送回應至 Pod：

 **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` 的一部分) 會將封包與 Pod 最初建立的連線進行比對，而且由於最初套用了 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 變更回 Pod 的 IP：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 172.16.0.1 | Src: 443            |                 |
| Dst: 10.85.1.56 | Dst: 67493          |                 |
+-----------------+---------------------+-----------------+
```

CNI 偵測到目的地 IP 屬於其網路中的 Pod，並將封包交付至正確的 Pod 網路命名空間。

此流程會示範 CNI NAT-ing 可如何透過允許封包路由回節點來簡化組態，並且無需額外的 Pod CIDR 路由。

## EKS 控制平面到混合節點上執行的 Pod (Webhook)
<a name="hybrid-nodes-concepts-traffic-flows-cp-to-pod"></a>

![\[EKS 控制平面到混合節點上執行的 Pod\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-cp-to-pod.png)


此流量模式最常見於 Webhook 中，而 EKS 控制平面需要直接啟動與混合節點上 Pod 中執行的 Webhook 伺服器的連線。範例包括驗證和變換許可 Webhook，其中這些 Webhook 會在資源驗證或變換程序期間由 API 伺服器呼叫。

### 請求
<a name="_request_5"></a>

 **1。EKS Kubernetes API 伺服器啟動請求** 

在叢集中設定 Webhook 並且相關 API 操作將其觸發後，EKS Kubernetes API 伺服器需要直接連線至 Webhook 伺服器 Pod。API 伺服器會先從與 Webhook 相關聯的服務或端點資源中查詢 Pod 的 IP 位址。

假設 Webhook Pod 在具有 IP `10.85.1.23` 的混合節點上執行，EKS Kubernetes API 伺服器會建立對 Webhook 端點的 HTTPS 請求。初始封包會透過 VPC 中的 EKS 控制平面 ENI 傳送，因為目的地 IP `10.85.1.23` 屬於已設定的遠端 Pod CIDR (`10.85.0.0/16`)。封包如下所示：

```
+-----------------+---------------------+-----------------+
| 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 路由表包含適用於遠端 Pod 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 位址。

 **5. 內部部署網路接收** 

封包送達本機內部部署路由器。路由器會參考其路由表，以判定連接 10.85.1.23 地址的方式。為此，您的內部部署網路必須具有將流量導向適當混合節點的 Pod 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 仍然是 Pod 的 IP。

 **7. CNI 處理** 

節點的網路堆疊會接收封包，並發現目的地 IP 不是節點的自有 IP，然後將其傳遞給 CNI 以進行處理。CNI 會識別目的地 IP 屬於在此節點上以本機執行的 Pod，並透過適當的虛擬介面將封包轉送至正確的 Pod：

```
Original packet -> node routing -> CNI -> Pod's network namespace
```

Pod 中的 Webhook 伺服器會接收請求並進行處理。

### 回應
<a name="_response_5"></a>

在 Webhook Pod 處理請求後，它會遵循相同路徑反向傳回回應：

 **7. Pod 傳送回應** 

Webhook Pod 會使用其自己的 IP 作為來源建立回應封包，並將原始請求者 (EKS 控制平面 ENI) 作為目的地：

```
+-----------------+---------------------+-----------------+
| IP Header       | TCP Header          | Payload         |
| Src: 10.85.1.23 | Src: 8443           |                 |
| Dst: 10.0.0.132 | Dst: 41892          |                 |
+-----------------+---------------------+-----------------+
```

CNI 會識別此封包會移至外部網路 (而非本機 Pod)，並將封包傳遞至保留原始來源 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 接收** 

該封包會到達連接到 EKS Kubernetes API 伺服器的 ENI，以便完成往返。API 伺服器會接收 Webhook 回應，並繼續根據此回應處理原始 API 請求。

此流量流程示範為什麼遠端 Pod CIDR 必須正確進行設定和路由：
+ VPC 必須具有指向內部部署閘道的遠端 Pod CIDR 的路由
+ 您的內部部署網路必須具有 Pod CIDR 的路由，並將流量導向託管這些 Pod 的特定節點
+ 如果沒有此路由組態，將無法從 EKS 控制平面連接混合節點上 Pod 中執行的 Webhook 和其他類似服務。

## 在混合節點上執行的 Pod 到 Pod
<a name="hybrid-nodes-concepts-traffic-flows-pod-to-pod"></a>

![\[在混合節點上執行的 Pod 到 Pod\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-pod-to-pod.png)


本節說明在不同混合節點上執行的 Pod 會如何彼此進行通訊。此範例假設您的 CNI 使用 VXLAN 進行封裝，而這在 Cilium 或 Calico 等 CNI 中很常見。整體程序與其他封裝通訊協定，例如 Geneve 或 IP-in-IP。

### 請求
<a name="_request_6"></a>

 **1。Pod A 啟動通訊** 

節點 1 上的 Pod A (`10.85.1.56`) 想要將流量傳送至節點 2 上的 Pod 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 攔截和處理封包** 

當 Pod A 的封包離開其網路命名空間時，CNI 會將其攔截。CNI 會參考其路由表並判定： - 目的地 IP (`10.85.2.67`) 屬於 Pod CIDR - 此 IP 不在本機節點上，但屬於節點 2 (`10.80.0.3`) - 該封包需要使用 VXLAN 進行封裝。

封裝的決策至關重要，因為底層實體網路不知道如何直接路由 Pod CIDR，它只知道如何在節點 IP 之間路由流量。

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 網路識別符 (VNI) 可識別此封包所屬的覆蓋網路 - 整個原始封包 (將 Pod A 的 IP 作為來源，將 Pod B 的 IP 作為目的地) 可在內部完整保留

已封裝的封包現在會進入節點 1 的常規網路堆疊，並以與任何其他封包相同的方式進行處理：

1.  **節點網路處理**：節點 1 的網路堆疊會根據其目的地 (`10.80.0.3`) 路由封包

1.  **本機網路交付**：
   + 如果兩個節點位於相同的第 2 層網路上，則該封包會直接傳送至節點 2
   + 如果封包位於不同的子網路上，則會先將該封包轉送至本機路由器

1.  **路由器處理**：路由器會根據其路由表轉送封包，並將其交付至節點 2

 **3. 接收節點處理** 

當封裝的封包抵達節點 2 (`10.80.0.3`) 時：

1. 節點的網路堆疊會接收此封包並將其識別為 VXLAN 封包 (UDP 連接埠 `4789`)

1. 該封包會傳遞至 CNI 的 VXLAN 介面，以進行處理

 **4. VXLAN 解封裝** 

節點 2 上的 CNI 會處理 VXLAN 封包：

1. 它會移除外部標頭 (乙太網路、IP、UDP 和 VXLAN)

1. 它會擷取原始內部封包

1. 該封包現恢復為其原始格式：

```
+------------------+-----------------+-------------+-----------------+
| 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`) 和：

1. 識別此 IP 屬於本機 Pod

1. 透過適當的虛擬介面路由封包

1. 將封包交付至 Pod B 的網路命名空間

### 回應
<a name="_response_6"></a>

當 Pod B 回應 Pod A 時，整個程序會發生反轉，即以相反順序執行：

1. Pod B 會將封包傳送至 Pod A (`10.85.1.56`)

1. 節點 2 的 CNI 會使用 VXLAN 進行封裝，並將目的地設定為節點 1 (`10.80.0.2`)

1. 封裝的封包會交付至節點 1

1. 節點 1 的 CNI 會將其解封裝，並將原始回應交付給 Pod A

## 雲端節點上的 Pod 到混合節點上的 Pod (東西流量)
<a name="hybrid-nodes-concepts-traffic-flows-east-west"></a>

![\[雲端節點上的 Pod 到混合節點上的 Pod\]](http://docs.aws.amazon.com/zh_tw/eks/latest/userguide/images/hybrid-nodes-east-west.png)


### 請求
<a name="_request_7"></a>

 **1。Pod A 啟動通訊** 

EC2 節點上的 Pod A (`10.0.0.56`) 想要將流量傳送至混合節點上的 Pod 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 時，Pod A 具有來自 VPC CIDR 的 IP，並會直接連接到 EC2 執行個體上的 ENI。Pod 的網路命名空間已連接至 VPC 網路，因此該封包會直接進入 VPC 路由基礎結構。

 **2. VPC 路由** 

VPC 路由表包含遠端 Pod 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 位址。

 **4. 內部部署網路接收** 

封包送達本機內部部署路由器。路由器會參考其路由表，以判定連接 10.85.1.56 地址的下一個躍點。您的內部部署路由器必須具有將流量導向適當混合節點的 Pod 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`)。當封包抵達節點時，它仍然將 Pod A 的 IP 作為來源，並將 Pod B 的 IP 作為目的地。

 **6. CNI 處理** 

節點的網路堆疊會接收封包，並發現目的地 IP 不是其自有 IP，然後將其傳遞給 CNI 以進行處理。CNI 會識別目的地 IP 屬於在此節點上以本機執行的 Pod，並透過適當的虛擬介面將封包轉送至正確的 Pod：

```
Original packet -> node routing -> CNI -> Pod B's network namespace
```

Pod B 會接收封包並視需要進行處理。

### 回應
<a name="_response_7"></a>

 **6. Pod B 傳送回應** 

Pod B 會以其自有 IP 作為來源建立回應封包，而會將 Pod 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 內的子網路。該封包會透過 VPC 網路路由至託管 Pod A 的 EC2 執行個體。

 **1。Pod A 接收回應** 

該封包抵達 EC2 執行個體，並透過其連接的 ENI 直接交付至 Pod A。由於 VPC CNI 不會為 VPC 中的 Pod 使用覆蓋網路，因此不需要額外的解封裝 - 封包送達時，其原始標題會完整保留。

此東西流量流程示範為什麼遠端 Pod CIDR 必須正確設定並可從雙向路由：
+ VPC 必須具有指向內部部署閘道的遠端 Pod CIDR 的路由
+ 您的內部部署網路必須具有 Pod CIDR 的路由，並將流量導向託管這些 Pod 的特定節點。