【k8s】8.k8s的网络模型(二):Flannel网络模型
flannel 通过该配置可以将网卡的 IP、MAC 信息存储到 etcd 中,这样,flannel 就知道所有的节点分配的 IP 段及 VTEP 设备的 IP 和 MAC 信息,并且所有节点的 flanneld 都可以感知到节点的添加和删除操作,就可以动态的更新本机的转发配置。上述介绍都是基于 VXLAN 实现的 Flannel 网络,VXLAN 适用于三层可达的网络环境,对集群的网络要求很宽松
目录
(2) 将 k8s flannel 设置为 host-gw 模式
Flannel 网络模型
1. IP地址管理
flannel 的 IP 地址是通过 etcd 管理的,可以查看 k8s flannel 使用的网段:
$ kubectl -n kube-flannel exec kube-flannel-ds-zsfdk -- cat /etc/kube-flannel/net-conf.json
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
10.244.0.0/16 是默认值,也可以在 k8s 初始化时指定 --pod-network-cidr
flannel 基于 10.244.0.0/16 网段为 pod 分配 IP ,以节点为单元划分小网段,每个节点上的 pod 划分一个 10.244.x.0/24 的网段,所以共能分配 255 个节点,每个节点上可以分配 253 个 pod。每个节点上都会有一个 flanneld 用于管理自己网段的租期。
$ cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24 // 分配的网段
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
2. flannel 的 VTEP 设备
查看节点设备:
$ ip a
4: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default
link/ether 62:10:77:75:f2:84 brd ff:ff:ff:ff:ff:ff
inet6 fe80::6010:77ff:fe75:f284/64 scope link
valid_lft forever preferred_lft forever
5: cni0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default qlen 1000
link/ether ae:25:1d:13:ba:9b brd ff:ff:ff:ff:ff:ff
inet6 fe80::ac25:1dff:fe13:ba9b/64 scope link
valid_lft forever preferred_lft forever
- flannel.1 即为 flannel 的 VTEP 设备,其中后缀1 相当于 VXLAN 的序号,即 VNI 标识
- cni0 是节点的网桥(相当于docker的docker0网桥)
$ brctl show
bridge name bridge id STP enabled interfaces
cni0 8000.ae251d13ba9b no veth4f0758af // 有两个pod被插到了cni0网桥上
veth8871bc4e
docker0 8000.024245060309 no
为什么不使用 docker0,而是再创建一个 cni0 ?
为了与 docker 解耦,但是他们的本质是相同的
3. pod 流量的转发过程
(1) 查看节点的路由规则
$ route -n
10.244.0.0 10.244.0.0 255.255.255.0 UG 0 0 0 flannel.1
10.244.1.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
10.244.2.0 10.244.2.0 255.255.255.0 UG 0 0 0 flannel.1
对于当前节点 10.244.1.0 来说:
-
到其他节点 10.244.0.0/10.244.2.0 的流量,由于是跨主机通信,都发到了 flannel.1 上
-
到本机的流量,发给了 cni0 网桥
(2) flannel 的出口网卡
flanneld 服务启动时,会需要配置--iface=eth0,即本节点的出口流量网卡(物理网卡)。
flannel 通过该配置可以将网卡的 IP、MAC 信息存储到 etcd 中,这样,flannel 就知道所有的节点分配的 IP 段及 VTEP 设备的 IP 和 MAC 信息,并且所有节点的 flanneld 都可以感知到节点的添加和删除操作,就可以动态的更新本机的转发配置。
$ kubectl -n kube-flannel describe pod kube-flannel-ds-zsfdk | grep iface -3
Args:
--ip-masq
--kube-subnet-mgr
--iface=ens160
$ ip a
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:6d:b3:e0 brd ff:ff:ff:ff:ff:ff
altname enp2s0
inet 172.16.240.128/24 metric 100 brd 172.16.240.255 scope global dynamic ens160
valid_lft 1425sec preferred_lft 1425sec
inet6 fe80::20c:29ff:fe6d:b3e0/64 scope link
valid_lft forever preferred_lft forever
(3) 流量转发过程
-
k8s-slave1 节点中的 pod-a(10.244.2.19)当中的 IP 包通过 pod-a 内的路由表被发送到eth0,进一步通过veth pair转到宿主机中的网桥 cni0
-
到达 cni0 当中的 IP 包通过匹配节点 k8s-slave1 的路由表发现通往 10.244.2.19 的 IP 包应该交给 flannel.1 接口
-
flannel.1 作为一个 VTEP 设备,收到报文后将按照 VTEP 的配置进行封包,第一次会查询ETCD,知道10.244.2.19的vtep设备是k8s-slave2机器,IP地址是172.21.51.69,拿到MAC 地址进行 VXLAN 封包。
-
通过节点 k8s-slave2 跟 k8s-slave1之间的网络连接,VXLAN 包到达 k8s-slave2 的 eth0 接口
-
通过端口 8472,VXLAN 包被转发给 VTEP 设备 flannel.1 进行解包
-
解封装后的 IP 包匹配节点 k8s-slave2 当中的路由表(10.244.2.0),内核将 IP 包转发给cni0
-
cni0将 IP 包转发给连接在 cni0 上的 pod-b
4. 利用host-gw模式提升集群网络性能
上述介绍都是基于 VXLAN 实现的 Flannel 网络,VXLAN 适用于三层可达的网络环境,对集群的网络要求很宽松,但是同时由于会通过 VTEP 设备进行额外封包和解包,因此给性能带来了额外的开销。
(1) 原理
网络插件的目的其实就是将本机的 cni0 网桥的流量送到目的主机的 cni0 网桥,实际上有很多集群是部署在同一个二层网络环境下的,可以直接利用二层的主机当作流量转发的网关,这样就不用经过封包解包,直接通过路由表去转发流量,效率更高。
为什么三层可达的网络不直接利用网关转发流量?内核中的路由规则限制,网关必须在和主机当中至少一个 IP 处于同一网段。
(2) 将 k8s flannel 设置为 host-gw 模式
$ kubectl edit cm kube-flannel-cfg -n kube-system
...
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "host-gw"
}
}
kind: ConfigMap
...
然后重启 flannel 服务的 pod:
$ kubectl -n kube-system get pod | grep flannel
kube-flannel-ds-amd64-5dgb8 1/1 Running 0 15m
kube-flannel-ds-amd64-c2gdc 1/1 Running 0 14m
kube-flannel-ds-amd64-t2jdd 1/1 Running 0 15m
$ kubectl -n kube-system delete pod xxx
重启完成后,可以再查看节点路由表:
$ route -n
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.136.2 0.0.0.0 UG 100 0 0 eth0
10.244.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
10.244.1.0 172.21.51.68 255.255.255.0 UG 0 0 0 eth0
10.244.2.0 172.21.51.69 255.255.255.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.136.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
可以看到,已经没有了 flannel.1 设备。
对当前节点 10.244.0.0 来说:
-
请求 10.244.1.0/10.244.2.0,由于跨主机通信,走的是 eth0 网卡,直接将流量打到了出口物理网卡上(相当于上图的ens33)
-
请求本机依然走的 cni0 网桥
更多推荐
所有评论(0)