VXLAN
Кратко о технологии VXLAN
Virtual Extensible LAN (VXLAN) является технологией сетевой виртуализации, созданной для решения проблем масштабируемости в больших системах облачных вычислений. Она использует схожую с VLAN технику для MAC инкапсуляции Layer 2 Ethernet кадров в UDP-пакеты. VXLAN позволяет создать виртуальную L2 сеть и растянуть ее поверх L3, таких сетей может быть 2^24, т.е. больше 16 млн. Технология используется облачными провайдерами, где виртуальная машина может спокойно мигрировать между географически разделенными датацентрами.
Вот тут можно почитать подробней: http://www.vmgu.ru/news/vmware-vxlan-for-vsphere
Пример простой конфигурации VXLAN на openvswitch под ALTLinux
Попробуем настроить VXLAN на ALTLinux в самом простом варианте. Вот топология:
host1 и host2 соединены по OpenVPN через Интернет, внешние IP я тут не показываю, host2 так же соединен с host3 по Ethetnet. В терминологии VXLAN эти IP адреса являются VTEP (VXLAN Tunnel End Poin). Можно конечно использовать внешниие IP для организации VTEP, но во первых это не безопасно, во вторых host2 не имеет белого IP и находится за NAT. Для работы VXLAN используется порт 8472 UDP, убедитесь, что он не закрыт на firewall.
Установка
На host1 у меня установлен ALTLinux P7, на host2 и host3 стоит ALTLinux P8.
На всех хостах необходимо установить пакет openvswitch.
# apt-get install openvswitch
Вообще openvswitch очень мощная штука, вот официальный сайт, там можно найти много интересного: http://openvswitch.org
Далее запускаем его, можно через service, можно так:
# /etc/init.d/openvswitch start
Starting ovsdb-server [ DONE ]
Configuring Open vSwitch system IDs [ DONE ]
Starting ovs-vswitchd [ DONE ]
Enabling remote OVSDB managers [ DONE ]
iptables already has a rule for gre, not explicitly enabling [ DONE ]
Настройка
Теперь можем конфигурировать наш виртуальных коммутатор, на host1 создадим бридж:
# ovs-vsctl add-br OVS-BR0
Так же создадим порт для соединения с host2.
# ovs-vsctl add-port OVS-BR0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip=192.168.101.10
Посмотрим конфигурацию:
# ovs-vsctl show
627126b6-ef0f-4ff9-9a4b-446bac7f93a6
Bridge "OVS-BR0"
Port "vxlan1"
Interface "vxlan1"
type: vxlan
options: {remote_ip="192.168.101.10"}
Port "OVS-BR0"
Interface "OVS-BR0"
type: internal
ovs_version: "2.0.1"
Далее создадим бридж и порты на host2, тут их будет два:
# ovs-vsctl add-br OVS-BR0
# ovs-vsctl add-port OVS-BR0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip=192.168.101.1
# ovs-vsctl add-port OVS-BR0 vxlan2 -- set Interface vxlan2 type=vxlan options:remote_ip=192.168.7.47
Смотрим получившуюся конфигурацию:
# ovs-vsctl show
65a5df63-c1ba-43c8-b60c-4e0acc26d8ce
Bridge "OVS-BR0"
Port "OVS-BR0"
Interface "OVS-BR0"
type: internal
Port "vxlan2"
Interface "vxlan2"
type: vxlan
options: {remote_ip="192.168.7.47"}
Port "vxlan1"
Interface "vxlan1"
type: vxlan
options: {remote_ip="192.168.101.1"}
ovs_version: "2.4.1"
Создадим мост и порт на host3:
# ovs-vsctl add-br OVS-BR0
# ovs-vsctl add-port OVS-BR0 vxlan1 -- set Interface vxlan1 type=vxlan options:remote_ip:192.168.7.120
Получившийся конфиг:
# ovs-vsctl show
bed739d4-ddd8-4813-846a-a4c305209c14
Bridge "OVS-BR0"
Port "OVS-BR0"
Interface "OVS-BR0"
type: internal
Port "vxlan1"
Interface "vxlan1"
type: vxlan
options: {remote_ip="192.168.7.120"}
ovs_version: "2.4.1"
Теперь вешаем IP адреса на наши bridge-интерфейсы,
на host1:
[root@host1 ~]# ifconfig -a OVS-BR0 192.168.99.1 netmask 255.255.255.0
на host2:
[root@host2 ~]# ifconfig -a OVS-BR0 192.168.99.2 netmask 255.255.255.0
на host3:
[root@host3 ~]# ifconfig -a OVS-BR0 192.168.99.3 netmask 255.255.255.0
Проверка
Теперь проверяем, что получилось:
с host1:
[root@host1 ~]# ping -c 3 192.168.99.2
PING 192.168.99.2 (192.168.99.2) 56(84) bytes of data.
64 bytes from 192.168.99.2: icmp_req=1 ttl=64 time=24.8 ms
64 bytes from 192.168.99.2: icmp_req=2 ttl=64 time=13.3 ms
64 bytes from 192.168.99.2: icmp_req=3 ttl=64 time=13.0 ms
--- 192.168.99.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 13.073/17.075/24.817/5.477 ms
[root@host1 ~]# ping -c 3 192.168.99.3
PING 192.168.99.3 (192.168.99.3) 56(84) bytes of data.
64 bytes from 192.168.99.3: icmp_req=1 ttl=64 time=89.7 ms
64 bytes from 192.168.99.3: icmp_req=2 ttl=64 time=14.0 ms
64 bytes from 192.168.99.3: icmp_req=3 ttl=64 time=14.4 ms
--- 192.168.99.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 14.037/39.417/89.759/35.597 ms
с host2:
[root@sf-lenovo ~]# ping -c 3 192.168.99.1
PING 192.168.99.1 (192.168.99.1) 56(84) bytes of data.
64 bytes from 192.168.99.1: icmp_req=1 ttl=64 time=12.3 ms
64 bytes from 192.168.99.1: icmp_req=2 ttl=64 time=26.5 ms
64 bytes from 192.168.99.1: icmp_req=3 ttl=64 time=14.0 ms
--- 192.168.99.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 12.385/17.651/26.532/6.316 ms
[root@sf-lenovo ~]# ping -c 3 192.168.99.3
PING 192.168.99.3 (192.168.99.3) 56(84) bytes of data.
64 bytes from 192.168.99.3: icmp_req=1 ttl=64 time=2.82 ms
64 bytes from 192.168.99.3: icmp_req=2 ttl=64 time=0.726 ms
64 bytes from 192.168.99.3: icmp_req=3 ttl=64 time=0.708 ms
--- 192.168.99.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.708/1.419/2.825/0.994 ms
с host3:
[root@host3 ~]# ping -c 3 192.168.99.1
PING 192.168.99.1 (192.168.99.1) 56(84) bytes of data.
64 bytes from 192.168.99.1: icmp_req=1 ttl=64 time=14.4 ms
64 bytes from 192.168.99.1: icmp_req=2 ttl=64 time=15.0 ms
64 bytes from 192.168.99.1: icmp_req=3 ttl=64 time=14.3 ms
--- 192.168.99.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 14.355/14.629/15.078/0.348 ms
[root@host3 ~]# ping -c 3 192.168.99.3
PING 192.168.99.3 (192.168.99.3) 56(84) bytes of data.
64 bytes from 192.168.99.3: icmp_req=1 ttl=64 time=0.059 ms
64 bytes from 192.168.99.3: icmp_req=2 ttl=64 time=0.081 ms
64 bytes from 192.168.99.3: icmp_req=3 ttl=64 time=0.078 ms
--- 192.168.99.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.059/0.072/0.081/0.013 ms
Еще вот такую информацию можно посмотреть о бридже:
[root@host2 ~]# ovs-vsctl list bridge
_uuid : 822177df-484a-4cac-a51f-912375dabe91
auto_attach : []
controller : []
datapath_id : "0000de772182ac4c"
datapath_type : ""
datapath_version : "<unknown>"
external_ids : {}
fail_mode : []
flood_vlans : []
flow_tables : {}
ipfix : []
mcast_snooping_enable: false
mirrors : []
name : "OVS-BR0"
netflow : []
other_config : {}
ports : [5114a843-629c-4945-af2c-cd8004bae4c4, 52eb30a8-0035-41fe-bd59-6104c8ff8f06, dcd6f78f-1185-4ec3-8a62-ec9cd933951a]
protocols : []
rstp_enable : false
rstp_status : {}
sflow : []
status : {}
stp_enable : false
Если бы мы еще создали соединение между host1 и host3, то получилось бы кольцо, что хорошо для отказоустойчивости, но в таком случае нужно влючать протокол STP, что бы рвать петли, вот так (на всех openvswitch):
# ovs-vsctl set Bridge OVS-BR0 stp_enable=true
Настроенные бриджи можно посмотреть командой:
# ovs-vsctl list-br
OVS-BR0
А так список портов:
[root@host2 ~]# ovs-vsctl list-ports OVS-BR0
vxlan1
vxlan2
Одна из самых полезных команд, просмотр интерфейсов:
[root@host2 ~]# ovs-vsctl list interface
_uuid : e2adc1d8-3458-49f2-b98a-86a68eeb21ae
admin_state : up
bfd : {}
bfd_status : {}
cfm_fault : []
cfm_fault_status : []
cfm_flap_count : []
cfm_health : []
cfm_mpid : []
cfm_remote_mpids : []
cfm_remote_opstate : []
duplex : []
error : []
external_ids : {}
ifindex : 7
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current : []
link_resets : 0
link_speed : []
link_state : up
lldp : {}
mac : []
mac_in_use : "de:77:21:82:ac:4c"
mtu : 1500
name : "OVS-BR0"
ofport : 65534
ofport_request : []
options : {}
other_config : {}
statistics : {collisions=0, rx_bytes=7801, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=83, tx_bytes=9911, tx_dropped=0, tx_errors=0, tx_packets=81}
status : {driver_name=openvswitch}
type : internal
_uuid : a4f52dc0-4345-4c22-bb89-0c201254d4bf
admin_state : up
bfd : {}
bfd_status : {}
cfm_fault : []
cfm_fault_status : []
cfm_flap_count : []
cfm_health : []
cfm_mpid : []
cfm_remote_mpids : []
cfm_remote_opstate : []
duplex : []
error : []
external_ids : {}
ifindex : 0
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current : []
link_resets : 0
link_speed : []
link_state : up
lldp : {}
mac : []
mac_in_use : "62:78:d0:98:4e:42"
mtu : []
name : "vxlan2"
ofport : 2
ofport_request : []
options : {remote_ip="192.168.7.47"}
other_config : {}
statistics : {collisions=0, rx_bytes=1486, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=19, tx_bytes=57940, tx_dropped=0, tx_errors=0, tx_packets=1100}
status : {tunnel_egress_iface="eth0", tunnel_egress_iface_carrier=up}
type : vxlan
_uuid : 2e78186f-5c3f-4e06-900a-2358b8df1b6f
admin_state : up
bfd : {}
bfd_status : {}
cfm_fault : []
cfm_fault_status : []
cfm_flap_count : []
cfm_health : []
cfm_mpid : []
cfm_remote_mpids : []
cfm_remote_opstate : []
duplex : []
error : []
external_ids : {}
ifindex : 0
ingress_policing_burst: 0
ingress_policing_rate: 0
lacp_current : []
link_resets : 0
link_speed : []
link_state : up
lldp : {}
mac : []
mac_in_use : "fe:69:73:cf:d8:e3"
mtu : []
name : "vxlan1"
ofport : 3
ofport_request : []
options : {remote_ip="192.168.101.1"}
other_config : {}
statistics : {collisions=0, rx_bytes=1722, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=21, tx_bytes=58446, tx_dropped=0, tx_errors=0, tx_packets=1105}
status : {tunnel_egress_iface="tun0", tunnel_egress_iface_carrier=up}
type : vxlan
А вот так можно посмотреть таблицу mac-адресов:
[root@host2 ~]# ovs-appctl
fdb/show OVS-BR0
port VLAN MAC Age
3 0 06:50:58:05:ae:42 4
LOCAL 0 de:77:21:82:ac:4c 2
2 0 a2:20:93:2f:29:40 2
Вот эти маки в arp таблице:
[root@host2 ~]# arp -a
? (192.168.99.3) at a2:20:93:2f:29:40 [ether] on OVS-BR0
? (192.168.99.1) at 06:50:58:05:ae:42 [ether] on OVS-BR0
? (192.168.7.47) at e4:11:5b:5c:58:ba [ether] on eth0
Автозапуск
Что бы это все стартовало автоматом, нужно создать конфигурацию для интерфейса OVS-BR0 в etcnet, вот пример файла options:
# cat /etc/net/ifaces/OVS-BR0/options
TYPE=bri
BOOTPROTO=static
И файла ipv4address:
# cat /etc/net/ifaces/OVS-BR0/ipv4address
192.168.99.3/24
Ну и не забываем включить сервис openvswitch в автозапуск:
# chkconfig openvswitch on