网络虚拟化技术(一): Linux网络虚拟化

时间:2023-12-11 09:10:44

创建虚拟网络环境

使用命令

$ ip netns add net0

可以创建一个完全隔离的新网络环境,这个环境包括一个独立的网卡空间,路由表,ARP表,ip地址表,iptables,ebtables,等等。总之,与网络有关的组件都是独立的。

ip命令需要root权限的,但是由于本文大量使用ip命令,于是笔者给ip命令添加了capability,使普通用户也能使用ip命令

使用命令

$ ip netns list
net0

可以看到我们刚才创建的网络环境

进入虚拟网络环境

使用命令

$ ip netns exec net0 `command`

我们可以在 net0 虚拟环境中运行任何命令

$ ip netns exec net0 bash
$ ip ad
: lo: <LOOPBACK> mtu qdisc noop state DOWN
link/loopback ::::: brd :::::

这样我们可以在新的网络环境中打开一个shell,可以看到,新的网络环境里面只有一个lo设备,并且这个lo设备与外面的lo设备是不同的,之间不能互相通讯。

连接两个网络环境

新的网络环境里面没有任何网络设备,并且也无法和外部通讯,就是一个孤岛,通过下面介绍的这个方法可以把两个网络环境连起来,简单的说,就是在两个网络环境之间拉一根网线

$ ip netns add net1

先创建另一个网络环境net1,我们的目标是把net0与net1连起来

$ ip link add type veth
$ ip ad
: lo: <LOOPBACK> mtu qdisc noop state DOWN
link/loopback ::::: brd :::::
: veth0: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN qlen
link/ether ::::3a:dd brd ff:ff:ff:ff:ff:ff
: veth1: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN qlen
link/ether :4f:fd:cc::1b brd ff:ff:ff:ff:ff:ff

这里创建连一对veth虚拟网卡,类似pipe,发给veth0的数据包veth1那边会收到,发给veth1的数据包veth0会收到。就相当于给机器安装了两个网卡,并且之间用网线连接起来了

$ ip link set veth0 netns net0
$ ip link set veth1 netns net1

这两条命令的意思就是把veth0移动到net0环境里面,把veth1移动到net1环境里面,我们看看结果

$ ip ad
: lo: <LOOPBACK> mtu qdisc noop state DOWN
link/loopback ::::: brd :::::
$ ip netns exec net0 ip ad
: lo: <LOOPBACK> mtu qdisc noop state DOWN
link/loopback ::::: brd :::::
: veth0: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN qlen
link/ether ::::3a:dd brd ff:ff:ff:ff:ff:ff
$ ip netns exec net1 ip ad
: lo: <LOOPBACK> mtu qdisc noop state DOWN
link/loopback ::::: brd :::::
: veth1: <BROADCAST,MULTICAST> mtu qdisc noop state DOWN qlen
link/ether :4f:fd:cc::1b brd ff:ff:ff:ff:ff:ff

veth0 veth1已经在我们的环境里面消失了,并且分别出现在net0与net1里面。下面我们简单测试一下net0与net1的联通性

$ ip netns exec net0 ip link set veth0 up
$ ip netns exec net0 ip address add 10.0.1.1/ dev veth0
$ ip netns exec net1 ip link set veth1 up
$ ip netns exec net1 ip address add 10.0.1.2/ dev veth1

分别配置好两个设备,然后用ping测试一下联通性:

$ ip netns exec net0 ping -c  10.0.1.2
PING 10.0.1.2 (10.0.1.2) () bytes of data.
bytes from 10.0.1.2: icmp_req= ttl= time=0.101 ms
bytes from 10.0.1.2: icmp_req= ttl= time=0.057 ms
bytes from 10.0.1.2: icmp_req= ttl= time=0.048 ms --- 10.0.1.2 ping statistics ---
packets transmitted, received, % packet loss, time 1999ms
rtt min/avg/max/mdev = 0.048/0.068/0.101/0.025 ms

