neutron l3 agent 初始化过程代码走读

neutron-l3-agent 初始化流表过程
/usr/bin/neutron-l3-agent --config-file=/etc/neutron/neutron_dvr_compute.conf --config-file=/etc/neutron/dvr_compute_agent.ini

说明:
1  "//" 为 neutron-l3-agent 初始化过程的一个step步骤标记        

+------------------------------------------------------------------------------------+ 
(一) neutron-l3-agent 初始化过程:
+------------------------------------------------------------------------------------+ 
/usr/bin/neutron-l3-agent 调用neutron.agent.l3_agent.py中的main()方法来启动neutron-l3-agent服务。main()方法中创建一个加载了neutron.agent.l3.agent.L3NATAgentWithStateReport管理器的server,
然后启动这个server。launch server时,会调用server的start()方法。

(1) neutron.agent.l3_agent.py 中main()方法启动过程:
   1.1. 初始化 manager: neutron.agent.l3.agent.L3NATAgentWithStateReport:
   1.2. 初始化 neutron.service.py 中 class Service(n_rpc.Service)对象,并执行其start()方法。 初始化过程中将 加载 neutron.agent.l3.agent.L3NATAgentWithStateReport 类以及设置一些配置参数。
   
   //step 1.2 中 class Service(n_rpc.Service) start 方法逻辑:
        1.2.1 初始化 rpc connection,并创建消费者线程 消费 rpc topic。
        1.2.2 创建loop任务周期性调用report_state方法上报 l3-agent 服务的状态
        1.2.3 创建loop周期性的任务调用 neutron.agent.l3.agent.L3NATAgentWithStateReport 中的 periodic_sync_routers_task 方法从北向neutron-server fullsync 当前host上的所有的router_ids。
        1.2.4 调用neutron.agent.l3.agent.L3NATAgentWithStateReport 中的after_start 方法处理router loop
        
        //上述步骤 1.2.3 中 fullsync routers处理过程:
            初始化 namespace_manager(neutron.agent.l3.namespace_manager.py)实例对象。该实例对象主要是l3 的router namespace,dvr_snat_ns 以及 dvr_fip_ns 进行管理。如清除ns操作等。
            通过plugin_rpc 调用get_router_ids方法从北向获取当前host上的router_ids。
            通过plugin_rpc 调用get_routers方法批量地(一次取sync_routers_chunk_size 个router)从北向获取当前host上的所有routers。
            轮训 routers,处理router:
                将router_id 加入到router namespace中的标记队列,使其在清除ns时不清楚 router的ns
                如果router 为分布式路由:
                    如果router 存在ext_net_id(即external_gateway_info属性中的network_id字段存在),将router的fip_ns加入到router namespace中的标记队列中。
                    如果router 不存在ext_net_id,且l3 agent配置为dvr_snat 模式,则namespace管理器清除router的 snat namespace。
                如果router为HA router:
                    检测router的状态是否与db状态一致,如果不一致,发送router状态变化通知。
                构建RouterUpdate对象,加入到RouterProcessingQueue 的优先级队列Queue.PriorityQueue中等待处理。RouterUpdate构建参数:
                    queue.RouterUpdate(
                            r['id'],
                            queue.PRIORITY_SYNC_ROUTERS_TASK,
                            router=r,
                            timestamp=timestamp)   // 不设置action
                设置fullsync = False
                调整sync_routers_chunk_size 的值
                将当前router_info中不在北向获取routers中的router 构建RouterUpdate对象,加入到RouterProcessingQueue中等待处理。RouterUpdate构建参数:
                    queue.RouterUpdate(router_id,
                            queue.PRIORITY_SYNC_ROUTERS_TASK,
                            timestamp=timestamp,
                            action=queue.DELETE_ROUTER)     // 设置action                
                    
        // 上述步骤 1.2.4 中 after_start()处理逻辑
            (a)启动一个协程池调用 _process_routers_loop 方法轮询处理router。处理router的方法为_process_router_update:
                按顺序从RouterProcessingQueue 的优先级队列Queue.PriorityQueue中取出RouterUpdate对象。
                    if update.action == queue.PD_UPDATE:  
                        //Processing IPv6 PD Prefix Update,and continue
                    if update.action == queue.DELETE_ROUTER 且最后的更新时间小于router的timstamp:
                        // 将router_id 从内存中保存router更新时间的self.last_update_time字典中删除
                    if update.action == queue.CREATE_DISTRIBUTED_DHCP:
                        if update.id in self.router_info:
                            // continue。此时处理极端情况,当路由更新时,distributed_dhcp_notify 被接受到
                        如果从内存中保存的_prefetched_routers能够获取到router:
                            将updateRouter中的prefetched_network 保存到router的prefetched_networks属性中
                    if update.action != queue.DELETE_ROUTER and not router:
                        通过router_id 从北向获取router,获取不到,返回异常。
                        if update.action == queue.CREATE_DISTRIBUTED_DHCP:
                            将updateRouter中的prefetched_network 保存到router的prefetched_networks属性中,并将router_id保存到内存中的_prefetched_routers字典中
                    if not router and update.action != queue.DELETE_ROUTER and update.id in self._prefetched_routers
                        // continue. Avoid removing prefetched router
                    if not router:
                        将router_id从内存中的_prefetched_routers 字典中删除
                        安全删除router:
                            通过router_id从router_info中获取当前router的router_info
                            通过namespace_manager 删除router的namespace
                            发送 router before_delete消息
                            将router的router_info信息从router_info中删除
                            发送 router after_delete消息
                        l3_agent_extensions_manager 调用配置文件中的三层agent扩展驱动(driver)调用自身的delete_router方法删除router
                        更新router的timestamp,使其在processing queue队列中变为 older events,防止删除的router重新创建。
                        将router_id从内存中的 _fetched_router_ids 字典中删除。
                    处理兼容的路由:(_process_router_if_compatible)
                        if not self.conf.enable_inat_enat:
                            创建agent gw port(floating ip gw port)。检测gw port是否存在,不存在进行创建:
                                创建fip namespace(fip-${net-id})
                                通过rpc_plugin从北向neutron-server获取agent_gateway_port
                                创建fip namespace:
                                    ip netns add ${fip_namespace}
                                    ip netns exec ${fip_namespace} ip link set lo up
                                    ip netns exec ${fip_namespace} sysctl -w net.ipv4.ip_forward=1
                                    ip netns exec ${fip_namespace} sysctl -w net.ipv4.conf.all.rp_filter=0
                                    ip netns exec ${fip_namespace} sysctl -w net.ipv4.conf.default.rp_filter=0
                                获取fg_interface_name(fg-${port_id前11位})
                                增加fip agent gateway:
                                    如果fip namespace中不存在 fg_interface_name,ovs创建该port。调用 interface_driver(neutron.agent.linux.interface.OVSInterfaceDriver) plug该接口(处理过程在dhcp agent分析过)
                                    fip namespace中初始化路由port. 调用interface_driver(neutron.agent.linux.interface.OVSInterfaceDriver) init_router_port 方法。
                                    在fip namespace中对agent_gateway_port 的每个fixip 执行garp:
                                         python ${python_site_package_dir}/neutron/agent/l3/send_arping.py ${fg_interface_name} ${fixip} ${agent_gateway_port_mac} 1
                                    在fip namespace中的fg_interface_name 接口上增加 agent_gateway_port的gw ip:
                                        ip netns exec ${fip_namespace} ip route replace default via ${gateway_ip}
                                        ip netns exec ${fip_namespace} sysctl -w net.ipv4.conf.${fg_interface_name}.proxy_arp=1
                                清除fg namespace 无用的port(lo接口除外)
                                fip ns 初始化完成        
                        if     router.get("prefetched_networks"): //router 中包含 prefetched_networks属性
                            // 调用_process_prefetched_router 方法在路由中添加 prefetched_networks 路由信息
                                    
                        如果 router 不在 router_info中:
                            // 增加router
                                从router_info中获取router
                                调用router_info中的process()方法对router进行处理(router处理的核心逻辑。详细走读下期分解)
                                发送router的 after_create 通知
                                调用l3_ext_manager 中配置的driver的 add_router方法处理l3 扩展功能
                        否则:
                            // 更新router
                                从router_info中获取router
                                发送router的 before_update 通知
                                调用router_info中的process()方法对router进行处理(router处理的核心逻辑。详细走读下期分解)
                                发送router的 after_update 通知
                                调用l3_ext_manager 中配置的driver的 add_router方法处理l3 扩展功能
                    更新routerProcess中RouterUpdate 的timestamp
                    +------------------end 完成单个RouterUpdate的处理---------------------------------+
                    
            (b) 启动一个协程池调用 _send_router_interface_garp 方法三分钟一次轮询处理,向router 发送garp。 对每个router中的每个qr port发送arp。
                在router的namespace(qrouter-${router_id})执行命令: python ${python_site_package_dir}/neutron/agent/l3/send_arping.py  ${gw_device_name} fa:fa:fa:fa:fa:fa ${qr_fixip} ${count}
        
   


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

andy-guo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值