k8s
通过
CNI
接口接入其他插件来实现网络通讯。目前比较流行的插件有
flannel
,
calico
等。
CNI
插件存放位置:
# cat /etc/cni/net.d/10-flannel.conflist
插件使用的解决方案如下:
•
虚拟网桥,虚拟网卡,多个容器共用一个虚拟网卡进行通信。
•
多路复用:
MacVLAN
,多个容器共用一个物理网卡进行通信。
•
硬件交换:
SR-LOV
,一个物理网卡可以虚拟出多个接口,这个性能最好。
•
容器间通信:同一个
pod
内的多个容器间的通信,通过
lo
即可实现;
• pod
之间的通信:
•
同一节点的
pod
之间通过
cni
网桥转发数据包。
•
不同节点的
pod
之间的通信需要网络插件支持。
• pod
和
service
通信
:
通过
iptables
或
ipvs
实现通信,
ipvs
取代不了
iptables
,因为
ipvs
只能做
负载均衡,而做不了
nat
转换。
• pod
和外网通信:
iptables
的
MASQUERADE
。
• Service
与集群外部客户端的通信;(
ingress
、
nodeport
、
loadbalancer
)
flannel网络
• VXLAN
,即
Virtual Extensible LAN
(虚拟可扩展局域网),是
Linux
本身支持的一网种网络虚
拟化技术。
VXLAN
可以完全在内核态实现封装和解封装工作,从而通过“隧道”机制,构建
出覆盖网络(
Overlay Network
)。
• VTEP
:
VXLAN Tunnel End Point
(虚拟隧道端点),在
Flannel
中
VNI
的默认值是
1
,这也是
为什么宿主机的
VTEP
设备都叫
flannel.1
的原因。
• Cni0:
网桥设备,每创建一个
pod
都会创建一对
veth pair
。其中一端是
pod
中的
eth0
,另一端
是
Cni0
网桥中的端口(网卡)。
• Flannel.1: TUN
设备
(
虚拟网卡
)
,用来进行
vxlan
报文的处理(封包和解包)。不同
node
之间
的
pod
数据流量都从
overlay
设备以隧道的形式发送到对端。
• Flanneld
:
flannel
在每个主机中运行
flanneld
作为
agent
,它会为所在主机从集群的网络地址
空间中,获取一个小的网段
subnet
,本主机内所有容器的
IP
地址都将从中分配。同时
Flanneld
监听
K8s
集群数据库,为
flannel.1
设备提供封装数据时必要的
mac
、
ip
等网络数据信
息。
flannel网络原理
•
当容器发送
IP
包,通过
veth pair
发往
cni
网桥,再路由到本机的
flannel.1
设备进行处理。
• VTEP
设备之间通过二层数据帧进行通信,源
VTEP
设备收到原始
IP
包后,在上面加
上一个目的
MAC
地址,封装成一个内部数据帧,发送给目的
VTEP
设备。
•
内部数据桢,并不能在宿主机的二层网络传输,
Linux
内核还需要把它进一步封装成
为宿主机的一个普通的数据帧,承载着内部数据帧通过宿主机的
eth0
进行传输。
• Linux
会在内部数据帧前面,加上一个
VXLAN
头,
VXLAN
头里有一个重要的标志叫
VNI
,它是
VTEP
识别某个数据桢是不是应该归自己处理的重要标识。
• flannel.1
设备只知道另一端
flannel.1
设备的
MAC
地址,却不知道对应的宿主机地址是
什么。在
linux
内核里面,网络设备进行转发的依据,来自
FDB
的转发数据库,这个
flannel.1
网桥对应的
FDB
信息,是由
flanneld
进程维护的。
• linux
内核在
IP
包前面再加上二层数据帧头,把目标节点的
MAC
地址填进去,
MAC
地
址从宿主机的
ARP
表获取。
•
此时
flannel.1
设备就可以把这个数据帧从
eth0
发出去,再经过宿主机网络来到目标节
点的
eth0
设备。目标主机内核网络栈会发现这个数据帧有
VXLAN Header
,并且
VNI
为
1
,
Linux
内核会对它进行拆包,拿到内部数据帧,根据
VNI
的值,交给本机 flannel.1设备处理
,flannel.1
拆包,根据路由表发往
cni
网桥,最后到达目标容器。
k8s网络通信
• flannel
支持多种后端:
• Vxlan
• vxlan //报文封装,默认
• Directrouting //直接路由,跨网段使用
vxlan
,同网段使用
host-gw
模式。
• host-gw
: //主机网关,性能好,但只能在二层网络中,不支持跨网络,
如果有成千上万的
Pod
,容易产生广播风暴,不推荐
• UDP
: //性能差,不推荐
•
配置
flannel
:
• # kubectl -n kube-system edit cm kube-flannel-cfg
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan",
"Directrouting": true
}
}