Openstack DVR検証


**※ Junoリリース時に書いたメモのため内容が古いのに注意**

## Overview

Openstack DVR環境を試してみたいけど、ベアメタルで試す環境がないのでVagrant環境で試してみる。

## Requirements

- Openstack (Tested on Juno)

## Install


[第20回 OpenStack勉強会 Neutron Deep Dive - DVR ](http://www.slideshare.net/ToruMakabe/20-openstack-neutron-deep-dive-dvr)

詳細な資料は上記Slideshare資料にアップされているのでその設定を参考に進める。

openstack-neutron-ml2がcompute nodeに入っていることを確認する。
入ってなければインストールする。OpenstackはRDOでインストールされていることを前提とする。

```
yum install openstack-neutron-ml2
```

Neutronの

- ml2_conf.ini
- l3_agent.ini
- neutron.conf

をそれぞれ修正する。また各ノードにl3-agent, metadata-serviceが入ってることを確認する。

### Controller Node

```ml2_conf.ini
# cat plugins/ml2/ml2_conf.ini | grep -v -e "^#" -e "^\s*$"                                                                                           !2062
[ml2]
type_drivers = flat,vxlan
tenant_network_types = vxlan
mechanism_drivers=openvswitch,l2population
[ml2_type_flat]
flat_networks = external
[ml2_type_vlan]
[ml2_type_gre]
[ml2_type_vxlan]
vni_ranges =10:100
vxlan_group =224.0.0.1
[securitygroup]
enable_security_group = True
enable_ipset = True
firewall_driver = neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
```

```l3_agent.ini
# cat l3_agent.ini  | grep -v -e "^#" -e "^\s*$"                                                                                                      !2045
[DEFAULT]
debug = False
interface_driver =neutron.agent.linux.interface.OVSInterfaceDriver
use_namespaces = True
handle_internal_only_routers = True
external_network_bridge = br-ex
metadata_port = 9697
send_arp_for_ha = 3
periodic_interval = 40
periodic_fuzzy_delay = 5
enable_metadata_proxy = True
router_delete_namespaces = True
agent_mode = dvr_snat
allow_automatic_l3agent_failover=False
```

```neutron.conf
# cat neutron.conf | grep -v -e "^#" -e "^\s*$"                                                                                                       !2063
[DEFAULT]
verbose = True
router_distributed = True
debug = False
use_syslog = False
log_dir =/var/log/neutron
bind_host = 0.0.0.0
bind_port = 9696
core_plugin =neutron.plugins.ml2.plugin.Ml2Plugin
service_plugins =neutron.services.l3_router.l3_router_plugin.L3RouterPlugin,neutron.services.loadbalancer.plugin.LoadBalancerPlugin
auth_strategy = keystone
base_mac = fa:16:3e:00:00:00
mac_generation_retries = 16
dhcp_lease_duration = 86400
dhcp_agent_notification = True
allow_bulk = True
allow_pagination = False
allow_sorting = False
allow_overlapping_ips = True
agent_down_time = 75
router_scheduler_driver = neutron.scheduler.l3_agent_scheduler.ChanceScheduler
allow_automatic_l3agent_failover = True
dhcp_agents_per_network = 1
api_workers = 32
rpc_workers = 32
use_ssl = False
notify_nova_on_port_status_changes = True
notify_nova_on_port_data_changes = True
nova_url = http://10.1.4.71:8774/v2
nova_region_name =RegionOne
nova_admin_username =nova
nova_admin_tenant_id =**********************
nova_admin_password =***********
nova_admin_auth_url =http://10.1.4.71:35357/v2.0
send_events_interval = 2
kombu_reconnect_delay=1.0
rabbit_host=10.1.4.71
rabbit_port=5672
rabbit_hosts=10.1.4.71:5672
rabbit_use_ssl=False
rabbit_userid=guest
rabbit_password=guest
rabbit_virtual_host=/
rabbit_ha_queues=False
rpc_backend=neutron.openstack.common.rpc.impl_kombu
control_exchange=neutron
[matchmaker_redis]
[matchmaker_ring]
[quotas]
[agent]
root_helper = sudo neutron-rootwrap /etc/neutron/rootwrap.conf
report_interval = 30
[keystone_authtoken]
auth_host = 10.1.4.71
auth_port = 35357
auth_protocol = http
admin_tenant_name = services
admin_user = neutron
admin_password = *******************
auth_uri=http://10.1.4.71:5000/
[database]
connection = mysql://neutron:a0ce8c5077f64ea9@10.1.4.71/neutron
max_retries = 10
retry_interval = 10
min_pool_size = 1
max_pool_size = 10
idle_timeout = 3600
max_overflow = 20
[service_providers]
service_provider=LOADBALANCER:Haproxy:neutron.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
service_provider=VPN:openswan:neutron.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default
```

### Compute Node

```ml2_conf.ini
# cat /etc/neutron/plugins/ml2/ml2_conf.ini  | grep -v -e "^#" -e "^\s*$"
[ml2]
type_drivers = flat,vxlan
tenant_network_types = vxlan
mechanism_drivers = openvswitch,l2population
[ml2_type_flat]
flat_networks = external
[ml2_type_vlan]
[ml2_type_gre]
[ml2_type_vxlan]
vni_ranges =10:100
vxlan_group =224.0.0.1
[securitygroup]
enable_security_group = True
[ovs]
l2_population = True
tunnel_types = vxlan
enable_distributed_routing = True
enable_tunneling = True
bridge_mappings = external:br-ex
[agent]
l2_population = True
tunnel_types = vxlan
enable_distributed_routing = True
```

- l3_agent.ini → 変更なし
- neutron.conf → 変更なし


dashboardのバグでDVRだと`no ports available`になってしまうので該当するファイルを修正する。(※2015/01/27現在公開されている公式のコードでは修正済)

https://ask.openstack.org/en/question/51634/juno-dvr-associate-floating-ip-reported-no-ports-available/


```/usr/share/openstack-dashboard/openstack_dashboard/api/neutron.py

find  def _get_reachable_subnets(self, ports):

replace  p.device_owner == 'network:router_interface'  
↓  
p.device_owner == 'network:router_interface'   or p.device_owner == 'network:router_interface_distributed'
```

### インスタンス起動時のDHCPが繋がらない場合

一度networkの再起動、openstackの再起動、openstack上の仮想ネットワークの削除、再作成を行う。
ホスト側のインターフェースにデバイス名に間違いないか確認。ブリッジインターフェースの間違いがないか確認。


ネットワークを再起動し通信パターンを確認

|サブネット|ホスト|Non-DVR|DVR|
|--:|--:|--:|--:|
|同じ|同じ|仮想スイッチ|仮想スイッチ|
|同じ|違う|トンネル|トンネル|
|違う|同じ|Network-node経由|DVR on Compute Node|
|違う|違う|Network-node経由|DVR on Compute Node|

### 時刻合わせ

Openstackは時刻の同期が重要になり大きく時刻ズレがある場合インスタンスの起動等も出来なくなるため必ずchronyをインストールしておく。

```
yum install chrony
service chronyd start
```


・bootするホストを指定し仮想マシンを起動

```bash
nova image-listで起動したいimageのIDを確認
neutron net-listでnicを作るnetworkのidを確認
nova hypervisor-listで起動したいハイパーバイザーの名前を確認

nova boot --image 5165cfd8-c389-464e-b210-88295aa2009c --flavor m1.tiny --availability-zone nova:compute1 --nic net-id=bf251706-6c13-4390-b088-3a5310432104
```

それぞれ異なるホストでインスタンスを起動し、DVRで直接Compute node同士で通信しているかtcpdumpで確認する。

```bash
tcpdump -i enp0s8 src host compute2 and dst host compute1 -vvv -X
```

仮想マシンからpingを飛ばすと以下のようなパケットが確認出来、直接Compute同士で通信していることが分かる。

```bash
05:25:29.970735 IP (tos 0x0, ttl 64, id 41605, offset 0, flags [DF], proto UDP (17), length 134)
    compute2.37954 > compute1.4789: [no cksum] VXLAN, flags [I] (0x08), vni 10
IP (tos 0x0, ttl 64, id 1534, offset 0, flags [DF], proto ICMP (1), length 84)
    172.16.42.6 > 172.16.42.7: ICMP echo request, id 22273, seq 133, length 64
	0x0000:  4500 0086 a285 4000 4011 8a79 c0a8 460c  E.....@.@..y..F.
	0x0010:  c0a8 460b 9442 12b5 0072 0000 0800 0000  ..F..B...r......
	0x0020:  0000 0a00 fa16 3e9c 472d fa16 3edc c00c  ......>.G-..>...
	0x0030:  0800 4500 0054 05fe 4000 4001 887d ac10  ..E..T..@.@..}..
	0x0040:  2a06 ac10 2a07 0800 e864 5701 0085 71d7  *...*....dW...q.
	0x0050:  463d 0000 0000 0000 0000 0000 0000 0000  F=..............
	0x0060:  0000 0000 0000 0000 0000 0000 0000 0000  ................
	0x0070:  0000 0000 0000 0000 0000 0000 0000 0000  ................
	0x0080:  0000 0000 0000                           ......
```