svc namespace isolation support for different octavia drivers
This patch ensures svc namespace isolation may work with different types of octavia drivers. Depending on the ownership of the security group, as well as the tenant kuryr-controller is running on, there may be a need to create (and apply) a new security group for the loadbalancer VIP port, or simply update the existing one. A new configuration option, names sg_mode has been added that accepts update|create depending on the desired behavior. As of today, the options will be: - Amphora driver: needs to 'update' the SG as the VIP port is connected to the amphora through the allow_address_pair option, and the SG rules are enforced on the amphora port rather than on the VIP port. However, as both ports share the same SG, updating it will ensure the proper isolation. Note the SG in the amphora driver belongs to the admin tenant instead of the one creating the loadbalancer. - OVN driver: SG is applied directly on the VIP port, so both updating or creating a SG will work as the VIP port belongs to the tenant. However, as of today OVN-driver does not create a SG for the loadbalancer and the SG applied is the default one. Thus, there is a need for setting the sg_mode to 'create', so that a new one is created and the proper rules are applied there. Implements: blueprint octavia-ovn-provider Change-Id: I4ad4d55b75ce7a6d5e102b5f35bedc07af4fbb96
This commit is contained in:
parent
5963d01731
commit
451add3543
|
@ -55,10 +55,11 @@ KURYR_K8S_LBAAS_USE_OCTAVIA=True
|
|||
# In case Octavia is used for LBaaS, you can choose the
|
||||
# Octavia's Load Balancer provider.
|
||||
# KURYR_EP_DRIVER_OCTAVIA_PROVIDER=default
|
||||
# Uncomment the next two to enable ovn provider. Note only L2 mode is
|
||||
# supported
|
||||
# Uncomment the next lines to enable ovn provider. Note L2 mode is used
|
||||
# to ensure member subnet is added
|
||||
# KURYR_EP_DRIVER_OCTAVIA_PROVIDER=ovn
|
||||
# KURYR_K8S_OCTAVIA_MEMBER_MODE=L2
|
||||
# KURYR_K8S_OCTAVIA_SG_MODE=create
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -450,6 +450,7 @@ function configure_neutron_defaults {
|
|||
fi
|
||||
iniset "$KURYR_CONFIG" neutron_defaults external_svc_net "$ext_svc_net_id"
|
||||
iniset "$KURYR_CONFIG" octavia_defaults member_mode "$KURYR_K8S_OCTAVIA_MEMBER_MODE"
|
||||
iniset "$KURYR_CONFIG" octavia_defaults sg_mode "$KURYR_K8S_OCTAVIA_SG_MODE"
|
||||
if [[ "$use_octavia" == "True" ]]; then
|
||||
# Octavia takes a very long time to start the LB in the gate. We need
|
||||
# to tweak the timeout for the LB creation. Let's be generous and give
|
||||
|
|
|
@ -62,6 +62,7 @@ OPENSHIFT_CNI_BINARY_URL=${OPENSHIFT_CNI_BINARY_URL:-https://github.com/containe
|
|||
# Octavia
|
||||
KURYR_K8S_LBAAS_USE_OCTAVIA=${KURYR_K8S_LBAAS_USE_OCTAVIA:-True}
|
||||
KURYR_K8S_OCTAVIA_MEMBER_MODE=${KURYR_K8S_OCTAVIA_MEMBER_MODE:-L3}
|
||||
KURYR_K8S_OCTAVIA_SG_MODE=${KURYR_K8S_OCTAVIA_SG_MODE:-update}
|
||||
|
||||
# Kuryr_ovs_baremetal
|
||||
KURYR_CONFIGURE_BAREMETAL_KUBELET_IFACE=${KURYR_CONFIGURE_BAREMETAL_KUBELET_IFACE:-True}
|
||||
|
|
|
@ -219,6 +219,11 @@ octavia_defaults = [
|
|||
help=_("Define the communication mode between load balanacer "
|
||||
"and its members"),
|
||||
default='L3'),
|
||||
cfg.StrOpt('sg_mode',
|
||||
help=_("Define the LBaaS SG policy."),
|
||||
choices=[('create', 'replace the VIP SG with a new one'),
|
||||
('update', 'add rules to the existing VIP SG')],
|
||||
default='update'),
|
||||
]
|
||||
|
||||
cache_defaults = [
|
||||
|
|
|
@ -89,13 +89,17 @@ class LBaaSv2Driver(base.LBaaSDriver):
|
|||
self._release(loadbalancer, loadbalancer,
|
||||
lbaas.delete_loadbalancer, loadbalancer.id)
|
||||
|
||||
sg_id = self._find_listeners_sg(loadbalancer)
|
||||
if sg_id:
|
||||
try:
|
||||
neutron.delete_security_group(sg_id)
|
||||
except n_exc.NeutronClientException:
|
||||
LOG.exception('Error when deleting loadbalancer security '
|
||||
'group. Leaving it orphaned.')
|
||||
sg_id = self._find_listeners_sg(loadbalancer)
|
||||
if sg_id:
|
||||
# Note: reusing activation timeout as deletion timeout
|
||||
self._wait_for_deletion(loadbalancer, _ACTIVATION_TIMEOUT)
|
||||
try:
|
||||
neutron.delete_security_group(sg_id)
|
||||
except n_exc.NeutronClientException:
|
||||
LOG.exception('Error when deleting loadbalancer security '
|
||||
'group. Leaving it orphaned.')
|
||||
except n_exc.NotFound:
|
||||
LOG.debug('Security group %s already deleted', sg_id)
|
||||
|
||||
def _ensure_security_groups(self, loadbalancer, service_type):
|
||||
# We only handle SGs for legacy LBaaSv2, Octavia handles it dynamically
|
||||
|
@ -152,24 +156,45 @@ class LBaaSv2Driver(base.LBaaSDriver):
|
|||
|
||||
def _extend_lb_security_group_rules(self, loadbalancer, listener):
|
||||
neutron = clients.get_neutron_client()
|
||||
sg_id = self._get_vip_port(loadbalancer).get('security_groups')[0]
|
||||
|
||||
if CONF.octavia_defaults.sg_mode == 'create':
|
||||
sg_id = self._find_listeners_sg(loadbalancer)
|
||||
# if an SG for the loadbalancer has not being created, create one
|
||||
if not sg_id:
|
||||
sg = neutron.create_security_group({
|
||||
'security_group': {
|
||||
'name': loadbalancer.name,
|
||||
'project_id': loadbalancer.project_id,
|
||||
},
|
||||
})
|
||||
sg_id = sg['security_group']['id']
|
||||
loadbalancer.security_groups.append(sg_id)
|
||||
vip_port = self._get_vip_port(loadbalancer)
|
||||
neutron.update_port(
|
||||
vip_port.get('id'),
|
||||
{'port': {
|
||||
'security_groups': loadbalancer.security_groups}})
|
||||
else:
|
||||
sg_id = self._get_vip_port(loadbalancer).get('security_groups')[0]
|
||||
|
||||
for sg in loadbalancer.security_groups:
|
||||
try:
|
||||
neutron.create_security_group_rule({
|
||||
'security_group_rule': {
|
||||
'direction': 'ingress',
|
||||
'port_range_min': listener.port,
|
||||
'port_range_max': listener.port,
|
||||
'protocol': listener.protocol,
|
||||
'security_group_id': sg_id,
|
||||
'remote_group_id': sg,
|
||||
'description': listener.name,
|
||||
},
|
||||
})
|
||||
except n_exc.NeutronClientException as ex:
|
||||
if ex.status_code != requests.codes.conflict:
|
||||
LOG.exception('Failed when creating security group rule '
|
||||
'for listener %s.', listener.name)
|
||||
if sg != sg_id:
|
||||
try:
|
||||
neutron.create_security_group_rule({
|
||||
'security_group_rule': {
|
||||
'direction': 'ingress',
|
||||
'port_range_min': listener.port,
|
||||
'port_range_max': listener.port,
|
||||
'protocol': listener.protocol,
|
||||
'security_group_id': sg_id,
|
||||
'remote_group_id': sg,
|
||||
'description': listener.name,
|
||||
},
|
||||
})
|
||||
except n_exc.NeutronClientException as ex:
|
||||
if ex.status_code != requests.codes.conflict:
|
||||
LOG.exception('Failed when creating security group '
|
||||
'rule for listener %s.', listener.name)
|
||||
|
||||
# ensure routes have access to the services
|
||||
service_subnet_cidr = self._get_subnet_cidr(loadbalancer.subnet_id)
|
||||
|
@ -540,6 +565,15 @@ class LBaaSv2Driver(base.LBaaSDriver):
|
|||
|
||||
raise k_exc.ResourceNotReady(loadbalancer)
|
||||
|
||||
def _wait_for_deletion(self, loadbalancer, timeout):
|
||||
lbaas = clients.get_loadbalancer_client()
|
||||
|
||||
for remaining in self._provisioning_timer(timeout):
|
||||
try:
|
||||
lbaas.show_loadbalancer(loadbalancer.id)
|
||||
except n_exc.NotFound:
|
||||
return
|
||||
|
||||
def _provisioning_timer(self, timeout):
|
||||
# REVISIT(ivc): consider integrating with Retry
|
||||
interval = 3
|
||||
|
|
Loading…
Reference in New Issue