# 集群底层网络

Kubernetes 本身并不负责实现 Pod 之间的网络联通，通常是由系统管理员或者 Container Network Interface (CNI) 插件建立的，因此本节仅针对默认情况下的 Pod 间的底层网络架构进行介绍。默认情况下的底层网络架构如下图所示：

![Kubernetes中默认底层网络架构](https://2906552408-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M6Ub8CloS5kJszh6xSR%2Fsync%2F7c5757271b89fb3735339127aeb421310187f375.png?generation=1588594613592543\&alt=media)

由于 Kubernetes 需要保证集群内部的任意两个 Pod 具有不同的 IP 地址，因此默认情况下使用了一个比较粗暴的解决方案：每个 Node 使用一个网段，如上图，节点 A 使用的是 `10.1.1.0/24` 网段，而节点 B 使用的是 `10.1.2.0/24` 网段，如此可以保证不同的节点中必然不会有重复的容器。

## 同节点中的 Pod 通信

默认情况下，Pod 使用 veth pair 设备连接至 Docker 网络提供的 LinuxBridge 设备。因此同一个 Node 中的 Pod 间的通信只需要将数据经由该 LinuxBridge 转发即可。

## 不同节点中的 Pod 通信

连接不同 Node 中的 LinuxBridge 有多种方案：overlay 或 underlay 等。

以上图为例，在默认情况下，Worker A 为了转发其内部 Pod 中的数据至 Worker B，应当包含下述路由条目：

|     目标网络    |     下一跳    |
| :---------: | :--------: |
| 10.1.2.0/24 | 10.100.0.2 |

如此，当 Worker A 中的 Pod A 和 Pod B 中的目标地址为 `10.1.2.1` 或 `10.1.2.2` 的数据发送至 eth0 时，其可以通过查询到上述路由条目，将其转发至 Worker B 中。

同样，Worker B 应当包含下述路由条目，以此可以将其本地 Pod 的数据转发至 Worker A 中：

|     目标网络    |     下一跳    |
| :---------: | :--------: |
| 10.1.1.0/24 | 10.100.0.1 |

## 容器网络接口 (CNI) 插件

在容器的发展过程中，为了使得容器之间的网络建立更加方便，诞生了**容器网络接口 (CNI)**&#x9879;目，即只要满足该接口规范开发的网络插件，就可以被容器使用。

目前已经有许多插件，并且均提供了 YAML 定义清单，以便 Kubernetes 应用：

* Calico
* Flannel
* Romana
* Weave Net
* 等等

若想自行开发 CNI 插件，可以参考[官方提供的案例](https://github.com/containernetworking/plugins/tree/master/plugins/sample/main.go)，或者也可以参考官方提供的插件的源码，如 [Bridge](https://github.com/containernetworking/plugins/blob/master/plugins/main/bridge/bridge.go) 等。
