Merge "DVR: Ignore DHCP port during DVR host query" into stable/stein

This commit is contained in:
Zuul 2020-01-29 03:52:38 +00:00 committed by Gerrit Code Review
commit fc230e2e29
6 changed files with 40 additions and 9 deletions

View File

@ -75,6 +75,15 @@ Controller node
[DEFAULT] [DEFAULT]
router_distributed = True router_distributed = True
.. note::
For a large scale cloud, if your deployment is running DVR with DHCP,
we recommend you set ``host_dvr_for_dhcp=False`` to achieve higher
L3 agent router processing performance. When this is set to False,
DNS functionality will not be available via the DHCP namespace (dnsmasq)
however, a different nameserver will have to be configured, for
example, by specifying a value in ``dns_nameservers`` for subnets.
#. Restart the following services: #. Restart the following services:
* Server * Server

View File

@ -162,16 +162,18 @@ class exception_logger(object):
return call return call
def get_other_dvr_serviced_device_owners(): def get_other_dvr_serviced_device_owners(host_dvr_for_dhcp=True):
"""Return device_owner names for ports that should be serviced by DVR """Return device_owner names for ports that should be serviced by DVR
This doesn't return DEVICE_OWNER_COMPUTE_PREFIX since it is a This doesn't return DEVICE_OWNER_COMPUTE_PREFIX since it is a
prefix, not a complete device_owner name, so should be handled prefix, not a complete device_owner name, so should be handled
separately (see is_dvr_serviced() below) separately (see is_dvr_serviced() below)
""" """
return [n_const.DEVICE_OWNER_LOADBALANCER, device_owners = [n_const.DEVICE_OWNER_LOADBALANCER,
n_const.DEVICE_OWNER_LOADBALANCERV2, n_const.DEVICE_OWNER_LOADBALANCERV2]
n_const.DEVICE_OWNER_DHCP] if host_dvr_for_dhcp:
device_owners.append(n_const.DEVICE_OWNER_DHCP)
return device_owners
def get_dvr_allowed_address_pair_device_owners(): def get_dvr_allowed_address_pair_device_owners():

View File

@ -25,6 +25,12 @@ ROUTER_DISTRIBUTED_OPTS = [
default=True, default=True,
help=_("Determine if setup is configured for DVR. If False, " help=_("Determine if setup is configured for DVR. If False, "
"DVR API extension will be disabled.")), "DVR API extension will be disabled.")),
cfg.BoolOpt('host_dvr_for_dhcp',
default=True,
help=_("Flag to determine if hosting a DVR local router to "
"the DHCP agent is desired. If False, any L3 function "
"supported by the DHCP agent instance will not be "
"possible, for instance: DNS.")),
] ]

View File

