Skip to content

Commit

Permalink
Allow skip processing exposed ports
Browse files Browse the repository at this point in the history
The endpoints 'network_driver_program_external_connectivity'
and 'network_driver_revoke_external_connectivity' will dynamically
create security group and security group rules to open the ports
exposed by the docker container. However, such processing invokes
too much neutron API calls thus significantly slowing down the
container start/stop. However, such processing is not mandatory
because users can manually configure the SGs to achieve the
equivalent.

This patch make the processing of exposed ports configurable.
As a result, it can be disabled if users want a better performance.

Change-Id: I6d6d176512e6b30bb7372408aec1a7bac12335ab
  • Loading branch information
hongbin committed Apr 22, 2018
1 parent bf529e0 commit 17db307
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 0 deletions.
1 change: 1 addition & 0 deletions devstack/plugin.sh
Expand Up @@ -59,6 +59,7 @@ function configure_kuryr {
configure_auth_token_middleware "$KURYR_CONFIG" kuryr \
"$KURYR_AUTH_CACHE_DIR" neutron
iniset $KURYR_CONFIG DEFAULT capability_scope $KURYR_CAPABILITY_SCOPE
iniset $KURYR_CONFIG DEFAULT process_external_connectivity $KURYR_PROCESS_EXTERNAL_CONNECTIVITY
fi

if [[ "$ENABLE_PLUGINV2" == "True" ]]; then
Expand Down
1 change: 1 addition & 0 deletions devstack/settings
Expand Up @@ -20,6 +20,7 @@ KURYR_POOL_PREFIX=${KURYR_POOL_PREFIX:-10.10.0.0/16}
KURYR_POOL_PREFIX_LEN=${KURYR_POOL_PREFIX_LEN:-24}

KURYR_CAPABILITY_SCOPE=${KURYR_CAPABILITY_SCOPE:-local}
KURYR_PROCESS_EXTERNAL_CONNECTIVITY=${KURYR_PROCESS_EXTERNAL_CONNECTIVITY:-True}

KURYR_DOCKER_ENGINE_PORT=${KURYR_DOCKER_ENGINE_PORT:-2375}
DOCKER_CLUSTER_STORE=${DOCKER_CLUSTER_STORE:-etcd://$SERVICE_HOST:$ETCD_PORT}
Expand Down
3 changes: 3 additions & 0 deletions kuryr_libnetwork/config.py
Expand Up @@ -52,6 +52,9 @@
cfg.ListOpt('enabled_port_drivers',
default=['kuryr_libnetwork.port_driver.drivers.veth'],
help=_('Available port drivers')),
cfg.BoolOpt('process_external_connectivity',
default=True,
help=_('Do processing external connectivity')),
cfg.StrOpt('ssl_cert_file',
default='/var/lib/kuryr/certs/cert.pem',
help=_('This option allows setting absolute path'
Expand Down
6 changes: 6 additions & 0 deletions kuryr_libnetwork/controllers.py
Expand Up @@ -1437,6 +1437,9 @@ def network_driver_program_external_connectivity():
json_data = flask.request.get_json(force=True)
LOG.debug("Received JSON data %s for"
" /NetworkDriver.ProgramExternalConnectivity", json_data)
if not cfg.CONF.process_external_connectivity:
return flask.jsonify(const.SCHEMA['SUCCESS'])

# TODO(banix): Add support for exposed ports
port = _get_neutron_port_from_docker_endpoint(json_data['EndpointID'])
if port:
Expand All @@ -1459,6 +1462,9 @@ def network_driver_revoke_external_connectivity():
json_data = flask.request.get_json(force=True)
LOG.debug("Received JSON data %s for"
" /NetworkDriver.RevokeExternalConnectivity", json_data)
if not cfg.CONF.process_external_connectivity:
return flask.jsonify(const.SCHEMA['SUCCESS'])

# TODO(banix): Add support for removal of exposed ports
port = _get_neutron_port_from_docker_endpoint(json_data['EndpointID'])
if port:
Expand Down
83 changes: 83 additions & 0 deletions kuryr_libnetwork/tests/unit/test_external_connectivity.py
Expand Up @@ -21,6 +21,7 @@

from kuryr.lib import constants as lib_const
from kuryr.lib import utils as lib_utils
from kuryr_libnetwork import config
from kuryr_libnetwork import constants
from kuryr_libnetwork.tests.unit import base
from kuryr_libnetwork import utils
Expand Down Expand Up @@ -55,6 +56,7 @@ def test_network_driver_program_external_connectivity(self, existing_sg,
num_ports, mock_list_ports, mock_create_security_group,
mock_create_security_group_rule, mock_show_port,
mock_update_port):
config.CONF.set_override('process_external_connectivity', True)
fake_docker_net_id = lib_utils.get_hash()
fake_docker_endpoint_id = lib_utils.get_hash()

Expand Down Expand Up @@ -142,6 +144,51 @@ def test_network_driver_program_external_connectivity(self, existing_sg,
decoded_json = jsonutils.loads(response.data)
self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)

@mock.patch('kuryr_libnetwork.controllers.app.neutron.update_port')
@mock.patch('kuryr_libnetwork.controllers.app.neutron.show_port')
@mock.patch(
'kuryr_libnetwork.controllers.app.neutron.create_security_group_rule')
@mock.patch(
'kuryr_libnetwork.controllers.app.neutron.create_security_group')
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_ports')
@ddt.data((False, 1), (True, 1), (False, 2), (True, 2))
@ddt.unpack
def test_network_driver_program_external_connectivity_disabled(
self, existing_sg,
num_ports, mock_list_ports, mock_create_security_group,
mock_create_security_group_rule, mock_show_port,
mock_update_port):
config.CONF.set_override('process_external_connectivity', False)
fake_docker_net_id = lib_utils.get_hash()
fake_docker_endpoint_id = lib_utils.get_hash()

port_opt = []
for i in range(num_ports):
port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL_TCP})
port_opt.append({u'Port': PORT + i, u'Proto': PROTOCOL_UDP})
port_opt.append({u'Port': SINGLE_PORT, u'Proto': PROTOCOL_UDP})
options = {'com.docker.network.endpoint.exposedports':
port_opt,
'com.docker.network.portmap':
[]}
data = {
'NetworkID': fake_docker_net_id,
'EndpointID': fake_docker_endpoint_id,
'Options': options,
}
response = self.app.post('/NetworkDriver.ProgramExternalConnectivity',
content_type='application/json',
data=jsonutils.dumps(data))

self.assertEqual(200, response.status_code)
mock_update_port.assert_not_called()
mock_show_port.assert_not_called()
mock_create_security_group_rule.assert_not_called()
mock_create_security_group.assert_not_called()
mock_list_ports.assert_not_called()
decoded_json = jsonutils.loads(response.data)
self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)

@mock.patch('kuryr_libnetwork.controllers.app.neutron.update_port')
@mock.patch('kuryr_libnetwork.controllers.app.neutron.show_port')
@mock.patch(
Expand All @@ -155,6 +202,7 @@ def test_network_driver_revoke_external_connectivity(self, existing_sg,
removing_sg, mock_list_ports, mock_list_security_groups,
mock_delete_security_groups, mock_show_port,
mock_update_port):
config.CONF.set_override('process_external_connectivity', True)
fake_docker_net_id = lib_utils.get_hash()
fake_docker_endpoint_id = lib_utils.get_hash()

Expand Down Expand Up @@ -219,3 +267,38 @@ def test_network_driver_revoke_external_connectivity(self, existing_sg,
mock_update_port.assert_not_called()
decoded_json = jsonutils.loads(response.data)
self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)

@mock.patch('kuryr_libnetwork.controllers.app.neutron.update_port')
@mock.patch('kuryr_libnetwork.controllers.app.neutron.show_port')
@mock.patch(
'kuryr_libnetwork.controllers.app.neutron.delete_security_group')
@mock.patch(
'kuryr_libnetwork.controllers.app.neutron.list_security_groups')
@mock.patch('kuryr_libnetwork.controllers.app.neutron.list_ports')
@ddt.data((False, False), (False, True), (True, False), (True, True))
@ddt.unpack
def test_network_driver_revoke_external_connectivity_disabled(
self, existing_sg,
removing_sg, mock_list_ports, mock_list_security_groups,
mock_delete_security_groups, mock_show_port,
mock_update_port):
config.CONF.set_override('process_external_connectivity', False)
fake_docker_net_id = lib_utils.get_hash()
fake_docker_endpoint_id = lib_utils.get_hash()

data = {
'NetworkID': fake_docker_net_id,
'EndpointID': fake_docker_endpoint_id,
}
response = self.app.post('/NetworkDriver.RevokeExternalConnectivity',
content_type='application/json',
data=jsonutils.dumps(data))

self.assertEqual(200, response.status_code)
mock_list_ports.assert_not_called()
mock_list_security_groups.assert_not_called()
mock_delete_security_groups.assert_not_called()
mock_show_port.assert_not_called()
mock_update_port.assert_not_called()
decoded_json = jsonutils.loads(response.data)
self.assertEqual(constants.SCHEMA['SUCCESS'], decoded_json)

0 comments on commit 17db307

Please sign in to comment.