一个稍微复杂的网络环境

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAV4AAAC2CAIAAAAeKXIWAAAOGElEQVR42u2dX0xT5xuA+VOrM6VZZISm8QLmcISYuFiaRV1UEky8AOOWXZnptRczcxcmXkAgIXGJmRdeGJJ5UUUXZnSSLTgcWzQCQwKmphXMqJVQOogUbLColAH6e+X87DpqSwuOfrbPc9XvnPN9PXnf93t6vtPCyXgBABBBBiEAANQAAAmq4TkApD2oAQBQAwCgBgBADQCAGgAANQAAagAA1AAAqAEAUAMAoAYAQA0AgBoAADWgBgBADQCAGgAANQAAagAA1AAAqAEAUAMAoAYAQA0AgBoAADUAQPKZm5tDDQD/0NvbW1NTU1JSkjFP5AEul2vv3r0GgyEnJ0deuN3u2AMmdPyi776E8Q8ePFhUVCQv7Hb74cOH5bVer8/Pzy8rK2tubo4ccGZmZvfu3UePHo3/HFADpD4yLWVy3r1797UTY2xszGw2W61W7zwWi2X9+vWPHj2KNlqix8d+9yWMPzs7m5eXd+TIEXkth50+fbq/vz8YDIpQZP7LW9TX1y8YU6RQXl4ugkANAK/htROjurpaNv70009a88qVK9KUyRxtkESPj/3uSxj/1q1bsqW1tTWyr8fjkV0FBQXhG3/44YfCwkIxTvzngBoANTzfsmWLbJTP5/DZVVpaGm2QRI9PVA2Lji/ukLWGXCZE9vX5fHKwLC5CWxwOh1xiyLojoXNADYAanst6XjaGZtqzZ8+kaTQaow2S6PGJqmHR8cUdn3766Wv7ancTNm3apDVlGbJhw4YLFy4keg6oAVDD86ysLNkYunsvK3lpZmdnRxsk0eMTnZaxxx8eHs7MzDxz5kxkx5MnT2pv0djYqG3Zs2fP119/vYRzQA0rTXFxcQa8QqKhzlXD1NRUQlcN8R+/tKuGaOOLFEQNIogFvU6cOCGHya5Tp06FNpaVlc3MzKCGt+NT6wWEKikjIxAIPHnyRKbB9PS0fDwm8V7D0NCQ1hwcHIznXkP8xy/tXkO08WUpIQcs6HL8+HE5Ri43FlxNxFYzakAN6qrB6/WOjo76/X4RhNghKWqoqqoK/0bgxx9/DP9GILJLosfHfveExg8GgwaDobq6Ovz4uro6zQs2m+1N6Qk1oIYkq6Gvr+/BgwdyeSx2kCvnpKjB5/OZTCar1frXPBaLxWw2j4+PR+uS6PGJqiHG+K2trXLwrVu3QgfX1tZqdyIaGhqWHAHUgBqUU0NnZ6fD4RA7PHz4cHJy8r+WQrTL6f7+/oqKCsM8lZWVLpcr9lxK9PgY757Q+EeOHMnLywtfeSW6WEANqOHtUENLS4vYobe3V5bWExMTVEhsioqKDh48qNpZoQbU8ObVcPHiRblI7unpcbvdMX5rDCqDGlDDm1dDY2PjtWvXuru779+/jxpQA2pY+lxKdITYXZYwIGoA1IAaUAOghhRVwwoPiBpQA2pImhrOnTtXUlKi1+s3bNhw/vz5BXuDweBXX32Vl5eXlZUVOfkbGhqk16pVq2QEGWfB3gsXLsTY297eXl5enpOTYzQat23bdvXqVdQAqEEhNWzdunVwcHBoaGj79u3SvH79evjeb7/99s6dO7Ozs5HXBb/99pu8ll6eebTuob0yTmhw4eOPPw7fe+PGDZ1Ot2PHDrfb7ff7Dxw4oEkKNQBqUEUNf/zxh9aUF9IsKysL33v79u1oS4Zdu3ZpvzIK7x7aK+PI646ODq3Z1tYWvlekIK+dTqfWHB0dlebGjRtRA6AGVdQwOTmpNQOBgDRzc3PD9/7999/R1LBu3brI7nHuXbt2beRP7rKzs1EDoAZF1SBTOsY9xTerBp/Px21IQA1v5YIihhp27ty56IKiq6vrtQsKbTFy6dIl1ACoQVE1aPcRQ7chf//99zjV8Ouvvy56G1L0ISNH3obs6OjQ6/WFhYXijunpael+9uxZGQE1AGpQRQ0yJzdv3vzOO+/IRA3/jmBRNQg2m+3999+XvjKCjPPaLy+1vd99992Cuwk9PT379u3Lzc3V6XRms3n//v03b95EDYAakq+GlUR7bsKHH37IT54ANaS7Gj777LPbt28Hg8E///xTu7mwzF8uoAbUAKmghsuXL1ssllWrVhmNRlFDU1MTP5QG1IAa+BsKQA2oATUAakANqAFQA2pADYAaUANqANSAGlADoIbUxGQy8ajLEEajETWgBvg/ExMTHo/H6XS2t7c3Nzd/Hzcyl75Xj2WelURA4iDRkJjwHArUkNYEAoGRkRGXy2W329va2n6JG5mEv6jHMs9KIiBxkGhITCQylAdqSF+ePn06Pj7u9XplPjgcjq640f5iWjWWeVYSAYmDRENiIpGhPFBD+hIMBuXjUWaCfE4ODg72x41Mwn71WOZZSQQkDhINiYlEhvJADenLzMyMzAH5hHz8+LHf7x+LG5mEY+qxzLOSCEgcJBoSE4kM5YEa0p25V8zGjUzCWfVY5lmF4kBJoAZYIm/82ecpfFaAGlADZwWoATVwVoAaADUAagDUAKgBUAOgBkANgBoANQBqQA1MQtQAqIFJiBoANaAG1ACoATWgBkANqAE1AGpADagBUENKEwgEDAYDagDUAP9iYGCgoKAANQBqgH9ht9s3bdqk4InJtYzf7ydBqAE1JAebzfb5558reGKlpaXXr18nQagBNSSHioqKM2fOKHhiVVVVX375JQlCDaghCcjH8nvvvafmdbvL5Xr33XedTidpQg2oYeUIBAL19fUy95qampQ9STlDk8nU2Nj47NkzUoYa0l0N8jn5xRdffPDBBzJv/7unQq5Zs2bPnj2dnZ2KR6OlpeWTTz7R6XT/XSgkzsXFxYcOHRoYGGA2ogZFkc9wqdRvvvnm3r173J9fGSTOouNjx45J5Nva2ggIalCOkZERWflzWz5ZyMqloKCAxQtqUI66ujpZSlAQSUQWL+fPnycOqEG5upSlNQWRROrr67EzalAOWev6fD4KIol0d3d/9NFHxAE1qAV/NZB0lP2LEtSAGiCZ+P1+uXYjDqjhbVVDb29vTU1NSUmJ9s08NZSULNjt9sOHDxcVFen1+vz8/LKysubmZgKIGpJZlCIFUcPdu3dRQxKzYLVaT58+3d/fHwwGXS7X7t27pW99fT0xRA3JX1CgBnWWdR6PR/pyqwI1oAay8C98Pp/0lcUFMUQNqIEs/MPRo0elr5r/Fwc1oAZIjhpOnjyp5aKxsZEYogbUQBZecuLECemVmZl56tQpAogaUANZeMnx48elS1ZWlpr/LAs1pHJRxpj/qCG5Wairq9O8YLPZCB1qQA1k4SW1tbWyJTs7u6GhgbihBlXUEPnfiqikFc5CtH8bRQxRQ/LvNQBZQA0UJZAF1EBRAllADaiBoiQLgBooSrIAqIGiJAuAGihKsgCogaIkC4AaKEqyAOmghuLi4gx4hURDwbIgR+rnKAXVILF+AaG4Z2QEAoEnT55MTU1NT0/Pzs4q8ulNahTPEWpI/bLzer2jo6N+v1+KTyoPNZAj1AAvy66vr+/BgwfDw8NSeYo8D5YcqZ8j1JD6ZdfZ2elwOKTyHj58ODk5iRrIEWqAl2XX0tIildfb2zs0NDQxMYEayBFqgJdld/HixdbW1p6eHrfb/ejRI9RAjlADvND+D/K1a9e6u7vv37+PGsgRalAr95FnJUWwd+9eg8GQk5MjL2SdiRqUylFfX19tbW3o4aOoATWsRNmNj4+bzWar1frXPBaLZf369X6/HzWokyPt4aOy/kcNqGHlyq66ulq2/Pzzz1qzqalJmvIZhRqUurJbdBdqSHc1aMVx+fLlrVu3rlmzZt26dZWVlQMDA6ED2tvby8vLZWlgNBq3bdt29erVBX1DaBu3bNkir+V6QWsODQ1Js7S0FDWokyPUgBriLbvNmzffuXMnEAhoTyjYuXOntvfGjRs6nW7Hjh1ut1sWBQcOHJC9586di1FbUqCyZXp6WmtOTU1JU0oWNaiTI9SAGuItu66uLq05OTkpzdWrV2tNKThpOp1OrTk6OirNjRs3xqitrKws7a8Atebc3Jz21APUoE6OUANqiLfsQh/yz189p0Brrl27NvLP6cLnebSrhmAwyFWDsjlCDahhKfeoIsvO5/PF31271+D1erWmx+PhXoNqOUINqGG5Zbdr1y55fenSpWjdMzMzF3SvqqoK/4biypUr0qypqUEN6uQINaCG5ZZdR0eHXq8vLCyUha5c0MolwNmzZ7dv3x462Gw2y8H37t0LbRkbGzOZTFardXgei8Uix0hNoAZ1coQaUMNyy07o6enZt29fbm6uTqeTItu/f//NmzdDe202W35+/oIuLperoqLCME9lZaXURPqU3duSo8jbE6gBNaQI/OSJHKEGyg41kCPUQNmhBnKEGig71ECOUANlhxrIEWqg7FADOUINqIGyI0eoATVQduQINaAGyo4coQbF1WAymXiMYgij0ahg2ZEj9XOUgmoQJiYmPB6P0+lsb29vbm7+Pr2RCEgcJBoSE3WecUCO1M9RCqohEAiMjIy4XC673d7W1vZLeiMRkDhINCQmEhlFKoMcqZ+jFFTD06dPx8fHvV6vxNrhcHSlNxIBiYNEQ2IikVGkMsiR+jlKQTUEg0FRr0RZHDw4ONif3kgEJA4SDYmJREaRyiBH6ucoBdUwMzMj8RX7Pn782O/3j6U3EgGJg0RDYiKRUaQyyJH6OUpBNWjMvWI2vQnFQcH6IEfq5ygF1QAAqAEAUAMAoAYAQA0AgBoAADWgBgBADQCAGgAANQAAagAA1AAAqAEAUAMAoAYAQA0AgBoAADUAAGoAANQAAKgBNQAAagAA1AAAqAEAUAMArLQaAABQAwCgBgBIkP8B9sj66+D5RSsAAAAASUVORK5CYII=" alt="2013-02-29-linux-network-emulator__1.png" />

