Комментарии

Галерея

Опрос

Из каких стран идет больше всего спама, попыток взлома на ваши серверы?:

Настройка сетевого интерфейса в Qemu/KVM, объединённого в bridge

Всё чаще в процессе виртуализации необходимо наличие одного или нескольких виртуальных сетевых интерфейсов. Сегодня мы рассмотрим, как наладить работу с сетью нескольких виртуальных машин Qemu с минимальными затратами. Почему выбраны такие технологии, как Qemu/KVM? Достаточно заглянуть на Phoronix.com и преимущества Qemu/KVM перед другими средствами виртуализации станут очевидны. Стоит заметить, что выигрыш в тестах производительности справедлив для процессоров Intel. Для систем на базе AMD может подойти VirtualBox или VMWare.

Для начала нужно убедиться в наличии нужных модулей ядра (KVM, модули сетевого моста, Tun/Tap интерфейс):

# zcat /proc/config.gz | grep -E 'KVM|(^CONFIG_BRIDGE)|TUN'
CONFIG_INET_XFRM_TUNNEL=m
CONFIG_INET_TUNNEL=m
CONFIG_INET_XFRM_MODE_TUNNEL=m
CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_INET6_XFRM_MODE_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_BRIDGE_NETFILTER=y
CONFIG_BRIDGE=m
CONFIG_BRIDGE_IGMP_SNOOPING=y
CONFIG_TUN=m
CONFIG_HAVE_KVM=y
CONFIG_HAVE_KVM_IRQCHIP=y
CONFIG_HAVE_KVM_EVENTFD=y
CONFIG_KVM_APIC_ARCHITECTURE=y
CONFIG_KVM_MMIO=y
CONFIG_KVM_ASYNC_PF=y
CONFIG_HAVE_KVM_MSI=y
CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y
CONFIG_KVM=m
CONFIG_KVM_INTEL=m
# CONFIG_KVM_AMD is not set

Возможные use-флаги для установки Qemu в Gentoo:

app-emulation/qemu-1.4.2  USE="aio alsa caps curl fdt filecaps jpeg mixemu ncurses opengl png sdl seccomp threads uuid vhost-net vnc -accessibility -bluetooth -debug -iscsi -pulseaudio -python -rbd -sasl (-selinux) -smartcard -spice -static -static-softmmu -static-user -systemtap -tci {-test} -tls -usbredir -vde -virtfs -xattr -xen -xfs" PYTHON_TARGETS="python2_7 -python2_5 -python2_6" QEMU_SOFTMMU_TARGETS="i386 x86_64 -alpha -arm -cris -lm32 -m68k -microblaze -microblazeel -mips -mips64 -mips64el -mipsel -or32 -ppc -ppc64 -ppcemb -s390x -sh4 -sh4eb -sparc -sparc64 -unicore32 -xtensa -xtensaeb" QEMU_USER_TARGETS="i386 x86_64 -alpha -arm -armeb -cris -m68k -microblaze -microblazeel -mips -mipsel -or32 -ppc -ppc64 -ppc64abi32 -s390x -sh4 -sh4eb -sparc -sparc32plus -sparc64 -unicore32"

Сначала нужно создать сетевой мост в системе. В Gentoo это делается редактированием /etc/conf.d/net. У меня он имеет следующий вид (1 туннель tap0 добавлен на всякий случай и не пригодится в дальнейшем, т.к. qemu может создавать их автоматически):

modules="!ifconfig"
 
bridge_br0="enp7s0 tap0"
rc_net_br0_need="net.enp7s0 net.tap0"
config_br0="192.168.10.210/16"
routes_br0="default gw 192.168.10.1"
 
config_enp7s0="null"
 
tuntap_tap0="tap"
#tunctl_tap0="-u user -g user"
config_tap0="null"
# ip link show br0
4: br0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT 
    link/ether 3a:db:33:10:df:ef brd ff:ff:ff:ff:ff:ff
# ip link show tap0
3: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN mode DEFAULT qlen 500
    link/ether 3a:db:33:10:df:ef brd ff:ff:ff:ff:ff:ff

В файле /etc/qemu/bridge.conf указывается какое устройство сетевого моста должен использовать Qemu:

allow br0

Для возможности обмена пакетами между виртуальными машинами через созданные виртуальные сетевые устройства, нужно сгенерировать для них уникальные MAC-адреса. Я делаю это таким образом:

printf 'DE:AD:%02X:%02X:%02X:%02X\n' $((RANDOM%256)) $(($$%256)) $(($$/256%256)) $(($1))

Как видно здесь задействован PID процесса ($$) для генерации последовательности. Возможный скрипт запуска Qemu:

#!/bin/bash
 
# original qemu mac: 52:54:00:12:34:56
# printf 'DE:AD:BE:EF:%02X:%02X\n' $((RANDOM%256)) $((RANDOM%256))
 
QEMU="/usr/bin/qemu-kvm"
 
genmaddr() {
	printf 'DE:AD:%02X:%02X:%02X:%02X\n' $((RANDOM%256)) $(($$%256)) $(($$/256%256)) $(($1))
}
 
MADDR0=`genmaddr 10`
MADDR1=`genmaddr 20`
 
echo "maddr0: ${MADDR0}"
echo "maddr1: ${MADDR1}"
 
${QEMU} \
	-monitor stdio \
	-smp 2 \
	-vga cirrus \
	-enable-kvm \
	-m 512 \
	-localtime \
	-cdrom /mnt/routine/tmp/iso/systemrescuecd-x86-3.7.0.iso \
	-hda ${1}.qcow2 \
	-hdb ${1}-swap.qcow2 \
	-net nic,vlan=0,macaddr=${MADDR0} -net bridge,vlan=0 \
	-net nic,vlan=1,macaddr=${MADDR1} -net bridge,vlan=1 \
	-boot d \
	-name "${1}"

После запуска скрипта, на хосте должно появиться 2 дополнительных туннельных устройства (по одному на каждую сетевую карту):

# ip tap
tap1: tap vnet_hdr
tap2: tap vnet_hdr
tap0: tap

Удачи!