

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# 混合节点的网络流量
<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_cn/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_cn/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 到本地”网关。

 **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_cn/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` 服务（发往 `172.16.0.1:443` 的数据包）的 `KUBE-SVC-XXX` 链。

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 属于配置的远程容器组 CIDR (`10.85.0.0/16`)，它通过 VPC 中的 ENI 将其发送，并将子网的路由器作为下一个跃点。

 **6. VPC 路由** 

VPC 路由表包含远程容器组 CIDR (`10.85.0.0/16`) 的条目，该条目将此流量引导至“VPC 到本地”网关。

 **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 属于其网络中的某个容器组（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 到本地”网关。

 **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 操作如何允许将数据包路由回节点，而无需为容器组（pod）CIDR 进行额外路由，从而简化配置。

## EKS 控制面板到混合节点上运行的容器组（pod）（Webhook）
<a name="hybrid-nodes-concepts-traffic-flows-cp-to-pod"></a>

![\[EKS 控制面板到混合节点上运行的容器组（pod）\]](http://docs.aws.amazon.com/zh_cn/eks/latest/userguide/images/hybrid-nodes-cp-to-pod.png)


这种流量模式最常见于 Webhook，其中 EKS 控制面板需要直接启动与在混合节点上的容器组（pod）中运行的 Webhook 服务器的连接。示例包括验证和变更准入 Webhook，它们由 API 服务器在资源验证或变更过程中调用。

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

 **1。EKS Kubernetes API 服务器启动请求** 

如果集群中配置了 Webhook 并且相关的 API 操作触发了它，EKS Kubernetes API 服务器需要直接连接到 Webhook 服务器容器组（pod）。API 服务器首先从与 Webhook 关联的服务或端点资源中查找容器组（pod）的 IP 地址。

假设 Webhook 容器组在 IP 为 `10.85.1.23` 的混合节点上运行，则 EKS Kubernetes API 服务器会创建一个针对 Webhook 端点的 HTTPS 请求。初始数据包通过 VPC 中的 EKS 控制面板 ENI 发送，因为目标 IP `10.85.1.23` 属于配置的远程容器组 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 路由表包含远程容器组 CIDR (`10.85.0.0/16`) 的专用路由。此路由规则将数据包引导至“VPC 到本地”网关（例如，用于 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 识别此数据包发送到外部网络（不是本地容器组），并将数据包传递到节点的网络堆栈，同时保留原始源 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 服务器接收 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_cn/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 上的容器组 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 拦截并处理数据包** 

容器组（pod）A 的数据包离开其网络命名空间时，CNI 会拦截它。CNI 会查询其路由表并确定：– 目标 IP (`10.85.2.67`) 属于容器组 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）确定此数据包属于哪个叠加网络 – 整个原始数据包（以容器组 A 的 IP 作为源，容器组 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. 容器组 B 向容器组 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_cn/eks/latest/userguide/images/hybrid-nodes-east-west.png)


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

 **1。容器组（pod）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 时，容器组（pod）A 拥有来自 VPC CIDR 的 IP，并直接附加到 EC2 实例上的 ENI。容器组（pod）的网络命名空间连接到 VPC 网络，因此数据包直接进入 VPC 路由基础设施。

 **2. VPC 路由** 

VPC 路由表包含远程容器组 CIDR (`10.85.0.0/16`) 的专用路由，该路由将此流量引导至“VPC 到本地”网关：

```
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）的特定节点。