已经确认 只有ovn neutron 有dvr 相关的代码,且neutron 默认部署也是集中式的,可以通过一个参数 enable_distributed_floating_ip 配置为分布式的
一、 neutron 如何控制fip的分布式|集中式
1. dvr 情况下, fip nat 如何配置
创建fip的主流程
DVR FIP QOS 作用在local chassis port上面
对比了下 之前的fip的port details的mac,mac其实是内网ip的mac
那么DVR设置时最重要的mac信息知道来自于哪里了。
创建时的log
# 注意 neutron:fip_external_mac'
2021-03-29 18:14:24.012 25 DEBUG ovsdbapp.backend.ovs_idl.event [req-7fb392de-cd6b-42ca-8db3-5a05986b9dfd - - - - -] Matched CREATE: FIPAddDeleteEvent(events=('create', 'delete'), table='NAT', conditions=(('type', '=', 'dnat_and_snat'),), old_conditions=None) to row=NAT(logical_port=['4b77bfe4-d1db-441d-84d8-1625fef75914'], external_port_range=, external_ids={'neutron:fip_external_mac': 'fa:16:3e:e8:a0:ba', 'neutron:fip_id': '90f825b2-d012-439e-b055-d738215f3fe7', 'neutron:fip_port_id': '4b77bfe4-d1db-441d-84d8-1625fef75914', 'neutron:revision_number': '2', 'neutron:router_name': 'neutron-ca7f7714-28f3-4ad3-af9e-048611d906d6'}, options={}, exempted_ext_ips=[], allowed_ext_ips=[], type=dnat_and_snat, external_ip=10.120.3.197, external_mac=['fa:16:3e:e8:a0:ba'], logical_ip=10.119.1.102) old= matches /var/lib/kolla/venv/lib/python3.6/site-packages/ovsdbapp/backend/ovs_idl/event.py:44
# 对应neutron相关的代码
# neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py
...
columns = {'type': 'dnat_and_snat',
'logical_ip': floatingip['fixed_ip_address'],
'external_ip': floatingip['floating_ip_address'],
'logical_port': floatingip['port_id'],
'external_ids': ext_ids} # 这里只是逻辑上的记录
if ovn_conf.is_ovn_distributed_floating_ip():
if self._nb_idl.lsp_get_up(floatingip['port_id']).execute():
columns['external_mac'] = port_db['mac_address']
# 在配置fip的nat时要把mac 给进去
2. dvr情况下, lrp如何设置
可以看到当provider网络是vlan|flat 类型时,如果是dvr模式,则需要配置redirect。
# neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/maintenance.py
def check_redirect_type_router_gateway_ports(self):
"""Check OVN router gateway ports
Check for the option "redirect-type=bridged" value for
router gateway ports.
"""
if not self.has_lock:
return
context = n_context.get_admin_context()
cmds = []
gw_ports = self._ovn_client._plugin.get_ports(
context, {'device_owner': [n_const.DEVICE_OWNER_ROUTER_GW]})
for gw_port in gw_ports:
enable_redirect = False
if ovn_conf.is_ovn_distributed_floating_ip():
try:
r_ports = self._ovn_client._get_router_ports(
context, gw_port['device_id'])
except l3_exc.RouterNotFound:
LOG.debug("No Router %s not found", gw_port['device_id'])
continue
else:
network_ids = {port['network_id'] for port in r_ports}
networks = self._ovn_client._plugin.get_networks(
context, filters={'id': network_ids})
# NOTE(ltomasbo): For VLAN type networks connected through
# the gateway port there is a need to set the redirect-type
# option to bridge to ensure traffic is not centralized
# through the controller.
# If there are no VLAN type networks attached we need to
# still make it centralized.
if networks:
enable_redirect = all(
net.get(pnet.NETWORK_TYPE) in [n_const.TYPE_VLAN,
n_const.TYPE_FLAT]
for net in networks)
lrp_name = utils.ovn_lrouter_port_name(gw_port['id'])
lrp = self._nb_idl.get_lrouter_port(lrp_name)
redirect_value = lrp.options.get(
ovn_const.LRP_OPTIONS_REDIRECT_TYPE)
if enable_redirect:
if redirect_value != ovn_const.BRIDGE_REDIRECT_TYPE:
opt = {ovn_const.LRP_OPTIONS_REDIRECT_TYPE:
ovn_const.BRIDGE_REDIRECT_TYPE}
cmds.append(self._nb_idl.db_set(
'Logical_Router_Port', lrp_name, ('options', opt)))
# 可以看到这里dvr 需要配置为redirect
else:
if redirect_value == ovn_const.BRIDGE_REDIRECT_TYPE:
cmds.append(self._nb_idl.db_remove(
'Logical_Router_Port', lrp_name, 'options',
(ovn_const.LRP_OPTIONS_REDIRECT_TYPE)))
和以上逻辑相同,还有获取_gen_router_port_options(self, port, network=None)
lrp option的具体内容是
opt = {ovn_const.LRP_OPTIONS_REDIRECT_TYPE:
ovn_const.BRIDGE_REDIRECT_TYPE}
cmds.append(self._nb_idl.db_set(
'Logical_Router_Port', lrp_name, ('options', opt)))
# LRP_OPTIONS_REDIRECT_TYPE = 'redirect-type'
# BRIDGE_REDIRECT_TYPE = "bridged"
opt = {'redirect-type': "bridged"}
二、 ovn k8s 如何实现 DVR fip
可以看到这个例子就是DVR FIP 的使用效果
ovs-k8s 关于DGP的描述中并不需要配置redirect,代码中并没有。详见DGP 分析:juejin.cn/post/723033…