创建虚拟网络环境并且连接网线

ip netns add net0
ip netns add net1
ip netns add bridge
ip link add type veth
ip link set dev veth0 name net0-bridge netns net0
ip link set dev veth1 name bridge-net netns bridge
ip link add type veth
ip link set dev veth0 name net1-bridge netns net1
ip link set dev veth1 name bridge-net netns bridge

在bridge中创建并且设置br设备

ip netns exec bridge brctl addbr br
ip netns exec bridge ip link set dev br up
ip netns exec bridge ip link set dev bridge-net up
ip netns exec bridge ip link set dev bridge-net up
ip netns exec bridge brctl addif br bridge-net
ip netns exec bridge brctl addif br bridge-net

然后配置两个虚拟环境的网卡

ip netns exec net0 ip link set dev net0-bridge up
ip netns exec net0 ip address add 10.0.1.1/ dev net0-bridge
ip netns exec net1 ip link set dev net1-bridge up
ip netns exec net1 ip address add 10.0.1.2/ dev net1-bridge

测试

$ ip netns exec net0 ping -c  10.0.1.2
PING 10.0.1.2 (10.0.1.2) () bytes of data.
bytes from 10.0.1.2: icmp_req= ttl= time=0.121 ms
bytes from 10.0.1.2: icmp_req= ttl= time=0.072 ms
bytes from 10.0.1.2: icmp_req= ttl= time=0.069 ms --- 10.0.1.2 ping statistics ---
packets transmitted, received, % packet loss, time 1999ms
rtt min/avg/max/mdev = 0.069/0.087/0.121/0.025 ms