@ -33,6 +33,7 @@ from sqlalchemy import or_
from neutron.common import utils from neutron.common import utils
from neutron.conf.db import dvr_mac_db from neutron.conf.db import dvr_mac_db
from neutron.conf.db import l3_dvr_db
from neutron.db import models_v2 from neutron.db import models_v2
from neutron.extensions import dvr as ext_dvr from neutron.extensions import dvr as ext_dvr
from neutron.objects import router from neutron.objects import router
@ -42,6 +43,7 @@ LOG = logging.getLogger(__name__)
dvr_mac_db.register_db_dvr_mac_opts() dvr_mac_db.register_db_dvr_mac_opts()
l3_dvr_db.register_db_l3_dvr_opts()
@registry.has_registry_receivers @registry.has_registry_receivers
@ -151,6 +153,7 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
:param subnet: subnet id to match and extract ports of interest :param subnet: subnet id to match and extract ports of interest
:returns: list -- Ports on the given subnet in the input host :returns: list -- Ports on the given subnet in the input host
""" """
host_dvr_for_dhcp = cfg.CONF.host_dvr_for_dhcp
filters = {'fixed_ips': {'subnet_id': [subnet]}, filters = {'fixed_ips': {'subnet_id': [subnet]},
portbindings.HOST_ID: [host]} portbindings.HOST_ID: [host]}
ports_query = self.plugin._get_ports_query(context, filters=filters) ports_query = self.plugin._get_ports_query(context, filters=filters)
@ -158,7 +161,7 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase):
models_v2.Port.device_owner.startswith( models_v2.Port.device_owner.startswith(
constants.DEVICE_OWNER_COMPUTE_PREFIX), constants.DEVICE_OWNER_COMPUTE_PREFIX),
models_v2.Port.device_owner.in_( models_v2.Port.device_owner.in_(
utils.get_other_dvr_serviced_device_owners())) utils.get_other_dvr_serviced_device_owners(host_dvr_for_dhcp)))
ports_query = ports_query.filter(owner_filter) ports_query = ports_query.filter(owner_filter)
ports = [ ports = [
self.plugin._make_port_dict(port, process_extensions=False) self.plugin._make_port_dict(port, process_extensions=False)

View File

@ -22,11 +22,12 @@ from neutron_lib import constants as n_const
from neutron_lib.exceptions import l3 as l3_exc from neutron_lib.exceptions import l3 as l3_exc
from neutron_lib.plugins import constants as plugin_constants from neutron_lib.plugins import constants as plugin_constants
from neutron_lib.plugins import directory from neutron_lib.plugins import directory
from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from sqlalchemy import or_ from sqlalchemy import or_
from neutron.common import utils as n_utils from neutron.common import utils as n_utils
from neutron.conf.db import l3_dvr_db as l3_dvr_db_conf
from neutron.db import agentschedulers_db from neutron.db import agentschedulers_db
from neutron.db import l3_agentschedulers_db as l3agent_sch_db from neutron.db import l3_agentschedulers_db as l3agent_sch_db
from neutron.db import l3_dvr_db from neutron.db import l3_dvr_db
@ -37,6 +38,7 @@ from neutron.plugins.ml2 import db as ml2_db
from neutron.plugins.ml2 import models as ml2_models from neutron.plugins.ml2 import models as ml2_models
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
l3_dvr_db_conf.register_db_l3_dvr_opts()
class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin): class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
@ -334,6 +336,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
def _get_dvr_hosts_for_subnets(self, context, subnet_ids): def _get_dvr_hosts_for_subnets(self, context, subnet_ids):
"""Get a list of hosts with DVR servicable ports on subnet_ids.""" """Get a list of hosts with DVR servicable ports on subnet_ids."""
host_dvr_dhcp = cfg.CONF.host_dvr_for_dhcp
Binding = ml2_models.PortBinding Binding = ml2_models.PortBinding
Port = models_v2.Port Port = models_v2.Port
IPAllocation = models_v2.IPAllocation IPAllocation = models_v2.IPAllocation
@ -345,12 +348,13 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
owner_filter = or_( owner_filter = or_(
Port.device_owner.startswith(n_const.DEVICE_OWNER_COMPUTE_PREFIX), Port.device_owner.startswith(n_const.DEVICE_OWNER_COMPUTE_PREFIX),
Port.device_owner.in_( Port.device_owner.in_(
n_utils.get_other_dvr_serviced_device_owners())) n_utils.get_other_dvr_serviced_device_owners(host_dvr_dhcp)))
query = query.filter(owner_filter) query = query.filter(owner_filter)
hosts = [item[0] for item in query if item[0] != ''] hosts = [item[0] for item in query if item[0] != '']
return hosts return hosts
def _get_dvr_subnet_ids_on_host_query(self, context, host): def _get_dvr_subnet_ids_on_host_query(self, context, host):
host_dvr_dhcp = cfg.CONF.host_dvr_for_dhcp
query = context.session.query( query = context.session.query(
models_v2.IPAllocation.subnet_id).distinct() models_v2.IPAllocation.subnet_id).distinct()
query = query.join(models_v2.IPAllocation.port) query = query.join(models_v2.IPAllocation.port)
@ -360,7 +364,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
models_v2.Port.device_owner.startswith( models_v2.Port.device_owner.startswith(
n_const.DEVICE_OWNER_COMPUTE_PREFIX), n_const.DEVICE_OWNER_COMPUTE_PREFIX),
models_v2.Port.device_owner.in_( models_v2.Port.device_owner.in_(
n_utils.get_other_dvr_serviced_device_owners())) n_utils.get_other_dvr_serviced_device_owners(host_dvr_dhcp)))
query = query.filter(owner_filter) query = query.filter(owner_filter)
return query return query
@ -458,6 +462,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
IPAllocation = models_v2.IPAllocation IPAllocation = models_v2.IPAllocation
Port = models_v2.Port Port = models_v2.Port
host_dvr_dhcp = cfg.CONF.host_dvr_for_dhcp
query = context.session.query(Binding) query = context.session.query(Binding)
query = query.join(Binding.port) query = query.join(Binding.port)
query = query.join(Port.fixed_ips) query = query.join(Port.fixed_ips)
@ -469,7 +474,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin):
models_v2.Port.device_owner.startswith( models_v2.Port.device_owner.startswith(
n_const.DEVICE_OWNER_COMPUTE_PREFIX), n_const.DEVICE_OWNER_COMPUTE_PREFIX),
models_v2.Port.device_owner.in_( models_v2.Port.device_owner.in_(
n_utils.get_other_dvr_serviced_device_owners())) n_utils.get_other_dvr_serviced_device_owners(host_dvr_dhcp)))
query = query.filter(device_filter) query = query.filter(device_filter)
host_filter = or_( host_filter = or_(
ml2_models.PortBinding.host == host, ml2_models.PortBinding.host == host,

View File

@ -0,0 +1,6 @@
---
other:
- |
A new config option, ``host_dvr_for_dhcp``, was added to neutron.conf
for DVR to determine whether to host the DVR local router to the
scheduled DHCP node(s).