
It also adds 2 sample of devstack's local.conf file for deploying Neutron with OVN mechanism driver. Needed to create PNG files out of the existing SVG ones in order to pass the pdf doc build. Co-Authored-By: Aaron Rosen <aaronorosen@gmail.com> Co-Authored-By: Akihiro Motoki <amotoki@gmail.com> Co-Authored-By: Amitabha Biswas <abiswas@us.ibm.com> Co-Authored-By: Andreas Jaeger <aj@suse.com> Co-Authored-By: Anh Tran <anhtt@vn.fujitsu.com> Co-Authored-By: Assaf Muller <amuller@redhat.com> Co-Authored-By: Babu Shanmugam <bschanmu@redhat.com> Co-Authored-By: Brian Haley <bhaley@redhat.com> Co-Authored-By: Chandra S Vejendla <csvejend@us.ibm.com> Co-Authored-By: Daniel Alvarez <dalvarez@redhat.com> Co-Authored-By: Dong Jun <dongj@dtdream.com> Co-Authored-By: Emilien Macchi <emilien@redhat.com> Co-Authored-By: Flavio Fernandes <flavio@flaviof.com> Co-Authored-By: Gal Sagie <gal.sagie@huawei.com> Co-Authored-By: Gary Kotton <gkotton@vmware.com> Co-Authored-By: Guoshuai Li <ligs@dtdream.com> Co-Authored-By: Han Zhou <zhouhan@gmail.com> Co-Authored-By: Hong Hui Xiao <xiaohhui@cn.ibm.com> Co-Authored-By: Jakub Libosvar <libosvar@redhat.com> Co-Authored-By: Jeff Feng <jianhua@us.ibm.com> Co-Authored-By: Jenkins <jenkins@review.openstack.org> Co-Authored-By: Jonathan Herlin <jonte@jherlin.se> Co-Authored-By: Kyle Mestery <mestery@mestery.com> Co-Authored-By: Le Hou <houl7@chinaunicom.cn> Co-Authored-By: Lucas Alvares Gomes <lucasagomes@gmail.com> Co-Authored-By: Matthew Kassawara <mkassawara@gmail.com> Co-Authored-By: Miguel Angel Ajo <majopela@redhat.com> Co-Authored-By: Murali Rangachari <muralirdev@gmail.com> Co-Authored-By: Numan Siddique <nusiddiq@redhat.com> Co-Authored-By: Reedip <rbanerje@redhat.com> Co-Authored-By: Richard Theis <rtheis@us.ibm.com> Co-Authored-By: Russell Bryant <rbryant@redhat.com> Co-Authored-By: Ryan Moats <rmoats@us.ibm.com> Co-Authored-By: Simon Pasquier <spasquier@mirantis.com> Co-Authored-By: Terry Wilson <twilson@redhat.com> Co-Authored-By: Tong Li <litong01@us.ibm.com> Co-Authored-By: Yunxiang Tao <taoyunxiang@cmss.chinamobile.com> Co-Authored-By: Yushiro FURUKAWA <y.furukawa_2@jp.fujitsu.com> Co-Authored-By: chen-li <shchenli@cn.ibm.com> Co-Authored-By: gong yong sheng <gong.yongsheng@99cloud.net> Co-Authored-By: lidong <lidongbj@inspur.com> Co-Authored-By: lzklibj <lzklibj@cn.ibm.com> Co-Authored-By: melissaml <ma.lei@99cloud.net> Co-Authored-By: pengyuesheng <pengyuesheng@gohighsec.com> Co-Authored-By: reedip <rbanerje@redhat.com> Co-Authored-By: venkata anil <anilvenkata@redhat.com> Co-Authored-By: xurong00037997 <xu.rong@zte.com.cn> Co-Authored-By: zhangdebo <zhangdebo@inspur.com> Co-Authored-By: zhangyanxian <zhang.yanxian@zte.com.cn> Co-Authored-By: zhangyanxian <zhangyanxianmail@163.com> Change-Id: Ia121ec5146c1d35b3282e44fd1eb98932939ea8c Partially-Implements: blueprint neutron-ovn-merge
16 KiB
OpenStack Metadata API and OVN
Introduction
OpenStack Nova presents a metadata API to VMs similar to what is available on Amazon EC2. Neutron is involved in this process because the source IP address is not enough to uniquely identify the source of a metadata request since networks can have overlapping IP addresses. Neutron is responsible for intercepting metadata API requests and adding HTTP headers which uniquely identify the source of the request before forwarding it to the metadata API server.
The purpose of this document is to propose a design for how to enable this functionality when OVN is used as the backend for OpenStack Neutron.
Neutron and Metadata Today
The following blog post describes how VMs access the metadata API through Neutron today.
https://www.suse.com/communities/blog/vms-get-access-metadata-neutron/
In summary, we run a metadata proxy in either the router namespace or DHCP namespace. The DHCP namespace can be used when there's no router connected to the network. The one downside to the DHCP namespace approach is that it requires pushing a static route to the VM through DHCP so that it knows to route metadata requests to the DHCP server IP address.
- Instance sends a HTTP request for metadata to 169.254.169.254
- This request either hits the router or DHCP namespace depending on the route in the instance
- The metadata proxy service in the namespace adds the following info
to the request:
- Instance IP (X-Forwarded-For header)
- Router or Network-ID (X-Neutron-Network-Id or X-Neutron-Router-Id header)
- The metadata proxy service sends this request to the metadata agent (outside the namespace) via a UNIX domain socket.
- The neutron-metadata-agent service forwards the request to the Nova metadata API service by adding some new headers (instance ID and Tenant ID) to the request [0].
For proper operation, Neutron and Nova must be configured to communicate together with a shared secret. Neutron uses this secret to sign the Instance-ID header of the metadata request to prevent spoofing. This secret is configured through metadata_proxy_shared_secret on both nova and neutron configuration files (optional).
Neutron and Metadata with OVN
The current metadata API approach does not translate directly to OVN. There are no Neutron agents in use with OVN. Further, OVN makes no use of its own network namespaces that we could take advantage of like the original implementation makes use of the router and dhcp namespaces.
We must use a modified approach that fits the OVN model. This section details a proposed approach.
Overview of Proposed Approach
The proposed approach would be similar to the isolated network case in the current ML2+OVS implementation. Therefore, we would be running a metadata proxy (haproxy) instance on every hypervisor for each network a VM on that host is connected to.
The downside of this approach is that we'll be running more metadata proxies than we're doing now in case of routed networks (one per virtual router) but since haproxy is very lightweight and they will be idling most of the time, it shouldn't be a big issue overall. However, the major benefit of this approach is that we don't have to implement any scheduling logic to distribute metadata proxies across the nodes, nor any HA logic. This, however, can be evolved in the future as explained below in this document.
Also, this approach relies on a new feature in OVN that we must implement first so that an OVN port can be present on every chassis (similar to localnet ports). This new type of logical port would be localport and we will never forward packets over a tunnel for these ports. We would only send packets to the local instance of a localport.
Step 1 - Create a port for the metadata proxy
When using the DHCP agent today, Neutron automatically creates a port for the DHCP agent to use. We could do the same thing for use with the metadata proxy (haproxy). We'll create an OVN localport which will be present on every chassis and this port will have the same MAC/IP address on every host. Eventually, we can share the same neutron port for both DHCP and metadata.
Step 2 - Routing metadata API requests to the correct Neutron port
This works similarly to the current approach.
We would program OVN to include a static route in DHCP responses that routes metadata API requests to the localport that is hosting the metadata API proxy.
Also, in case DHCP isn't enabled or the client ignores the route info, we will program a static route in the OVN logical router which will still get metadata requests directed to the right place.
If the DHCP route does not work and the network is isolated, VMs won't get metadata, but this already happens with the current implementation so this approach doesn't introduce a regression.
Step 3 - Management of the namespaces and haproxy instances
We propose a new agent called
neutron-ovn-metadata-agent
. We will run this agent on every
hypervisor and it will be responsible for spawning the haproxy instances
for managing the OVS interfaces, network namespaces and haproxy
processes used to proxy metadata API requests.
Step 4 - Metadata API request processing
Similar to the existing neutron metadata agent,
neutron-ovn-metadata-agent
must act as an intermediary
between haproxy and the Nova metadata API service.
neutron-ovn-metadata-agent
is the process that will have
access to the host networks where the Nova metadata API exists. Each
haproxy will be in a network namespace not able to reach the appropriate
host network. Haproxy will add the necessary headers to the metadata API
request and then forward it to neutron-ovn-metadata-agent
over a UNIX domain socket, which matches the behavior of the current
metadata agent.
Metadata Proxy Management Logic
In neutron-ovn-metadata-agent.
- On startup:
- Do a full sync. Ensure we have all the required metadata proxies
running. For that, the agent would watch the
Port_Binding
table of the OVN Southbound database and look for all rows with thechassis
column set to the host the agent is running on. For all those entries, make sure a metadata proxy instance is spawned for everydatapath
(Neutron network) those ports are attached to. The agent will keep record of the list of networks it currently has proxies running on by updating theexternal-ids
keyneutron-metadata-proxy-networks
of the OVNChassis
record in the OVN Southbound database that corresponds to this host. As an example, this key would look likeneutron-metadata-proxy-networks=NET1_UUID,NET4_UUID
meaning that this chassis is hosting one or more VM's connected to networks 1 and 4 so we should have a metadata proxy instance running for each. Ensure any running metadata proxies no longer needed are torn down.
- Do a full sync. Ensure we have all the required metadata proxies
running. For that, the agent would watch the
- Open and maintain a connection to the OVN Northbound database (using
the ovsdbapp library). On first connection, and anytime a reconnect
happens:
- Do a full sync.
- Register a callback for creates/updates/deletes to
Logical_Switch_Port rows to detect when metadata proxies should be
started or torn down.
neutron-ovn-metadata-agent
will watch OVN Southbound database (Port_Binding
table) to detect when a port gets bound to its chassis. At that point, the agent will make sure that there's a metadata proxy attached to the OVN localport for the network which this port is connected to. - When a new network is created, we must create an OVN
localport for use as a metadata proxy. This port will be owned
by
network:dhcp
so that it gets auto deleted upon the removal of the network and it will remainDOWN
and not bound to any chassis. The metadata port will be created regardless of the DHCP setting of the subnets within the network as long as the metadata service is enabled. - When a network is deleted, we must tear down the metadata proxy
instance (if present) on the host and delete the corresponding OVN
localport (which will happen automatically as it's owned by
network:dhcp
).
Launching a metadata proxy includes:
Creating a network namespace:
$ sudo ip netns add <ns-name>
Creating a VETH pair (OVS upgrades that upgrade the kernel module will make internal ports go away and then brought back by OVS scripts. This may cause some disruption. Therefore, veth pairs are preferred over internal ports):
$ sudo ip link add <iface-name>0 type veth peer name <iface-name>1
Creating an OVS interface and placing one end in that namespace:
$ sudo ovs-vsctl add-port br-int <iface-name>0 $ sudo ip link set <iface-name>1 netns <ns-name>
Setting the IP and MAC addresses on that interface:
$ sudo ip netns exec <ns-name> \ > ip link set <iface-name>1 address <neutron-port-mac> $ sudo ip netns exec <ns-name> \ > ip addr add <neutron-port-ip>/<netmask> dev <iface-name>1
Bringing the VETH pair up:
$ sudo ip netns exec <ns-name> ip link set <iface-name>1 up $ sudo ip link set <iface-name>0 up
Set
external-ids:iface-id=NEUTRON_PORT_UUID
on the OVS interface so that OVN is able to correlate this new OVS interface with the correct OVN logical port:$ sudo ovs-vsctl set Interface <iface-name>0 external_ids:iface-id=<neutron-port-uuid>
Starting haproxy in this network namespace.
Add the network UUID to
external-ids:neutron-metadata-proxy-networks
on the Chassis table for our chassis in OVN Southbound database.
Tearing down a metadata proxy includes:
- Removing the network UUID from our chassis.
- Stopping haproxy.
- Deleting the OVS interface.
- Deleting the network namespace.
Other considerations
This feature will be enabled by default when using ovn
driver, but there should be a way to disable it in case operators who
don't need metadata don't have to deal with the complexity of it
(haproxy instances, network namespaces, etcetera). In this case, the
agent would not create the neutron ports needed for metadata.
There could be a race condition when the first VM for a certain network boots on a hypervisor if it does so before the metadata proxy instance has been spawned.
Right now, the vif-plugged
event to Nova is sent out
when the up column in the OVN Northbound database's Logical_Switch_Port
table changes to True, indicating that the VIF is now up. To overcome
this race condition we want to wait until all network UUID's to which
this VM is connected to are present in
external-ids:neutron-metadata-proxy-networks
on the Chassis
table for our chassis in OVN Southbound database. This will delay the
event to Nova until the metadata proxy instance is up and running on the
host ensuring the VM will be able to get the metadata on boot.
Alternatives Considered
Alternative 1: Build metadata support into ovn-controller
We've been building some features useful to OpenStack directly into OVN. DHCP and DNS are key examples of things we've replaced by building them into ovn-controller. The metadata API case has some key differences that make this a less attractive solution:
The metadata API is an OpenStack specific feature. DHCP and DNS by contrast are more clearly useful outside of OpenStack. Building metadata API proxy support into ovn-controller means embedding an HTTP and TCP stack into ovn-controller. This is a significant degree of undesired complexity.
This option has been ruled out for these reasons.
Alternative 2: Distributed metadata and High Availability
In this approach, we would spawn a metadata proxy per virtual router or per network (if isolated), thus, improving the number of metadata proxy instances running in the cloud. However, scheduling and HA have to be considered. Also, we wouldn't need the OVN localport implementation.
neutron-ovn-metadata-agent
would run on any host that we
wish to be able to host metadata API proxies. These hosts must also be
running ovn-controller.
Each of these hosts will have a Chassis record in the OVN southbound
database created by ovn-controller. The Chassis table has a column
called external_ids
which can be used for general metadata
however we see fit. neutron-ovn-metadata-agent
will update
its corresponding Chassis record with an external-id of
neutron-metadata-proxy-host=true
to indicate that this OVN
chassis is one capable of hosting metadata proxy instances.
Once we have a way to determine hosts capable of hosting metadata API proxies, we can add logic to the ovn ML2 driver that schedules metadata API proxies. This would be triggered by Neutron API requests.
The output of the scheduling process would be setting an
external_ids
key on a Logical_Switch_Port in the OVN
northbound database that corresponds with a metadata proxy. The key
could be something like
neutron-metadata-proxy-chassis=CHASSIS_HOSTNAME
.
neutron-ovn-metadata-agent
on each host would also be
watching for updates to these Logical_Switch_Port rows. When it detects
that a metadata proxy has been scheduled locally, it will kick off the
process to spawn the local haproxy instance and get it plugged into
OVN.
HA must also be considered. We must know when a host goes down so that all metadata proxies scheduled to that host can be rescheduled. This is almost the exact same problem we have with L3 HA. When a host goes down, we need to trigger rescheduling gateways to other hosts. We should ensure that the approach used for rescheduling L3 gateways can be utilized for rescheduling metadata proxies, as well.
In neutron-server (ovn mechanism driver) .
Introduce a new ovn driver configuration option:
[ovn] isolated_metadata=[True|False]
Events that trigger scheduling a new metadata proxy:
- If isolated_metadata is True
- When a new network is created, we must create an OVN logical port
for use as a metadata proxy and then schedule this to one of the
neutron-ovn-metadata-agent
instances.
- When a new network is created, we must create an OVN logical port
for use as a metadata proxy and then schedule this to one of the
- If isolated_metadata is False
- When a network is attached to or removed from a logical router, ensure that at least one of the networks has a metadata proxy port already created. If not, pick a network and create a metadata proxy port and then schedule it to an agent. At this point, we need to update the static route for metadata API.
Events that trigger unscheduling an existing metadata proxy:
- When a network is deleted, delete the metadata proxy port if it
exists and unschedule it from a
neutron-ovn-metadata-agent
.
To schedule a new metadata proxy:
- Determine the list of available OVN Chassis that can host metadata
proxies by reading the
Chassis
table of the OVN Southbound database. Look for chassis that have an external-id ofneutron-metadata-proxy-host=true
. - Of the available OVN chassis, choose the one "least loaded", or currently hosting the fewest number of metadata proxies.
- Set
neutron-metadata-proxy-chassis=CHASSIS_HOSTNAME
as an external-id on the Logical_Switch_Port in the OVN Northbound database that corresponds to the neutron port used for this metadata proxy.CHASSIS_HOSTNAME
maps to the hostname row of a Chassis record in the OVN Southbound database.
This approach has been ruled out for its complexity although we have analyzed the details deeply because, eventually, and depending on the implementation of L3 HA, we will want to evolve to it.