From 50fdc6505f22758e6d0d4ccf01b3c13ca2a93153 Mon Sep 17 00:00:00 2001 From: LIU Yulong Date: Fri, 19 Aug 2016 10:16:44 +0800 Subject: [PATCH] DVR: Ignore DHCP port during DVR host query For large scale deployment, the dvr router will be installed to the scheduled DHCP host. This will definitely increase the l3 agent service pressure, especially in large number of concurrent updates, creation, or agent restart. This patch adds a config ``host_dvr_for_dhcp`` for the DHCP port device_owner filter during DVR host query. Then if we set ``host_dvr_for_dhcp = False``, L3-agent will not host the DVR router namespace in its connected networks' DHCP agent hosts. Closes-Bug: #1609217 Change-Id: I53e20be9b306bf9d3b34ec6a31e3afabd5a0fd6f (cherry picked from commit 8f057fb49ac637bd0dbf60ca07b89f0e4a59c7b7) --- doc/source/admin/deploy-ovs-ha-dvr.rst | 9 +++++++++ neutron/common/utils.py | 10 ++++++---- neutron/conf/db/l3_dvr_db.py | 6 ++++++ neutron/db/dvr_mac_db.py | 5 ++++- neutron/db/l3_dvrscheduler_db.py | 13 +++++++++---- .../config-host_dvr_for_dhcp-f949aca5bd666e24.yaml | 6 ++++++ 6 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/config-host_dvr_for_dhcp-f949aca5bd666e24.yaml diff --git a/doc/source/admin/deploy-ovs-ha-dvr.rst b/doc/source/admin/deploy-ovs-ha-dvr.rst index dc748456b78..39ae8ccbfe2 100644 --- a/doc/source/admin/deploy-ovs-ha-dvr.rst +++ b/doc/source/admin/deploy-ovs-ha-dvr.rst @@ -75,6 +75,15 @@ Controller node [DEFAULT] 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: * Server diff --git a/neutron/common/utils.py b/neutron/common/utils.py index 396f398d354..6d8d64b48e9 100644 --- a/neutron/common/utils.py +++ b/neutron/common/utils.py @@ -162,16 +162,18 @@ class exception_logger(object): 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 This doesn't return DEVICE_OWNER_COMPUTE_PREFIX since it is a prefix, not a complete device_owner name, so should be handled separately (see is_dvr_serviced() below) """ - return [n_const.DEVICE_OWNER_LOADBALANCER, - n_const.DEVICE_OWNER_LOADBALANCERV2, - n_const.DEVICE_OWNER_DHCP] + device_owners = [n_const.DEVICE_OWNER_LOADBALANCER, + n_const.DEVICE_OWNER_LOADBALANCERV2] + if host_dvr_for_dhcp: + device_owners.append(n_const.DEVICE_OWNER_DHCP) + return device_owners def get_dvr_allowed_address_pair_device_owners(): diff --git a/neutron/conf/db/l3_dvr_db.py b/neutron/conf/db/l3_dvr_db.py index 36ccd5d91d8..5b7f7027cc4 100644 --- a/neutron/conf/db/l3_dvr_db.py +++ b/neutron/conf/db/l3_dvr_db.py @@ -25,6 +25,12 @@ ROUTER_DISTRIBUTED_OPTS = [ default=True, help=_("Determine if setup is configured for DVR. If False, " "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.")), ] diff --git a/neutron/db/dvr_mac_db.py b/neutron/db/dvr_mac_db.py index 71c502700e7..412e28e4aae 100644 --- a/neutron/db/dvr_mac_db.py +++ b/neutron/db/dvr_mac_db.py @@ -33,6 +33,7 @@ from sqlalchemy import or_ from neutron.common import utils from neutron.conf.db import dvr_mac_db +from neutron.conf.db import l3_dvr_db from neutron.db import models_v2 from neutron.extensions import dvr as ext_dvr from neutron.objects import router @@ -42,6 +43,7 @@ LOG = logging.getLogger(__name__) dvr_mac_db.register_db_dvr_mac_opts() +l3_dvr_db.register_db_l3_dvr_opts() @registry.has_registry_receivers @@ -151,6 +153,7 @@ class DVRDbMixin(ext_dvr.DVRMacAddressPluginBase): :param subnet: subnet id to match and extract ports of interest :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]}, portbindings.HOST_ID: [host]} 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( constants.DEVICE_OWNER_COMPUTE_PREFIX), 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 = [ self.plugin._make_port_dict(port, process_extensions=False) diff --git a/neutron/db/l3_dvrscheduler_db.py b/neutron/db/l3_dvrscheduler_db.py index cdf88cb9bea..99aaa499b7e 100644 --- a/neutron/db/l3_dvrscheduler_db.py +++ b/neutron/db/l3_dvrscheduler_db.py @@ -22,11 +22,12 @@ from neutron_lib import constants as n_const from neutron_lib.exceptions import l3 as l3_exc from neutron_lib.plugins import constants as plugin_constants from neutron_lib.plugins import directory +from oslo_config import cfg from oslo_log import log as logging from sqlalchemy import or_ 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 l3_agentschedulers_db as l3agent_sch_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 LOG = logging.getLogger(__name__) +l3_dvr_db_conf.register_db_l3_dvr_opts() 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): """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 Port = models_v2.Port IPAllocation = models_v2.IPAllocation @@ -345,12 +348,13 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin): owner_filter = or_( Port.device_owner.startswith(n_const.DEVICE_OWNER_COMPUTE_PREFIX), 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) hosts = [item[0] for item in query if item[0] != ''] return hosts def _get_dvr_subnet_ids_on_host_query(self, context, host): + host_dvr_dhcp = cfg.CONF.host_dvr_for_dhcp query = context.session.query( models_v2.IPAllocation.subnet_id).distinct() 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( n_const.DEVICE_OWNER_COMPUTE_PREFIX), 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) return query @@ -458,6 +462,7 @@ class L3_DVRsch_db_mixin(l3agent_sch_db.L3AgentSchedulerDbMixin): IPAllocation = models_v2.IPAllocation Port = models_v2.Port + host_dvr_dhcp = cfg.CONF.host_dvr_for_dhcp query = context.session.query(Binding) query = query.join(Binding.port) 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( n_const.DEVICE_OWNER_COMPUTE_PREFIX), 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) host_filter = or_( ml2_models.PortBinding.host == host, diff --git a/releasenotes/notes/config-host_dvr_for_dhcp-f949aca5bd666e24.yaml b/releasenotes/notes/config-host_dvr_for_dhcp-f949aca5bd666e24.yaml new file mode 100644 index 00000000000..5ea144801e1 --- /dev/null +++ b/releasenotes/notes/config-host_dvr_for_dhcp-f949aca5bd666e24.yaml @@ -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).