关于如何控制 ovn fip 分布式或集中式

468 阅读2分钟

已经确认 只有ovn neutron 有dvr 相关的代码,且neutron 默认部署也是集中式的,可以通过一个参数 enable_distributed_floating_ip 配置为分布式的

一、 neutron 如何控制fip的分布式|集中式

1. dvr 情况下, fip nat 如何配置

创建fip的主流程

image.png

image.png

image.png

image.png

image.png

image.png

DVR FIP QOS 作用在local chassis port上面

image.png

image.png

image.png

image.png

image.png

对比了下 之前的fip的port details的mac,mac其实是内网ip的mac

image.png

image.png

image.png

那么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如何设置

image.png

可以看到当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"}


image.png

二、 ovn k8s 如何实现 DVR fip

image.png

可以看到这个例子就是DVR FIP 的使用效果

image.png

ovs-k8s 关于DGP的描述中并不需要配置redirect,代码中并没有。详见DGP 分析:juejin.cn/post/723033…

参考: satishdotpatel.github.io/openstack-a…