多个到KVM访客的不同VLAN中继(Linux)

我遇到了一个build筑挑战的障碍。 我有一台运行着KVM的服务器 – 它将包含许多客户端,一些运行虚拟防火墙和其他服务器,只是普通的Web服务器。

  • Web服务器需要单个未标记的VLAN接口
  • 防火墙需要一个标记的VLAN中继

现在通常情况下,这将很简单,只需添加一个eth0桥接器,在桥上添加几个VLAN( vmbr0.1等),然后为每个guest vmbr0.1 (或其倍数)分配带有untagged VLAN的接口。

  firewall1 (vlan 1,2,3,4) switch ===== eth0 vmbr0 firewall2 (vlan 1,2,5,6) (eth0) server1 (vlan 7) server2 (vlan 8) vlan trunk (1,2,3,4,5,6,7,8) 

现在,如果你只有几个接口需要传入一个客户端,这个工作正常。 但是当您需要将500个VLAN放入防火墙时会发生什么情况。 它不切实际。

所以我想不出的是如何创build一个数字中继(使用普通的VLAN和不同的VLAN),并将它们分配给一个guest虚拟机。

到目前为止,我发现的最接近的解决scheme是在主桥上创buildVLAN,然后为这些服务器分配一个VLAN。

然后,为防火墙创build一个桥接器,只需要客户端的tap接口,然后为该桥创builduntagged vlan接口,并将其添加到主vmbr0桥。

唯一的问题是没有标记的接口的stream量当然是没有标记的。

是否有可能标记stream量退出界面?

否则,如何才能实现不同的中继到KVM客人,可能有普通的VLAN和不同的VLAN(但不是所有的VLAN) – 并能够分配单个未标记的VLAN接口

一个漫长的解决scheme…

所以我一直在玩弄不同的概念,我想我已经做出了一个可行的解决scheme。 基本上有一个eth0所属的主干线( bt )。 那么对于每个防火墙虚拟机都有自己的桥梁。

 bridge name bridge id STP enabled interfaces bt 8000.002618895a72 no eth0 bt-fw1 8000.000000000000 no tap100i0 bt-fw2 8000.000000000000 no tap101i0 

此时,来自防火墙VM的标记stream量将进入其自己的桥接以供stream量进入。

然后,我为每个需要标记stream量的接口创buildVLAN,并为未标记的stream量创build主桥上的相应VLAN。

例如。 VLAN 1,4000-4005

 bt-fw1.1 | 1 | bt-fw1 bt-fw1.4000 | 4000 | bt-fw1 bt-fw1.4001 | 4001 | bt-fw1 bt-fw1.4002 | 4002 | bt-fw1 bt-fw1.4003 | 4003 | bt-fw1 bt-fw1.4004 | 4004 | bt-fw1 bt-fw1.4005 | 4005 | bt-fw1 bt-fw2.1 | 1 | bt-fw2 bt-fw2.4000 | 4000 | bt-fw2 bt-fw2.4001 | 4001 | bt-fw2 bt-fw2.4002 | 4002 | bt-fw2 bt-fw2.4003 | 4003 | bt-fw2 bt-fw2.4004 | 4004 | bt-fw2 bt-fw2.4005 | 4005 | bt-fw2 bt.1 | 1 | bt bt.4000 | 4000 | bt bt.4001 | 4001 | bt bt.4002 | 4002 | bt bt.4003 | 4003 | bt bt.4004 | 4004 | bt bt.4005 | 4005 | bt 

然后,为每个VLAN创build一个网桥,该网桥将来自每个接口的所有各个VLAN组合起来,以允许主网桥和VM网桥之间的无标记通信。

 bt.v1 8000.2a8c73ad057d no bt-fw1.1 bt-fw2.1 bt.1 bt.v4000 8000.2a8c73ad057d no bt-fw1.4000 bt-fw2.4000 bt.4000 bt.v4001 8000.2a8c73ad057d no bt-fw1.4001 bt-fw2.4001 bt.4001 bt.v4002 8000.2a8c73ad057d no bt-fw1.4002 bt-fw2.4002 bt.4002 bt.v4003 8000.2a8c73ad057d no bt-fw1.4003 bt-fw2.4003 bt.4003 bt.v4004 8000.2a8c73ad057d no bt-fw1.4004 bt-fw2.4004 bt.4004 bt.v4005 8000.2a8c73ad057d no bt-fw1.4005 bt-fw2.4005 bt.4005 

