Add spec for VPNaaS for OVN
Adding the spec to support VPNaaS for OVN for the RFE https://bugs.launchpad.net/neutron/+bug/1905391 Related-Bug: #1905391 Change-Id: If14135d42459296158a09641c880768994a1c9ac
This commit is contained in:
parent
ab24bc0620
commit
aa641b223f
224
specs/xena/vpnaas-ovn.rst
Normal file
224
specs/xena/vpnaas-ovn.rst
Normal file
@ -0,0 +1,224 @@
|
||||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
=========================
|
||||
VPNaaS for OVN Networking
|
||||
=========================
|
||||
|
||||
This specification covers the support for VPNaaS with OVN networking by adding
|
||||
a stand-alone VPN agent. This new agent will create a namespace on the node,
|
||||
connect it with the OVN distributed logical router and run the Swan process in
|
||||
the namespace.
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
The existing VPNaaS service plugin only supports the reference Neutron software
|
||||
routers, such as neutron L3 router using the L3 agent. This approach does not
|
||||
work if there is no L3 agent. For OVN a different solution is required.
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
Add a new stand-alone VPN agent to support OVN+VPN. Add OVN-specific service
|
||||
and device drivers that support this new VPN agent. This will have no impact
|
||||
on the existing VPN solution, the existing L3 agent and its VPN extension will
|
||||
still work.
|
||||
|
||||
Changes on neutron server
|
||||
-------------------------
|
||||
|
||||
VPN service driver and Agent scheduler
|
||||
++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
The VPN service driver has different implementations for different VPNaaS
|
||||
solutions. The existing implementation relies on the Neutron L3 router
|
||||
scheduler to decide where the VPN service process is hosted and the VPN device
|
||||
driver is part of the L3 agent. In OVN the L3 router scheduler and L3 agents
|
||||
are not used anymore, so a replacement is required.
|
||||
|
||||
For the newly-introduced agent type "VPN agent"
|
||||
we also add a corresponding VPN agent scheduler. Using the OVN-related
|
||||
scheduler for the router gateway port was ruled out because the VPN agent
|
||||
scheduler should also keep track whether the VPN agent(s) are still alive.
|
||||
|
||||
The new VPN agent scheduler will work on a per-router basis to have all IPSec
|
||||
site connections of a router processed by the same agent.
|
||||
|
||||
VPN gateway and transit network
|
||||
+++++++++++++++++++++++++++++++
|
||||
|
||||
In the existing implementation for ML2/OVS the VPNaaS shares the router gateway
|
||||
IP address with router SNAT, but for OVN the gateway public IP address (SNAT)
|
||||
can't be shared with the VPN because SNAT is not in the namespace context.
|
||||
A new public IP address is needed for the VPNaaS namespace, so a VPN gateway
|
||||
port is created in the external network of the router. This address will be
|
||||
visible as the external_v4_ip/external_v6_ip of the VPN service.
|
||||
|
||||
To connect the router with the namespace a "Transit network" (169.254.0.0/30)
|
||||
is created and attached to the router. It is used to route traffic between
|
||||
virtual machine network(s) and the VPN process namespace. The respective routes
|
||||
added to the router are (per peer CIDR):
|
||||
|
||||
- destination CIDR: peer CIDR
|
||||
- next hop: IP address of a port in the transit network (169.254.0.2)
|
||||
|
||||
The new ports and the transit network and subnet are managed using the API of
|
||||
the Neutron core plugin and OVN L3 router service plugin, not "under the hood"
|
||||
with OVN functions, to avoid inconsistencies between the Neutron database and
|
||||
OVN Northbound. This makes sure that scripts that sync Neutron DB and OVN
|
||||
Northbound (like neutron-ovn-db-sync-util) don't delete lswitches that
|
||||
were created for the VPNaaS transit network but have no corresponding Neutron
|
||||
DB entries.
|
||||
|
||||
The IDs of the newly added ports, transit network and subnet are stored in a
|
||||
new database table "vpn_ext_gws" (for VPN external gateways).
|
||||
The gateway port and transit network are created automatically when the first
|
||||
VPN service of a router is created and are deleted after the last VPN service
|
||||
of the router is removed.
|
||||
|
||||
Naming of Neutron objects
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
- External gateway port for VPN: "vpn-gw-{router_id}" (with device owner
|
||||
"network:vpn_router_gateway", device ID is the router ID)
|
||||
|
||||
- VPN transit network: "vpn-transit-network-{router_id}"
|
||||
|
||||
- VPN transit subnet: "vpn-transit-subnet-{router_id}"
|
||||
|
||||
- Port in the VPN transit network, to be plugged by the agent in the VPN
|
||||
namespace: "vpn-ns-{router_id}" (with device owner "network:vpn_namespace",
|
||||
device ID is the transit subnet ID)
|
||||
|
||||
Changes on VPN agent
|
||||
--------------------
|
||||
|
||||
For OVN the VPN functionality is implemented in a new dedicated VPN agent using
|
||||
new OVN specific device drivers.
|
||||
|
||||
Configuration synchronization
|
||||
+++++++++++++++++++++++++++++
|
||||
|
||||
The existing VPNaaS implementation uses rabbitmq RPCs to synchronize the VPN
|
||||
configuration between the database and the IKE daemon (strongswan etc)
|
||||
controlled by the agent.
|
||||
|
||||
Ideally a VPNaaS solution for OVN would avoid rabbitmq. But currently there
|
||||
is no support for configuring VPNs in OVN (via north/southbound databases).
|
||||
While it is possible to configure IPSec for tunnel ports, it's not possible
|
||||
to set up and configure IPSec site connections to external peers.
|
||||
|
||||
To still be able to offer VPNaaS some other means than configuration via
|
||||
OVN north/southbound tables is necessary. Possible solutions could be:
|
||||
|
||||
1. Use rabbitmq RPCs as in the existing VPNaaS plugin.
|
||||
2. Instead of rabbitmq, implement REST APIs on both ends (neutron server and
|
||||
VPN agent). This includes API endpoints that let the agent know about
|
||||
configuration changes (server -> agent), that allow agents to fetch the
|
||||
current configuration (agent -> server) and that allow agents to report
|
||||
state changes (agent -> server)
|
||||
|
||||
The least complex implementation approach is (1) to rely on existing code
|
||||
even if it is still using rabbitmq instead of rewriting the server/agent
|
||||
communication with new REST APIs.
|
||||
|
||||
VPN namespace management
|
||||
++++++++++++++++++++++++
|
||||
|
||||
The agent creates a VPN namespace and plugs two ports:
|
||||
|
||||
- the external gateway port
|
||||
- a port in the transit network bound to 169.254.0.2
|
||||
|
||||
There will be one VPN namespace per router and it's scheduled on exactly one
|
||||
VPN agent. The VPN agent shall make sure that only those VPN namespaces exist
|
||||
on the node which are scheduled there. I.e. when the agent starts it will
|
||||
synchronize with the controller and potentially delete superfluous VPN
|
||||
namespaces and/or create missing ones.
|
||||
|
||||
VPN namespaces are created by the VPN agent / device driver when the first
|
||||
IPSec site connection of a router is created and are deleted if all IPSec site
|
||||
connections of the router were deleted.
|
||||
|
||||
Routes are configured in the namespace to route incoming traffic to the local
|
||||
subnets (destination: local CIDR, next hop: router port of the transit network,
|
||||
i.e. 169.254.0.1). These routes are updated whenever the IPSec site connection
|
||||
configuration changes.
|
||||
|
||||
The agent will
|
||||
|
||||
1. create a namespace called "qvpn-{router_id}"
|
||||
2. create two interfaces in the namespace:
|
||||
|
||||
- vgxxxxxxxx-xxx, where xxxxxxxx-xxx is the prefix of the port UUID of the
|
||||
VPN external gateway port (IP address in the external network)
|
||||
- vrxxxxxxxx-xxx, where xxxxxxxx-xxx is the prefix of the port UUID of the
|
||||
VPN transit network port (169.254.0.2)
|
||||
|
||||
3. plug the two interfaces
|
||||
4. add routes
|
||||
|
||||
Liveness of the VPN agent
|
||||
+++++++++++++++++++++++++
|
||||
|
||||
There are two ways how liveness checks could be implemented:
|
||||
|
||||
1. Traditional way using rabbitmq. The VPN agent periodically reports its state
|
||||
("report_state" RPC). The server side plugin utilizes the
|
||||
AgentSchedulerDbMixin functionality to keep track of alive agents and will
|
||||
potentially reschedule VPN services if an agent is down.
|
||||
2. Liveness check using OVN similar to OVN Metadata agent. The server sets
|
||||
a new value of the "neutron:liveness_check_at" external_id in NB_Global,
|
||||
the agent monitors SB_Global and will set an external_id in its chassis row
|
||||
(external_id "neutron:ovn-vpnagent-sb-cfg")
|
||||
|
||||
The second approach is more in line with the management of agents in the Neutron
|
||||
OVN mech driver.
|
||||
|
||||
VPN plugin configuration for OVN
|
||||
--------------------------------
|
||||
|
||||
The OVN VPN plugin is an extension of the existing one in order to add the VPN
|
||||
agent scheduler and status checks.
|
||||
|
||||
The service plugin to be added to neutron.conf is
|
||||
neutron_vpnaas.services.vpn.ovn_plugin.VPNOVNDriverPlugin
|
||||
|
||||
For OVN there is a new dedicated service driver, so the service_provider
|
||||
setting in neutron_vpnaas.conf will be:
|
||||
VPN:openswan:neutron_vpnaas.services.vpn.service_drivers.ovn_ipsec.IPsecOvnVPNDriver:default
|
||||
|
||||
There is a new agent type "VPN agent"
|
||||
|
||||
- The agent binary is neutron-vpn-agent
|
||||
- The agent configuration file is /etc/neutron/vpn_agent.ini
|
||||
- The agent uses the VPN device driver configured in vpnagent/vpn_device_driver.
|
||||
An example device driver entry is
|
||||
vpn_device_driver = neutron_vpnaas.services.vpn.device_drivers.ovn_ipsec.OvnStrongSwanDriver
|
||||
|
||||
Database impact
|
||||
---------------
|
||||
|
||||
Two new tables are added to the neutron database:
|
||||
|
||||
- vpn_ext_gws: keeps the IDs of the additional network items needed for VPN
|
||||
services of a router (gateway port, transit network, subnet, port)
|
||||
- routervpnagentbindings: keeps the VPN agent ID per router
|
||||
|
||||
REST API and CLI impact
|
||||
-----------------------
|
||||
|
||||
There are no changes to the REST API or CLI of VPNaaS or Neutron.
|
||||
|
||||
The external IP address of the VPN service is visible in its
|
||||
external_v4_ip/external_v6_ip and will be different than the one of
|
||||
the router.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
* https://bugs.launchpad.net/neutron/+bug/1905391
|
Loading…
x
Reference in New Issue
Block a user