使用 Veth Pair 虚拟网卡对不同的网络空间进行通信
使用 Veth Pair 虚拟网卡对不同的网络空间进行通信
解决问题:
由于资源隔离带来的名称空间的网络隔离,解决不同的网络隔离的通信,隔离的目的是为了资源部署,我们诉求是要达到互联互通,不能只隔离,不通信,所以需要使用虚拟网卡对的方式来实现网络的互联互通。
brctl 命令
# 安装命令~# apt install bridge-utils ethtools -y# 查看当前服务器 bridge 类型的网卡~# brctl showbridge name bridge id STP enabled interfacesdocker0 8000.0242910296ce no # 查看当前网卡下的 mac 地址~# brctl showmacs docker0 port no mac addr is local?(是否是本地的mac地址,no表示为非本地的地址) ageing timer 1 12:88:4c:d1:3b:24 yes 0.00 1 12:88:4c:d1:3b:24 yes 0.00
模拟 Linux bridge
我们通过本地创建一个网桥,然后连接不同的网络空间,来达到模拟同一个 node 节点的 pod 通过网桥通信的目的。网桥的本质其实就是一个模拟二层的交换机,通过 MAC 地址来进行数据链路层的通信。
1.创建 br0 网桥
# 添加 br0 bridge 网桥~# ip link add br0 type bridge# 启动网桥~# ip link set br0 up# 查看 bridge~# brctl show bridge name bridge id STP enabled interfacesbr0 8000.000000000000 no docker0 8000.0242910296ce no veth3ea8f48
2.创建名称空间 ns1 和 ns2
~# ip netns add ns1~# ip netns add ns2
3.创建 veth 对
~# ip link add veth0 type veth peer br-veth0~# ip link add veth1 type veth peer br-veth1# 查看创建的 veth 对,通过查看此时 veth对 在 root名称空间下~# ip address show······6: br0: mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 link/ether ae:60:62:d9:67:aa brd ff:ff:ff:ff:ff:ff inet6 fe80::ac60:62ff:fed9:67aa/64 scope link valid_lft forever preferred_lft forever7: br-veth0@if8: mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 5e:6b:c5:04:47:52 brd ff:ff:ff:ff:ff:ff link-netns ns19: br-veth1@if10: mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 16:b4:3a:d1:88:e6 brd ff:ff:ff:ff:ff:ff link-netns ns2
4.将创建的 veth对 的一端插入到指定的名称空间
~# ip link set veth0 netns ns1~# ip link set veth1 netns ns2# 通过进入不同的名称空间查看网卡的一端~# ip netns exec ns1 ip a1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:008: veth0@if7: mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 7e:c7:8f:64:79:e0 brd ff:ff:ff:ff:ff:ff link-netnsid 0~# ip netns exec ns2 ip a1: lo: mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:0010: veth1@if9: mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 36:19:69:64:ab:8c brd ff:ff:ff:ff:ff:ff link-netnsid 0
5.将创建的 veth对 的另一端插入到 br0 的桥接网卡
~# ip link set br-veth0 master br0~# ip link set br-veth1 master br0# 查看网卡对 和 绑定情况~# brctl show br0bridge name bridge id STP enabled interfacesbr0 8000.16b43ad188e6 no br-veth0 br-veth1
6.启动网卡 veth0 veth1 br-veth0 br-veth1,并配置 ip 地址
~# ip link set br-veth0 up~# ip link set br-veth1 up~# ip netns exec ns1 ip link set veth0 up~# ip netns exec ns2 ip link set veth1 up~# ip netns exec ns1 ifconfig veth0 192.168.100.10/24~# ip netns exec ns2 ifconfig veth1 192.168.100.20/24~# ip netns exec ns1 ifconfig lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0veth0: flags=4099 mtu 1500 inet 192.168.100.10 netmask 255.255.255.0 broadcast 192.168.100.255 ether 7e:c7:8f:64:79:e0 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0# ip netns exec ns2 ifconfig lo: flags=73 mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0veth1: flags=4099 mtu 1500 inet 192.168.100.20 netmask 255.255.255.0 broadcast 192.168.100.255 ether 36:19:69:64:ab:8c txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0# 注意:也需要启动网卡 lo,否则 ping 本身的 IP地址不通,没有环回接口,ping 自己是走的 lo网卡~# ip netns exec ns1 ip link set lo up~# ip netns exec ns2 ip link set lo up# 效果展示,我们发现 ping 自己可以通,但是 ping 另一个名称空间的 IP地址不通,通过抓包查看root@tf:# ip netns exec ns2 ping 192.168.100.20PING 192.168.100.20 (192.168.100.20) 56(84) bytes of data.64 bytes from 192.168.100.20: icmp_seq=1 ttl=64 time=0.029 ms64 bytes from 192.168.100.20: icmp_seq=2 ttl=64 time=0.066 ms^C--- 192.168.100.20 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1014msrtt min/avg/max/mdev = 0.029/0.047/0.066/0.018 msroot@tf:# ip netns exec ns2 ping 192.168.100.10PING 192.168.100.10 (192.168.100.10) 56(84) bytes of data.From 192.168.100.20 icmp_seq=1 Destination Host UnreachableFrom 192.168.100.20 icmp_seq=2 Destination Host UnreachableFrom 192.168.100.20 icmp_seq=3 Destination Host Unreachable^C--- 192.168.100.10 ping statistics ---4 packets transmitted, 0 received, +3 errors, 100% packet loss, time 3073mspipe 4
7.抓包
# 对 br-veth0 抓包,我们发现地址可达,已经通过 arp 广播正确学习了 MAC 地址tcpdump -pne -i br-veth0
# 对 ns1 名称空间下的 veth0 进行抓包,看看是否有返回的报文# 我们发现并没有返回的报文,那么都能正确解析了,却没有返回的报文ip netns exec ns1 tcpdump -pne -i veth0
# 对 ns2 名称空间下的 veth1 进行抓包,可以正常返回 ARP 报文ip netns exec ns2 tcpdump -pne -i veth1
通过上边抓包可以判断,我们的配置是没有的问题的,问题应该出在 netfilter这个 hook 上,也就是 iptables 的 FORWARD 链
8. iptables FORWARD链开启
这个问题其实是 docker 修改了我们默认的 FORWARD 链的策略,可以查看官方文档的解释
docker-on-a-router
# 查看 FORWARD 链是否是 DROP 状态~# iptables-save | grep DROP:FORWARD DROP [29:2436]# 对 br0 网桥开启 FORWARD 转发~# iptables -A FORWARD -i br0 -j ACCEPT# 再次进行连通性测试,可以正常转发~# ip netns exec ns1 ping 192.168.100.20PING 192.168.100.20 (192.168.100.20) 56(84) bytes of data.64 bytes from 192.168.100.20: icmp_seq=1 ttl=64 time=0.075 ms64 bytes from 192.168.100.20: icmp_seq=2 ttl=64 time=0.065 ms64 bytes from 192.168.100.20: icmp_seq=3 ttl=64 time=0.150 ms64 bytes from 192.168.100.20: icmp_seq=4 ttl=64 time=0.137 ms
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
暂时没有评论,来抢沙发吧~