Я наткнулся на своего рода преграду с архитектурной проблемой. У меня есть сервер под управлением KVM, на котором будет несколько гостей, некоторые из которых будут использовать виртуализированные брандмауэры, а другие - просто веб-серверы.
Обычно это было бы просто, просто добавьте мост с помощью eth0
в нем добавляем несколько VLAN на мост (vmbr0.1
и т. д.) - затем выделите интерфейс с немаркированной 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 в брандмауэр. Это непрактично.
Так что я не могу понять, как создать номерные магистрали (с общими VLAN и разными VLAN) и выделить их гостю.
Ближайшее решение, которое я нашел до сих пор, - создать VLAN на главном мосту, а затем для серверов просто выделить из него одну VLAN.
Затем для брандмауэров создайте мост для каждого, только с гостевым tap
интерфейс в нем, затем создайте немаркированный vlan
интерфейс для соответствующего моста и добавьте его в основной vmbr0
мост.
Единственная проблема с этим состоит в том, что трафик, выходящий из немаркированного интерфейса, конечно, немаркирован.
Можно ли пометить трафик, выходящий из интерфейса?
-
В противном случае, как можно получить разные магистрали для гостей KVM, которые могут иметь общие VLAN и разные VLAN (но никогда ВСЕ vlan) - и иметь возможность назначать отдельные нетегированные интерфейсы vlan
Итак, я экспериментировал с разными концепциями и думаю, что нашел работоспособное решение. В основном это основной мостовой ствол (bt
) который eth0
принадлежит. Тогда для каждой виртуальной машины межсетевого экрана есть свой мост.
bridge name bridge id STP enabled interfaces
bt 8000.002618895a72 no eth0
bt-fw1 8000.000000000000 no tap100i0
bt-fw2 8000.000000000000 no tap101i0
В этот момент помеченный трафик от виртуальных машин межсетевого экрана войдет в свой собственный мост для входа трафика.
Затем я создал VLAN для каждого интерфейса, которому нужен тегированный трафик, и соответствующую 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 создается мост, который объединяет все соответствующие VLAN от каждого интерфейса, чтобы обеспечить немаркированную связь между основным мостом и мостами виртуальных машин.
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
файл может быстро стать огромным, я написал небольшой сценарий, который допускает минимальную настройку - но с тем же желаемым конечным результатом.
в /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
Я надеюсь, что это поможет кому-то другому, я потратил ДНИ на чтение и тестирование, и это кажется наиболее элегантным и простым в управлении решением.
Здесь тоже есть хорошее чтение http://blog.davidvassallo.me/2012/05/05/kvm-brctl-in-linux-bringing-vlans-to-the-gests/