From 00ca87fec3b59d24665c7db5886647ea9b2ca114 Mon Sep 17 00:00:00 2001 From: Pete Vander Giessen Date: Wed, 27 Feb 2019 17:04:19 +0100 Subject: [PATCH] Added gc_threshold overrides to sysctl.conf When clouds have a large number of hosts, the default size of the ARP cache is too small. The cache can overflow, which means that the system has no way to reach some ip addresses. Setting the threshold limits higher addresses the situation, in a reasonably safe way (the maximum impact is 5MB or so of additional RAM used). Docs on ARP at http://man7.org/linux/man-pages/man7/arp.7.html, and more discussion of the issue in the bug. Change-Id: I329ec51eff85a2a99a929c67ff0c68b3b36d7273 Closes-Bug: 1780348 --- config.yaml | 14 ++++++++++++++ hooks/neutron_ovs_hooks.py | 7 +++++++ unit_tests/test_neutron_ovs_hooks.py | 11 +++++++++++ unit_tests/test_neutron_ovs_utils.py | 4 ++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/config.yaml b/config.yaml index b9acbfec..90465e5b 100644 --- a/config.yaml +++ b/config.yaml @@ -295,3 +295,17 @@ options: be scheduled without a requirement for a dedicated network node to host centralized SNAT. This is especially important if only floating IPs are used in the network design and SNAT traffic is minimal or non-existent. + sysctl: + type: string + default: | + { net.ipv4.neigh.default.gc_thresh1 : 128, + net.ipv4.neigh.default.gc_thresh2 : 28672, + net.ipv4.neigh.default.gc_thresh3 : 32768, + net.ipv6.neigh.default.gc_thresh1 : 128, + net.ipv6.neigh.default.gc_thresh2 : 28672, + net.ipv6.neigh.default.gc_thresh3 : 32768, + net.nf_conntrack_max : 1000000, + net.netfilter.nf_conntrack_max : 1000000 } + description: | + YAML-formatted associative array of sysctl key/value pairs to be set + persistently e.g. '{ kernel.pid_max : 4194303 }'. diff --git a/hooks/neutron_ovs_hooks.py b/hooks/neutron_ovs_hooks.py index 7b97f46a..0d28d8e9 100755 --- a/hooks/neutron_ovs_hooks.py +++ b/hooks/neutron_ovs_hooks.py @@ -37,6 +37,8 @@ from charmhelpers.core.hookenv import ( relation_ids, ) +from charmhelpers.core.sysctl import create as create_sysctl + from neutron_ovs_utils import ( DHCP_PACKAGES, DVR_PACKAGES, @@ -117,6 +119,11 @@ def config_changed(): purge_packages(packages_to_purge) request_nova_compute_restart = True + sysctl_settings = config('sysctl') + if sysctl_settings: + create_sysctl(sysctl_settings, + '/etc/sysctl.d/50-openvswitch.conf') + configure_ovs() CONFIGS.write_all() # NOTE(fnordahl): configure_sriov must be run after CONFIGS.write_all() diff --git a/unit_tests/test_neutron_ovs_hooks.py b/unit_tests/test_neutron_ovs_hooks.py index c3b5bf94..c88b927f 100644 --- a/unit_tests/test_neutron_ovs_hooks.py +++ b/unit_tests/test_neutron_ovs_hooks.py @@ -32,6 +32,7 @@ utils.register_configs = _reg utils.restart_map = _map TO_PATCH = [ + 'create_sysctl', 'config', 'CONFIGS', 'get_shared_secret', @@ -111,6 +112,16 @@ class NeutronOVSHooksTests(CharmTestCase): self.assertTrue(self.CONFIGS.write_all.called) self.configure_ovs.assert_called_with() + def test_config_changed_sysctl_overrides(self): + self.test_config.set( + 'sysctl', + '{foo : bar}' + ) + self._call_hook('config-changed') + self.create_sysctl.assert_called_with( + '{foo : bar}', + '/etc/sysctl.d/50-openvswitch.conf') + @patch.object(hooks, 'neutron_plugin_joined') def test_config_changed_rocky_upgrade(self, _plugin_joined): self.determine_purge_packages.return_value = ['python-neutron'] diff --git a/unit_tests/test_neutron_ovs_utils.py b/unit_tests/test_neutron_ovs_utils.py index 6ef9a7b0..5f94d271 100644 --- a/unit_tests/test_neutron_ovs_utils.py +++ b/unit_tests/test_neutron_ovs_utils.py @@ -496,13 +496,13 @@ class TestNeutronOVSUtils(CharmTestCase): ML2CONF = "/etc/neutron/plugins/ml2/openvswitch_agent.ini" _restart_map = nutils.restart_map() expect = OrderedDict([ - (ML2CONF, ['neutron-openvswitch-agent']), (nutils.NEUTRON_CONF, ['neutron-openvswitch-agent']), + (ML2CONF, ['neutron-openvswitch-agent']), ]) - self.assertEqual(expect, OrderedDict(_restart_map)) for item in _restart_map: self.assertTrue(item in _restart_map) self.assertTrue(expect[item] == _restart_map[item]) + self.assertEqual(len(_restart_map.keys()), 2) @patch.object(nutils, 'use_dvr') @patch('charmhelpers.contrib.openstack.context.config')