From 6023978ae7b9a7fdc960cb577ec3e1474d5677a8 Mon Sep 17 00:00:00 2001 From: Hongbin Lu Date: Mon, 24 Dec 2018 23:38:39 +0000 Subject: [PATCH] Set binding:host_id on creating/updating port This patch depends on a change on kuryr-libnetwork [1], which skip populating 'binding:host_id' if it is already populated. This commit leverages the kuryr's change and has the 'binding:host_id' filled. This effectively moves a neutron API call from kuryr to zun but it increases the performance since docker daemon are blocked if the slow API call is in kuryr side. [1] https://review.openstack.org/#/c/627198/ Depends-On: https://review.openstack.org/#/c/627198/ Partial-Bug: #1809306 Change-Id: I67563ea069cafab16500bd8ba598743b7ae87fe6 --- zun/container/docker/driver.py | 7 ++++--- zun/network/kuryr_network.py | 16 +++++++++++++--- zun/network/neutron.py | 7 +++++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/zun/container/docker/driver.py b/zun/container/docker/driver.py index 36bd0d2ce..ee8421da5 100644 --- a/zun/container/docker/driver.py +++ b/zun/container/docker/driver.py @@ -379,7 +379,8 @@ class DockerDriver(driver.ContainerDriver): security_group_ids = utils.get_security_group_ids( context, container.security_groups) addresses, port = network_api.create_or_update_port( - container, docker_net_name, requested_network, security_group_ids) + container, docker_net_name, requested_network, security_group_ids, + set_binding_host=True) container.addresses = {requested_network['network']: addresses} ipv4_address = None @@ -1225,8 +1226,8 @@ class DockerDriver(driver.ContainerDriver): network = requested_network['network'] if network in container.addresses: raise exception.ZunException('Container %(container)s has ' - 'alreay connected to the network ' - '%(network)s.' + 'already connected to the ' + 'network %(network)s.' % {'container': container.uuid, 'network': network}) self._get_or_create_docker_network(context, network_api, network) diff --git a/zun/network/kuryr_network.py b/zun/network/kuryr_network.py index 04a4b9d99..c82eca8b1 100644 --- a/zun/network/kuryr_network.py +++ b/zun/network/kuryr_network.py @@ -36,6 +36,7 @@ LOG = logging.getLogger(__name__) BINDING_PROFILE = 'binding:profile' BINDING_HOST_ID = 'binding:host_id' +DEVICE_OWNER = 'compute:kuryr' class KuryrNetwork(network.Network): @@ -201,13 +202,18 @@ class KuryrNetwork(network.Network): return self.docker.networks(**kwargs) def create_or_update_port(self, container, network_name, - requested_network, security_groups=None): + requested_network, security_groups=None, + set_binding_host=False): if requested_network.get('port'): neutron_port_id = requested_network.get('port') neutron_port = self.neutron_api.get_neutron_port(neutron_port_id) # update device_id in port port_req_body = {'port': {'device_id': container.uuid}} - self.neutron_api.update_port(neutron_port_id, port_req_body) + if set_binding_host: + port_req_body['port']['device_owner'] = DEVICE_OWNER + port_req_body['port'][BINDING_HOST_ID] = container.host + self.neutron_api.update_port(neutron_port_id, port_req_body, + admin=True) # If there is pci_request_id, it should be a sriov port. # populate pci related info. @@ -232,12 +238,16 @@ class KuryrNetwork(network.Network): 'tenant_id': self.context.project_id, 'device_id': container.uuid, } + if set_binding_host: + port_dict['device_owner'] = DEVICE_OWNER + port_dict[BINDING_HOST_ID] = container.host ip_addr = requested_network.get("fixed_ip") if ip_addr: port_dict['fixed_ips'] = [{'ip_address': ip_addr}] if security_groups is not None: port_dict['security_groups'] = security_groups - neutron_port = self.neutron_api.create_port({'port': port_dict}) + neutron_port = self.neutron_api.create_port({'port': port_dict}, + admin=True) neutron_port = neutron_port['port'] preserve_on_delete = requested_network['preserve_on_delete'] diff --git a/zun/network/neutron.py b/zun/network/neutron.py index a461acaee..8232ef2c9 100644 --- a/zun/network/neutron.py +++ b/zun/network/neutron.py @@ -48,6 +48,13 @@ class NeutronAPI(object): client = self.client return client.update_port(port, body) + def create_port(self, body=None, admin=False): + if admin: + client = self._get_admin_client() + else: + client = self.client + return client.create_port(body) + def find_resourceid_by_name_or_id(self, resource, name_or_id, project_id=None): return neutronv20.find_resourceid_by_name_or_id(