[Из песочницы] Open vSwitch как ядро виртуальной сети
В данной статье для виртуализации используется KVM/libvirt, но сразу отмечу, статья не столько о KVM, сколько именно об особенностях преимуществах использования Open vSwitch для объединения виртуальных и физических сетевых устройств посредством технологии VLAN (802.1q). В былинные времена для проброса тегированного трафика в гипервизор использовались всевозможные костыли и подпорки различной степени неожиданности (tuntap, brctl, vconfig, ebtables и прочее), что приводило к захламлению операционной системы, хостящей гипервизор большим количеством ненужных виртуальных сетевых интерфейсов, мозолящих глаза в выводе ifconfig и вообще огорчало администраторов необходимостью строить стандартное сетевое устройство (коммутатор) из отдельных частей как какой-то велосипед. Помимо поддержки 802.1q от коммутатора на самом деле сегодня требуется еще много функций. Так необходимость в виртуальном устройстве максимально соответствующем по функционалу стандартному современному управляемому коммутатору привела к появлению проекта Open vSwitch (далее — OVS).Рисунок 1: Проект песочницыНа КДПВ (Рисунок 1) изображен юзкейс OVS для построения песочницы для подготовки к замене наших устаревших VPN-маршрутизаторов на новые. Нужно сконфигурировать новые VPN-маршрутизаторы аналогично уже инсталлированным в нашей компании с теми же IP адресами, правилами фильтрации и настройками динамической маршрутизаци. И протестировать всё в песочнице, эмулирующей ISP (через которые соединяются VPN-маршрутизаторы) и сайты нашей локалки. Но повторюсь, эта статья не о сложностях настройки наших VPN-маршрутизаторов, а о том, как подключить их к нашей уютной виртуальной песочнице посредством VLAN вообще и OVS в частности.
Начнём с самого начала, установив чистую копию ubuntu-14.04.1-server-amd64 с опцией «Virtual Machine host». После установки система имеет следующий вид:
Вывод утилит просмотра сетевых параметров root@sandbox:~# ifconfig |grep -vE 'RX|TX|coll|inet6|MTU'
eth0 Link encap: Ethernet HWaddr 00:1b:78:9c:2b: fc inet addr:10.0.7.1 Bcast:10.27.64.63 Mask:255.255.255.192
lo Link encap: Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0
virbr0 Link encap: Ethernet HWaddr 1a:70:19: e9:3c: c7 inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
root@sandbox:~# route -n
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.0.7.254 0.0.0.0 UG 0 0 0 eth0 10.0.7.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
root@sandbox:~# cat /etc/network/interfaces |grep -v ^#
auto lo iface lo inet loopback
auto eth0 iface eth0 inet static address 10.0.7.1 netmask 255.255.255.0 network 10.0.7.0 broadcast 10.0.7.255 gateway 10.0.7.254 # dns-* options are implemented by the resolvconf package, if installed dns-nameservers 10.0.1.1
root@sandbox:~# virsh net-list --all
Name State Autostart Persistent ---------------------------------------------------------- default active yes yes
root@sandbox:~# virsh net-dumpxml default
default 865fd53b-5bd5–430c-b7c7–664125dee9f6
root@sandbox:~# brctl show
bridge name bridge id STP enabled interfaces virbr0 8000.000000000000 yes
Всё очень стандартно, ни чего не обычного.На картинке всё еще проще:
Рисунок 2: Начальное состояние системы
Устанавливаем openvswitch: apt-get install openvswitch-switch
После его установки ни каких изменений в сетевых параметрах не происходит, лишь запускается сервис OVS, ждущий наших распоряжений. Не будем заставлять его ждать. Вводим нижеприведенные команды с консоли или помещаем их во временный .sh скрипт и запускаем:
ovs-vsctl add-br ovs-br0ovs-vsctl set port ovs-br0 tag=7ovs-vsctl add-port ovs-br0 eth0ovs-vsctl set port eth0 trunks=7,10,20,1010,1020ifconfig eth0 0ifconfig ovs-br0 10.0.7.1/24 upip r add default via 10.0.7.254
переключаем хост в тегированный порт свитчаПояснения ovs-vsctl add-br ovs-br0Создает почти пустой инстанс виртуального коммутатора, есть только один порт к которому и подключен одноименный внутренний интерфейс ovs-br0.ovs-vsctl set port ovs-br0 tag=7Конфигурируем этот порт как access-port для VLAN 7.
ovs-vsctl add-port ovs-br0 eth0Добавляем к нашему коммутатору еще один порт, в который переключаем интерфейс eth0.
ovs-vsctl set port eth0 trunks=7,10,20,1010,1020делаем этот порт транковым для указанных VLAN ID. В принципе, параметр trunks можно вообще не указывать, тогда порт будет пропускать все VLAN ID.
ifconfig eth0 0Обнуляем конфигурацию IP для eth0. Он больше не будет связан с IP стеком OS.
ifconfig ovs-br0 10.0.7.1/24 upВместо eth0 к IP стеку OS прикручиваем внутренний интерфейс ovs-br0.
ip r add default via 10.0.7.254Ну и не забываем восстановить таблицу маршрутизации
Переключаем хост в тегированный порт коммутатораМы в сети! ©
Смотрим, что же изменилось в сетевых настройках: root@sandbox:~# ovs-vsctl show
40952e4d-81ad-433b-b08b-f88ccd55f26a Bridge «ovs-br0» Port «ovs-br0» tag: 7 Interface «ovs-br0» type: internal Port «eth0» trunks: [7,10,20,1010,1020] Interface «eth0» ovs_version:»2.0.2»
root@sandbox:~# ifconfig |grep -vE 'RX|TX|coll|inet6|MTU'
eth0 Link encap: Ethernet HWaddr 00:1b:78:9c:2b: fc
lo Link encap: Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0
ovs-br0 Link encap: Ethernet HWaddr 00:1b:78:9c:2b: fc inet addr:10.27.64.1 Bcast:10.27.64.63 Mask:255.255.255.192
virbr0 Link encap: Ethernet HWaddr 32: b9: dd:38:09: f5 inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
root@sandbox:~# route -n
Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.27.64.62 0.0.0.0 UG 0 0 0 ovs-br0 10.27.64.0 0.0.0.0 255.255.255.192 U 0 0 0 ovs-br0 192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
Ну и в виде картинки: Рисунок 3: Установили openvswitch и подключили его к IP стеку OS вместо eth0.
Интерфейс коммутатора virbr0 в дальнейшем изображать не будем, он нам не интересен и ни на что не влияет.
Ничего неожиданного, всё логично и интуитивно понятно.
Еще один приятный момент для тех, кто уже начал беспокоиться о том, где же размещать стартовые скрипты применения этой конфигурации. Ничего особо делать и не придется, конфигурация OVS вышеуказанными командами ovs-vsctl не только применяется, но и автоматически сохраняется, так что вам не нужно переживать о несовпадение текущей и сохраненной конфигурации OVS. А файл /etc/network/interfaces нам надо лишь малость обновить в связи с заменой интерфейса eth0 на ovs-br0:
root@sandbox:~# cat /etc/network/interfaces |grep -v ^#
auto lo iface lo inet loopback
auto eth0 iface eth0 inet manual
auto ovs-br0 iface ovs-br0 inet static address 10.0.7.1 netmask 255.255.255.0 network 10.0.7.0 broadcast 10.0.7.254 gateway 10.0.7.254 # dns-* options are implemented by the resolvconf package, if installed dns-nameservers 10.0.1.1
Но коммутатор в данный момент всего с двумя портами, как же подключить к нему наши 5 виртуальных машин? Тут есть как минимум 2 пути. Первый, наиболее очевидный, состоит в том, чтобы с помощью команды ovs-vsctl add-port добавить порт (access или транковый — на выбор).
ovs-vsctl add-port ovs-br0 ISP tag=10 — set interface ISP type=internal — (две черточки) используется для выполнения нескольких команд ovs-vsctl в одну строку
Затем можно будет прямо в GUI virt-manager’а выбрать его для подключения сетевого интерфейса виртуальной машины. Но мы пойдем более масштабируемым способом. При этом порты создавать вообще не нужно (как собственно и в стандартном linux core bridge). Вместо этого можно создать порт-группы для OVS. Каждая порт-группа предназначена для подключения VM к соответствующему VLAN. К сожалению, их настройка из GUI virt-manager’а недоступна, необходимо вручную подготовить простенький XML файл, описывающий необходимые порт-группы и затем применить его через API libvirt с помощью команды virsh, как указано ниже:
XML-конфиг для конфигурации, показанной на Рисунке 1:
Пояснения vi /tmp/ovs-network.xmlкопируем в этот файл вышеуказанное содержимое XMLvirsh net-define /tmp/ovs-network.xmlконфигурируем новую сеть для KVM
virsh net-start ovs-networkзапускаем её
virsh net-autostart ovs-networkделаем её запуск автоматическим
что бы удалить ненужную сеть virsh net-destroy ovs-networkvirsh net-autostart --disable ovs-networkvirsh net-undefine ovs-network
изобразим полученное: Рисунок4: Создали порт-группы для наших VM
Создадим пару виртуальных машин VM1 и VM2 в virt-manager’е и при создании укажим Advanced options Virtual network 'ovs-network': Bridge networkПока оставим их выключенными
подправим конфиги виртуалокvirsh edit VM1
Найдем секцию interface и добавим параметр portgroup
Сделаеем так же для второй VMЕсли посмотреть сейчас состояние сетевых интерфейсов коммутатора и операционной системы, то увидим, что ни каких изменений не произошло. Порты на коммутаторе не добавились, лишних сетевых интерфейсов в системе не появилось.Теперь запустим обе VM:
и еще раз проверим состояние сетевых параметров хоста root@sandbox:~# ovs-vsctl show
40952e4d-81ad-433b-b08b-f88ccd55f26a Bridge «ovs-br0» Port «vnet0» tag: 10 Interface «vnet0» Port «ovs-br0» tag: 7 Interface «ovs-br0» type: internal Port «eth0» trunks: [7, 10, 20, 1010, 1020] Interface «eth0» Port «vnet1» tag: 20 Interface «vnet1» ovs_version:»2.0.2»
root@sandbox:~# ifconfig |grep -vE 'RX|TX|coll|inet6|MTU'
eth0 Link encap: Ethernet HWaddr 00:1b:78:9c:2b: fc
lo Link encap: Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0
ovs-br0 Link encap: Ethernet HWaddr 00:1b:78:9c:2b: fc inet addr:10.0.7.1 Bcast:10.27.64.63 Mask:255.255.255.192
virbr0 Link encap: Ethernet HWaddr 32: b9: dd:38:09: f5 inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
vnet0 Link encap: Ethernet HWaddr fe:54:00:5e: b9: b2
vnet1 Link encap: Ethernet HWaddr fe:54:00:7f:40: d0
Как видим, в коммутаторе добавились порты соответствующих порт-групп, а в системе добавилось пара интерфейсов с MAC-адресами, соответствующими VM (при выключение VM соответствующие порты и интерфейсы опять исчезнут).Рисунок 5: запустили пару VM
Еще упомяну, что 802.1q не единственная фича Open vSwitch, с его помощью можно организовать, например, бондинг двух интерфейсов и кое-что еще.
Вот, собственно, и всё. Надеюсь, кому-то эта статья поможет решиться использовать Open vSwitch в своих проектах и просто песочницах вместо стандартного linux bridge.