这现在允许到防火墙虚拟机的中继接口,只有我想要的VLAN。

任何未来的客户只需要一个单一的未标记的VLAN,只能被添加到相应的bt.X桥。

添加主机IP接口就像将IP添加到相应的VLAN网桥一样简单

例如。

 ip addr add 192.168.100.1/24 dev bt.v4005 

帮手脚本

由于我的/etc/network/interfaces文件可能会很快变得非常庞大,我写了一个小脚本,允许最less的configuration – 但是具有相同的最终结果。

在它包含的/etc/network/interfaces文件中

 # bridge bt-c0-fw1 vlan 1 4000-4005 interfaces tap100i0 # bridge bt-c0-fw2 vlan 1 4000-4005 interfaces tap101i0 # bridge bt vlan 1 4000-4005 interfaces eth0 # bridge-vlan bt vlan 1 4000-4005 interfaces bt-fw1 bt-fw2 bt auto eth0 iface eth0 inet manual post-up /scripts/build-bridges.sh || /bin/true 

然后在后续脚本/scripts/build-bridges.sh

 #!/bin/bash CONFIG="/etc/network/interfaces" DEFINERS="vlan|interfaces" DEBUG=0 # Tear down all interfaces modprobe -r 8021q modprobe 8021q brctl show | awk 'NR>1{print $1}' | while read BRIDGE; do ifconfig "$BRIDGE" down brctl delbr "$BRIDGE" done function run() { if [ $DEBUG -eq 1 ]; then echo "$@" else eval "$@" fi } function get_vars() { DATA=( $(echo "$2" | grep -Eoh "$1.+?" | sed -E "s/^$1 //g;s/($DEFINERS).+//g") ) for VAL in ${DATA[@]}; do echo $VAL | grep -qE "[0-9]+-[0-9]+" if [ $? -eq 0 ]; then LOWER=$(echo $VAL | cut -f1 -d"-") UPPER=$(echo $VAL | cut -f2 -d"-") for i in $(seq $LOWER $UPPER); do echo $i done else echo $VAL fi done } # Build bridges while read LINE; do BRIDGE=$(get_vars bridge "$LINE") if [[ ! "$BRIDGE" == "" ]]; then run brctl addbr $BRIDGE run ifconfig $BRIDGE up for INTERFACE in $(get_vars interfaces "$LINE"); do ifconfig $INTERFACE >/dev/null 2>&1 if [ $? -eq 0 ]; then run brctl addif $BRIDGE $INTERFACE fi done run ifconfig $BRIDGE up for VLAN in $(get_vars vlan "$LINE"); do run vconfig add $BRIDGE $VLAN 2>&1 | grep -vE "(VLAN 1 does not work|consider another number)" run ifconfig $BRIDGE.$VLAN up done fi done < <(grep -E "^# bridge " $CONFIG) # Build vlan bridges while read LINE; do BRIDGE=$(get_vars "bridge-vlan" "$LINE") for VLAN in $(get_vars " vlan" "$LINE"); do run brctl addbr $BRIDGE.v$VLAN run ifconfig $BRIDGE.v$VLAN up for INTERFACE in $(get_vars interfaces "$LINE"); do ifconfig $INTERFACE.$VLAN >/dev/null 2>&1 if [ $? -eq 0 ]; then run brctl addif $BRIDGE.v$VLAN $INTERFACE.$VLAN fi done done done < <(grep -E "^# bridge-vlan " $CONFIG) exit 0 

我希望这可以帮助别人,我花了DAYS阅读和testing,这似乎是最优雅,易于pipe理的解决scheme。

这里也有一些很好的阅读http://blog.davidvassallo.me/2012/05/05/kvm-brctl-in-linux-bringing-vlans-to-the-guests/