Flannel 分析之 veth pair
下方是我理解的Flannel vxlan网络模型,在每个Pod中有一个Pause容器提供公用网络命名空间,在根(ROOT)命名空间下,命名空间网络是互通的,这里通过了veth pair实现了命名空间互通

veth pair 介绍
veth pair是指虚拟设备对,veth pair中的两个设备分别位于网络命名空间的两侧,可以通过虚拟链路进行两个命名空间通信。
手动实验两个命名空间通信
首先创建两个命名空间
ip netns add ns1
ip netns add ns2
创建一对虚拟设备对
ip link add veth-ns1 type veth peer name veth-ns2
把这一对虚拟设备对分别绑定命名空间
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
分别给两个命名空间下的虚拟设备创建IP
ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns1
ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth-ns2
分别启动两个命名空间下的虚拟设备
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up
在ns1命名空间下ping ns2的IP
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.109 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.054 ms
手动实验绑定网桥
刚刚的实现证明了veth pair可以使两个命名空间互通,这里一对虚拟设备只能绑定一对命名空间,如果使多个命名空间互通就需要通过网桥来实现
首先创建网桥
brctl addbr br0
创建三个命名空间
ip netns add ns1
ip netns add ns2
ip netns add ns3
创建三对虚拟设备对,实现一端绑定命名空间,另一端绑定网桥
ip link add veth-ns1 type veth peer name br0-ns1
ip link add veth-ns2 type veth peer name br0-ns2
ip link add veth-ns3 type veth peer name br0-ns3
分别把虚拟设备对的一端绑定命名空间并设置IP
ip link set veth-ns1 netns ns1
ip link set veth-ns2 netns ns2
ip link set veth-ns3 netns ns3
ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns1
ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth-ns2
ip netns exec ns3 ip addr add 192.168.1.3/24 dev veth-ns3
分别把虚拟设备对的另一端绑定网桥
brctl addif br0 br0-ns1
brctl addif br0 br0-ns2
brctl addif br0 br0-ns3
全部启动各个设备
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns2 ip link set veth-ns2 up
ip netns exec ns3 ip link set veth-ns3 up
ip link set br0-ns1 up
ip link set br0-ns2 up
ip link set br0-ns3 up
ip link set br0 up
在ns1命名空间下ping ns2与ns3的IP
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.109 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.054 ms
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.3
PING 192.168.1.2 (192.168.1.3) 56(84) bytes of data.
64 bytes from 192.168.1.3: icmp_seq=1 ttl=64 time=0.109 ms
64 bytes from 192.168.1.3: icmp_seq=2 ttl=64 time=0.054 ms
FAQ
在实验过程中发现ping回环地址不通,经过测试发现创建ns后,自动有一个lo设备,所以想要访问自己需要up回环地址
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
[root@kube01 ~]# ip netns exec ns1 ip link set lo up
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.057 ms
在实验过程中发现绑定网桥后,ns1无法ping通别的命名空间,经过抓包发现ns1有包到了网桥,但是别的命名空间却无法接收到请求,分析发现网桥的转发功能由iptables控制,开启iptables对网桥的转发功能,发现可以正常访问
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.2
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.


[root@kube01 ~]# iptables -A FORWARD -o br0 -j ACCEPT
[root@kube01 ~]# ip netns exec ns1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.056 ms