POD的几种通信类型

pod作为K8S中的最小逻辑单元,它们的网络通信如何完成,一共有几种类型?

我大致分为3类:

  • 1、同 pod 内容器间通信;

  • 2、同节点上的 pod 间通信;

  • 3、不同节点上的 pod 间通信;

一、同 pod 内的容器间通信

同 pod 内的容器间通信最简单,这些容器共享网络命名空间,每个命名空间下都有 lo 回环接口,可以通过 localhost 来完成通信。

二、同节点上的 pod 间通信

当我们将 curl 容器和 httpbin 分别在两个 pod 中运行,这两个 pod 有可能调度到同一个节点上。curl发出的请求根据容器内的路由表到达了 pod 内的 eth0 接口。然后通过与 eth0 相连的隧道 veth1 到达节点的根网络空间。

veth1 通过网桥 cni0 与其他 pod 相连虚拟以太接口 vethX 相连,网桥会询问所有相连的接口是否拥有原始请求中的 IP 地址(比如这里的 10.42.1.9)。收到响应后,网桥会记录映射信息(10.42.1.9 => veth0),同时将数据转发过去。最终数据经过 veth0 隧道进入 pod httpbin 中。

三、不同节点的 pod 间通信

跨节点的 pod 间通信会复杂一些,且 不同网络插件的处理方式不同,这里选择一种容易理解的方式来简单说明下。

前半部分的流程与同节点 pod 间通信类似,当请求到达网桥,网桥询问哪个 pod 拥有该 IP 但是没有得到回应。流程进入主机的路由寻址过程,到更高的集群层面。

在集群层面有一张路由表,里面存储着每个节点的 Pod IP 网段(节点加入到集群时会分配一个 Pod 网段(Pod CIDR),比如在 k3s 中默认的 Pod CIDR 是 10.42.0.0/16,节点获取到的网段是 10.42.0.0/24、10.42.1.0/24、10.42.2.0/24,依次类推)。通过节点的 Pod IP 网段可以判断出请求 IP 的节点,然后请求被发送到该节点。

总结

现在应该对 Kubernetes 的网络通信有初步的了解了吧。

整个通信的过程需要各种组件的配合,比如 Pod 网络命名空间、pod 以太网接口 eth0、虚拟以太网接口 vethX、网桥(network bridge) cni0 等。其中有些组件与 pod 一一对应,与 pod 同生命周期。虽然可以通过手动的方式创建、关联和删除,但对于 pod 这种非永久性的资源会被频繁地创建和销毁,太多人工的工作也是不现实的。

实际上这些工作都是由容器委托给网络插件来完成的,而网络插件所遵循的规范 CNI(Container Network Interface)。

网络插件都做了什么?

  1. 创建 pod(容器)的网络命名空间
  2. 创建接口
  3. 创建 veth 对
  4. 设置命名空间网络
  5. 设置静态路由
  6. 配置以太网桥接器
  7. 分配 IP 地址
  8. 创建 NAT 规则
  9. ......

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!