🗒️k8s pod间的网络实现
2023-5-8
| 2023-5-17
0  |  0 分钟
type
status
date
slug
summary
tags
category
icon
password

写在前面

CNI插件聚焦的是pod间的通信,本文主要讲的是CNI插件的部分实现方案。但仅使用此插件还有一个问题:pod 是经常变化的,故出现了service(kube-proxy)。作为service的补充,又出现ingress等方案。当然,还有更强大的server mesh解决方案。
service的缺陷:
  • 首先,如果转发的 pod 不能正常提供服务,它不会自动尝试另一个 pod,当然这个可以通过 readiness probes 来解决。每个 pod 都有一个健康检查的机制,当有 pod 健康状况有问题时,kube-proxy 会删除对应的转发规则。
  • 另外,nodePort 类型的服务也无法添加 TLS 或者更复杂的报文路由机制。

1. k8s跨主机的网络实现

在 Docker 的默认配置下,不同宿主机上的容器通过 IP 地址进行互相访问是根本做不到的。为了解决这个问题,社区中出现了很多网络方案。同时k8s为了更好的控制网络的接入,推出了CNI即容器网络的API接口。
实际上CNI的容器网络通信流程跟前面的基础网络一样,只是CNI维护了一个单独的网桥来代替 docker0。这个网桥的名字就叫作:CNI 网桥,它在宿主机上的设备名称默认是:cni0。cni的设计思想,就是:Kubernetes 在启动 Infra 容器之后,就可以直接调用 CNI 网络插件,为这个 Infra 容器的 Network Namespace,配置符合预期的网络栈。
CNI插件三种网络实现模式:
大二层overlay网络
大二层overlay网络
三层网络
三层网络
underlay网络
underlay网络
  • overlay (基于隧道)模式是基于隧道技术实现的,整个容器网络和主机网络独立,容器之间跨主机通信时将整个容器网络封装到底层网络中,然后到达目标机器后再解封装传递到目标容器。不依赖与底层网络的实现。实现的插件有flannel(UDP、vxlan)、calico(IPIP)等等
  • 三层路由模式(基于路由)中容器和主机也属于不通的网段,他们容器互通主要是基于路由表打通,无需在主机之间建立隧道封包。但是限制条件必须依赖大二层同个局域网内。实现的插件有flannel(host-gw)、calico(BGP)等等
  • underlay网络是底层网络,负责互联互通。 容器网络和主机网络依然分属不同的网段,但是彼此处于同一层网络,处于相同的地位。整个网络三层互通,没有大二层的限制,但是需要强依赖底层网络的实现支持.实现的插件有calico(BGP)等等

2. flannel插件

Kubernetes系统上Pod网络的实现依赖于第三方插件,而Flannel是由CoreOS主推的目前比较主流的容器网络解决方案,CNI插件有两种功能:网络配置和网络策略,由于flannel比较简单,并不支持网络策略,flannel项目自身只是一个框架,真正提供网络功能的是它的后端实现,目前,Flannel支持三种不同后端实现,分别是:
  • UDP
  • VXLAN(默认方案)
  • host-gw
  • Directrouting(VXLAN的另一种方案)

2.1 VXLAN模式

UDP是Flannel项目最早支持的一种方式,是性能最差的方式,目前已被废弃。用的最多的是VXLANhost-gw模式的部署。
相比于两台宿主机之间的直接通信,基于 Flannel UDP 模式的容器通信多了一个额外的步骤,即 flanneld 的处理过程。而这个过程,由于使用到了 flannel0 这个 TUN 设备,仅在发出 IP 包的过程中,就需要经过三次用户态与内核态之间的数据拷贝,如下所示:
notion image
UDP 和 VXLAN 模式对比:
都是在现有的物理网络之上,通过软件创建一层虚拟的覆盖网络(Overlay Network),把不同宿主机上创建的虚拟设备连通,从而达到容器跨主机通信的目的。在每一个节点上启动flanneld进程,分配子网,创建虚拟设备,添加路由规则,维护相关表等。
模式
OSI
虚拟设备
拷贝次数
封装/解封装
维护表
内核原生支持
UDP
三层
flannel0(TUN)
三次
flanneld在用户态完成
etcd route
VXLAN
二层
flannel.1(VTEP)
一次
flannel.1在内核态完成
etcd、route ARP、FDB
VXLAN用的是大二层overlay网络模式,可以把flannel.1和cni0看成一个整体,如下图。和传统docker容器里的docker0网桥相比,docker0网桥只能让同一台节点的容器互通,而overlay网桥可以让整个集群的容器互通。
notion image

2.2 host-gw模式

由于VXLAN还存在额外的封包解包,导致其性能仍有部分损耗,所以Flannel就有了host-gw模式,即把宿主机eth0当作网关,除了本地路由之外没有额外开销,性能和calico差不多,由于没有叠加来实现报文转发,这样会导致路由表庞大。因为一个节点对应一个网络,也就对应一条路由条目。
💡
根据实际的测试,host-gw 的性能损失大约在 10% 左右,而其他所有基于 VXLAN“隧道”机制的网络方案,性能损失都在 20%~30% 左右。
💡
host-gw虽然VXLAN网络性能要强很多,但是种方式有个缺陷:要求各物理节点必须在同一个二层网络中,物理节点必须在同一网段中。这样会使得一个网段中的主机量会非常多,万一发一个广播报文就会产生干扰。在私有云场景下,宿主机不在同一网段是很常见的状态,所以就不能使用host-gw了。

2.3 Directrouting模式

VXLAN还有另外一种功能,VXLAN也支持类似host-gw的玩法:如果两个节点在同一网段时使用host-gw通信,如果不在同一网段中,即当前pod所在节点与目标pod所在节点中间有路由器,就使用VXLAN这种方式,使用叠加网络。
结合了Host-gw和VXLAN,这就是VXLAN的Directrouting模式
因此Flannel的VXLAN模式有两种:
  1. VXLAN: 原生的VXLAN,即扩展的虚拟LAN
  1. Directrouting:直接路由型
Directrouting模式设置:修改下载的kube-flannel.yml,将flannel的configmap对象改为
net-conf.json: | { "Network": "10.244.0.0/16", #默认网段 "Backend": { "Type": "VXLAN", # 注意格式 "Directrouting": true } }

3. 参考

 
技术
  • k8s
  • 网络
  • k8s kube-proxy的模式k8s故障排查
    目录