соединение гипервизоров при помощи VXLAN

    2015-11-20 18:44 | Автор: jekader | Filed under: FedoraMD, Jekader

    После настройки openvswitch на нескольких машинах для использования с виртуальными машинами я решил пойти дальше и воспользовался некоторыми плюшками, такими как создание распределённых коммутаторов. В моём примере это позволяет соединить гипервизоры по технологии VXLAN и сделать так чтобы виртуальные машины на разных гипервизорах общались напрямую, и даже DHCP сервер на одном гипервизоре выдавал IP виртуалкам с другого. При этом весь L2 траффик оказывается изолирован и энкапсулирован в IP пакеты.

    Сначала опишу имеющиеся гипервизоры:

    host1 - eth0 10.1.1.3/24, br1 192.168.223.3/24
    host2 - eth0 10.1.2.4/24, br1 192.168.223.4/24

    Как видим, гипервизоры находятся в разных подсетях, при этом имеют OVS коммутаторы в одной и той-же подсети. Допустим на host1 у нас крутится виртуальная машина с IP 192.168.223.1 и установленным DHCP сервером, а на host2 есть клиент, который должен получить IP.

    1) Настроить VXLAN довольно просто, главное не забыть открыть UDP порт 4789 так как через него будет приниматься траффик на обоих хостах.
    По сути всё что нужно сделать - это создать отдельный порт на OVS коммутаторе в который будет уходить неизвестный траффик. А этот порт в свою очередь будет энкапсулировать данные в VXLAN и отправлять через UDP на IP адрес другой машины.

    На host1:
    # ovs-vsctl add-port br1 to_host2 -- set interface to_host2 type=vxlan options:remote_ip=10.1.2.4

    Аналогично на host2 чтобы ответные пакеты высылались назад:
    # ovs-vsctl add-port br1 to_host1 -- set interface to_host1 type=vxlan options:remote_ip=10.1.1.3

    смотрим состояние коммутатора:
    # ovs-vsctl show
    daa6e9a1-410f-46e5-bfd8-feb263776263
    Bridge "br1"
    Port "to_host2"
    Interface "to_host2"
    type: vxlan
    options: {remote_ip="10.1.2.4"}
    Port "br1"
    Interface "br1"
    type: internal
    ovs_version: "2.3.0"

    Я добавил эти команды в rc.local на обеих машинах чтобы они выполнялись при загрузке.

    2) Теперь на host1 пингуем внутренний IP host2:
    # ping -c 3 192.168.223.4
    PING 192.168.223.7 (192.168.223.7) 56(84) bytes of data.
    64 bytes from 192.168.223.4: icmp_seq=1 ttl=64 time=0.859 ms
    64 bytes from 192.168.223.4: icmp_seq=2 ttl=64 time=0.602 ms
    64 bytes from 192.168.223.4: icmp_seq=3 ttl=64 time=0.571 ms

    --- 192.168.223.4 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2001ms
    rtt min/avg/max/mdev = 0.571/0.677/0.859/0.130 ms

    Работает!

    3) Проверим ARP таблицу на host1:
    # arp -n
    Address HWtype HWaddress Flags Mask Iface
    10.34.1.1 ether 60:70:80:9a:0b:1c C eth0
    192.168.223.1 ether 52:54:00:a1:b2:c3 C br1
    192.168.223.4 ether 60:70:80:88:cc:44 C br1

    Видим MAC адреса нашей виртуальной машины и гипервизора host2

    4) Посмотрим как это работает на стороне сетевого стека - запустим ping на host1 и одновременно tcpdump на host2 чтобы увидеть колдунство:

    # tcpdump -nn -i eth0 port 4789
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
    17:26:11.685339 IP 10.1.1.3.56787 > 10.1.2.4.4789: VXLAN, flags [I] (0x08), vni 0
    IP 192.168.223.3 > 192.168.223.4: ICMP echo request, id 19831, seq 1, length 64
    17:26:11.685570 IP 10.1.2.4.45397 > 10.1.1.3.4789: VXLAN, flags [I] (0x08), vni 0
    IP 192.168.223.4 > 192.168.223.3: ICMP echo reply, id 19831, seq 1, length 64
    17:26:12.686029 IP 10.1.1.3.56787 > 10.1.2.4.4789: VXLAN, flags [I] (0x08), vni 0
    IP 192.168.223.3 > 192.168.223.4: ICMP echo request, id 19831, seq 2, length 64
    17:26:12.686099 IP 10.1.2.4.45397 > 10.1.1.3.4789: VXLAN, flags [I] (0x08), vni 0
    IP 192.168.223.4 > 192.168.223.3: ICMP echo reply, id 19831, seq 2, length 64
    17:26:13.686006 IP 10.1.1.3.56787 > 10.1.2.4.4789: VXLAN, flags [I] (0x08), vni 0
    IP 192.168.223.3 > 192.168.223.4: ICMP echo request, id 19831, seq 3, length 64
    17:26:13.686093 IP 10.1.2.4.45397 > 10.1.1.3.4789: VXLAN, flags [I] (0x08), vni 0
    IP 192.168.223.4 > 192.168.223.3: ICMP echo reply, id 19831, seq 3, length 64

    6 packets captured
    6 packets received by filter
    0 packets dropped by kernel

    Хорошо видно как ICMP пакеты энкапсулируются в VXLAN пакеты, tcpdump даже показывает их содержимое.
    Аналогично работают и все остальные протоколы, и в целом OVS поддерживает довольно много действий по фильтрации и обработке данных - для моих нужд это не требуется, но в ситуацией с множеством независимых клиентов (openstack, openswitch) они используются довольно активно. Пример настройки "умного" свитча с фильтрацией тут.

    Если некоторые пакеты проходят а некоторые нет - смотрим в сторону MTU на интерфейсе br1 (измеряем при помощи iperf и ставим на интерфейсе).
    Для проверки можно временно поставить MTU 1300 на обеих сторонах и посмотреть поможет-ли:
    # ip link set dev br1 mtu 1300

    Подведём итоги: теперь не имея отдельного VLAN между виртуальными машинами на обоих гипервизорах есть прямая L2 связь, работает DHCP и можно проводить любые эксперименты в полной изоляции.

    1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 1,00 out of 5)
    Loading...

    Метки: , ,

    2 комментария »


    комментария 2

    1. Сергей:

      Спасибо.

      Пож-та, если есть выложите:

      Пример настройки «умного» свитча с фильтрацией тут.

      link is dead

    2. jekader:

      http://vswitch.org/support/dist-docs-2.5/tutorial/Tutorial.md.html

    Leave a comment

    *