From 4f31acd5658fd7fef97950d534e57e9c3c5e9558 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 ea26fc7e718..4f79ca60bd6 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 ed2e2debcd7..2cb56ad7734 100644 --- a/neutron/common/utils.py +++ b/neutron/common/utils.py @@ -161,16 +161,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 275f5e6fdd8..c21e68cd39b 100644 --- a/neutron/db/dvr_mac_db.py +++ b/neutron/db/dvr_mac_db.py @@ -32,6 +32,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 api as db_api from neutron.db import models_v2 from neutron.extensions import dvr as ext_dvr @@ -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 @@ -145,6 +147,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) @@ -152,7 +155,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 44c1f90f83a..748de4e62aa 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 @@ -455,6 +459,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) @@ -466,7 +471,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).