在网络虚拟化中,有两项技术的发展相当重要,甚至可以说是网络功能软件化、虚拟化的重要重要基础。
在linux中,对于创建的一些虚拟网卡之间实现通信,提供了linux bridge作为虚拟网桥,进行数据交换。
linux系统中,提供很多namespace用于实现内核资源相互隔离,相互隔离的资源之间互不影响,在现有资源下提供轻量级的虚拟化的服务。
本文将通过network namespace跟linux bridge介绍最为基础的网络虚拟化的基础应用。
在同一台linux host上构造如下,创建两个vif放入不同的network namespace进行网络隔离,通过将vif连接到linux bridge上实现通信。
[root@localhost baojx]# ifconfig -a
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1 (Local Loopback)
RX packets 64 bytes 5408 (5.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 64 bytes 5408 (5.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
// 创建网桥br
[root@localhost baojx]# brctl addbr br
[root@localhost baojx]# brctl show
bridge name bridge id STP enabled interfaces
br 8000.000000000000 no
// 生成bridge管理口br
[root@localhost baojx]# ifconfig -a
br: flags=4098 mtu 1500
ether 12:3f:c2:3c:08:83 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1 (Local Loopback)
RX packets 64 bytes 5408 (5.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 64 bytes 5408 (5.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
// 使能bridge管理口br,配置IP
[root@localhost baojx]# ip link set dev br up
[root@localhost baojx]# ip address add 192.168.0.254/24 dev br
[root@localhost baojx]# ifconfig br
br: flags=4163 mtu 1500
inet 192.168.0.254 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::9441:51ff:feff:524b prefixlen 64 scopeid 0x20
ether 96:41:51:ff:52:4b txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21 bytes 3535 (3.4 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
// 创建虚拟接口并attach到linux bridge端口
[root@localhost baojx]# ip link add veth0 type veth peer name br-vif-0
[root@localhost baojx]# ip link add veth1 type veth peer name br-vif-1
[root@localhost baojx]# ip address add 192.168.0.1/24 dev veth0
[root@localhost baojx]# ip link set veth0 up
[root@localhost baojx]# ip link set veth1 up
[root@localhost baojx]# ip link set br-vif-0 up
[root@localhost baojx]# ip link set br-vif-1 up
[root@localhost baojx]# ifconfig
br: flags=4163 mtu 1500
inet 192.168.0.254 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::9441:51ff:feff:524b prefixlen 64 scopeid 0x20
ether 96:41:51:ff:52:4b txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1505 bytes 398024 (388.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
br-vif-0: flags=4163 mtu 1500
inet6 fe80::8c4b:1fff:fec9:e8ae prefixlen 64 scopeid 0x20
ether 8e:4b:1f:c9:e8:ae txqueuelen 1000 (Ethernet)
RX packets 85 bytes 19249 (18.7 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
br-vif-1: flags=4163 mtu 1500
inet6 fe80::7821:8fff:fe7f:40d6 prefixlen 64 scopeid 0x20
ether 7a:21:8f:7f:40:d6 txqueuelen 1000 (Ethernet)
RX packets 87 bytes 19322 (18.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73 mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10
loop txqueuelen 1 (Local Loopback)
RX packets 64 bytes 5408 (5.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 64 bytes 5408 (5.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth0: flags=4163 mtu 1500
inet 192.168.0.1 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::fc45:2ff:fe76:50fb prefixlen 64 scopeid 0x20
ether fe:45:02:76:50:fb txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 85 bytes 19249 (18.7 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
veth1: flags=4163 mtu 1500
inet 192.168.0.2 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::bcc5:18ff:fe20:f886 prefixlen 64 scopeid 0x20
ether be:c5:18:20:f8:86 txqueuelen 1000 (Ethernet)
RX packets 8 bytes 648 (648.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 87 bytes 19322 (18.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
// 将虚拟bridge port添加到linux bridge,并开启端口混杂模式,接受所有数据包
[root@localhost baojx]# brctl addif br br-vif-0
[root@localhost baojx]# brctl addif br br-vif-1
[root@localhost baojx]# ip link set br-vif-0 promisc on
[root@localhost baojx]# ip link set br-vif-1 promisc on
[root@localhost baojx]# ifconfig br-vif-o
br-vif-o: error fetching interface information: Device not found
[root@localhost baojx]# ifconfig br-vif-0
br-vif-0: flags=4419 mtu 1500
inet6 fe80::8c4b:1fff:fec9:e8ae prefixlen 64 scopeid 0x20
ether 8e:4b:1f:c9:e8:ae txqueuelen 1000 (Ethernet)
RX packets 305 bytes 76400 (74.6 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 194 bytes 49524 (48.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@localhost baojx]# ifconfig br-vif-1
br-vif-1: flags=4419 mtu 1500
inet6 fe80::7821:8fff:fe7f:40d6 prefixlen 64 scopeid 0x20
ether 7a:21:8f:7f:40:d6 txqueuelen 1000 (Ethernet)
RX packets 310 bytes 76872 (75.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 196 bytes 50044 (48.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
// 创建network namespace ns
[root@localhost baojx]# ip netns add ns
[root@localhost baojx]# ip netns
ns
// 将veth1按入network namespace ns,进入namespace配置IP
[root@localhost baojx]# ip link set veth1 netns ns
[root@localhost baojx]# ip netns exec ns bash
[root@localhost baojx]# ip link set veth1 up
[root@localhost baojx]# ip address add 192.168.0.2/24 dev veth1
[root@localhost baojx]# ifconfig
veth1: flags=4163 mtu 1500
inet 192.168.0.2 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::bcc5:18ff:fe20:f886 prefixlen 64 scopeid 0x20
ether be:c5:18:20:f8:86 txqueuelen 1000 (Ethernet)
RX packets 708 bytes 183522 (179.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 568 bytes 142153 (138.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
// 检查对另外一个namespace的网络联通性
[root@localhost baojx]# ping 192.168.0.1 -c 1
PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
64 bytes from 192.168.0.1: icmp_seq=1 ttl=64 time=0.048 ms
--- 192.168.0.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.048/0.048/0.048/0.000 ms
至此,最为简单的模拟完成,本身组织实现并不复杂,只是一些管理工具cli比较难用。小记作为对之前摸索学习过程的小结。当然实际操作中还有其他比较有意思的小细节、小现象,在此就不一一赘述了。