配置lldpd检查线路链接情况

随着虚拟网络环境增加,环境中网卡数量也在不断增加,经常会忘记环境中哪些网卡连接到哪里,通过 lldp 
Link Layer Discovery Protocol ]
协议,我们可以清楚看到每个网卡连接到了哪些环境中的哪个网卡。

github 上有一个 lldp 在 linux 下的开源实现 
implementation of IEEE 802.1ab (LLDP) ]
,通过在每个环境中起一个 lldp daemon,我们就可以实时查看每个网卡的连接情况

Bridge 上 lldp 的数据

$ lldpcli show neighbors

LLDP neighbors:

Interface:    bridge-net0, via: LLDP, RID: 2, Time: 0 day, 00:06:53
Chassis:
ChassisID: mac 82:be:2a:ec:70:69
SysName: localhost
SysDescr: net0
Capability: Bridge, off
Capability: Router, off
Capability: Wlan, off
Port:
PortID: mac 82:be:2a:ec:70:69
PortDescr: net0-bridge Interface: bridge-net1, via: LLDP, RID: 1, Time: 0 day, 00:06:53
Chassis:
ChassisID: mac b2:34:28:b1:be:49
SysName: localhost
SysDescr: net1
Capability: Bridge, off
Capability: Router, off
Capability: Wlan, off
Port:
PortID: mac b2:34:28:b1:be:49
PortDescr: net1-bridge