Openstack neutron l3 HA的实现

记录学习neutron l3 HA实现的过程。

1.  router所在的所有节点的namespace中都会启动keepalived服务,通过keepalived服务来控制节点的选举:

keepalived的进程: keepalived -P -f /var/lib/neutron/ha_confs/d188f462-ae87-455d-9445-da00c842e78e/keepalived.conf -p /var/lib/neutron/ha_confs/d188f462-ae87-455d-9445-da00c842e78e.pid -r /var/lib/neutron/ha_confs/d188f462-ae87-455d-9445-da00c842e78e.pid-vrrp

keepalived的配置文件: 
vrrp_instance VR_1 {
    state BACKUP
    interface ha-eca0c14d-f0
    virtual_router_id 1
    priority 50
    nopreempt
    advert_int 1
    track_interface {
        ha-eca0c14d-f0
    }
    virtual_ipaddress {
        169.254.0.1/24 dev ha-eca0c14d-f0
    }
    virtual_ipaddress_excluded {
        10.168.89.167/24 dev qg-eb9e70a6-0a
        172.16.5.1/24 dev qr-ca16028e-41
        fe80::f816:3eff:febb:31bc/64 dev qr-ca16028e-41 scope link
        fe80::f816:3eff:fee8:4fda/64 dev qg-eb9e70a6-0a scope link
    }
    virtual_routes {
        0.0.0.0/0 via 10.168.89.254 dev qg-eb9e70a6-0a
    }
}

kilo neutron l3 ha的实现
主要围绕以下几个问题:
1. l3 agent的调度策略
2. keepalived 和 neutron-keepalived-state-change 服务是什么时候创建的
3. keepalived 和 neutron-keepalived-state-change 如何实现l3 ha
4. l3 ha 通常会遇到的问题以及解决的办法

neutron l3 相关的代码:
1. 配置文件中配置了service_plugins 指定加载l3_router_plugin:
service_plugins = neutron.services.l3_router.l3_router_plugin.L3RouterPlugin
其中plugin_type 设置成了constants.L3_ROUTER_NAT,   所以之后可以通过
manager.NeutronManager.get_service_plugins().get(service_constants.L3_ROUTER_NAT)来获得这个plugin
2.  l3_router_plugin中定义了supported_extension_aliases = ["dvr", "router", "ext-gw-mode",  "extraroute", "l3_agent_scheduler",  "l3-ha"]
继承的顺序如下:
common_db_mixin.CommonDbMixin,
extraroute_db.ExtraRoute_db_mixin,
l3_hamode_db.L3_HA_NAT_db_mixin,
l3_gwmode_db.L3_NAT_db_mixin,
l3_dvrscheduler_db.L3_DVRsch_db_mixin,
l3_hascheduler_db.L3_HA_scheduler_db_mixin 

一 创建router,执行的操作:
1. neutron server调用l3_hamode_db.L3_HA_NAT_db_mixin.create_router
    1.1. 调用l3_db.L3_NAT_dbonly_mixin.create_router方法创建数据库记录
    1.2. _create_ha_network如果当前没有ha network会创建ha network和 ha subnet, 同时会建立ha network和tenant的关系: 表ha_router_networks
    1.3. _set_vr_id设置vrid(virtual router id)会在keepalived中使用, 用于识别同一个租户下的不同router,  vrid的返回是1 到 254, 所以一个tenant最多只能建立254个router
    1.4  _create_ha_interfaces 根据配置文件的min_l3_agent_per_router 和 max_l3_agent_per_router 以及当前l3_agent的个数来在HA Network上创建port
           同时给这些port和router做绑定关系, agent和state初始化为null(表: ha_router_agent_port_bindings)
    1.5  _notify_ha_interfaces_update, 
           1.5.1: scheduler router, kilo中支持两种调度策略(ChanceScheduler 和 LeastRouterScheduler)可以在neutron.conf中router_scheduler_driver指定。
                         ChanceScheduler: 表示随机分配策略
                        LeastRouterScheduler:  表示最少router优先的策略
                        其中schedule_router的过程中还会执行bind_router操作,这个操作其实是将ha_router_agent_port_binding表中的ha port分配给agent, 同时建立router和agent的关系(routerl3agentbindings)
           1.5.2: rpc_cast, "routers_updated" 给这个router所分配的所有router
2. neutron l3 agent, agent/l3/agent.py  
    l3_agent的处理过程: L3NATAgent在初始化过程中会创建一个queue(queue里面存各个router的事件): self._queue = queue.RouterProcessingQueue(),
    l3_agent会有一个循环不断处理queue里面的数据(_process_routers_loop)。如果处理过程中出现异常会触发一次fullsync,保证这个l3_agent是最新的一个状态。后面需要学习fullsync的过程。
    routers_updated 所做的操作:
    2.1  _process_router_if_compatible(检查兼容性) 
         2.1.1 检查配置文件中的external_network_bridge是否存在。
         2.1.2 如果没有指定use_namespaces,则l3_agent只能处理一个router,所以判断更新事件的router_id和配置中的router_id是否一致。(这种情况可以忽略,现在一般都会用namespace)
         2.1.3 如果router没有指定external gateway,且该agent不支持internal router(配置文件中:handle_internal_only_routers ),抛出RouterNotCompatibleWithAgent异常
         2.1.4 之前的router_info中没有存改router信息执行_process_added_router, 否则_process_updated_router
    2.2 _process_added_router(处理新增的router)
         2.2.1 创建ha_router.HaRouter对象, 其中创建了namespaceManager 和iptablesManager
         2.2.2 调用ha_router的initialize
              2.2.2.1  router_info的initialize  创建namespace,同时setup lo设置以及设置namespace的网络转发参数, sysctl -w net.ipv4.ip_forward=1
              2.2.2.2 _init_keepalived_manager,  创建keepalivedManager,初始化一些keepalived的参数(比如,vrid、ha_subnet_cidr等),但是还没有创建进程。
              2.2.2.3 ha_network_added, 创建物理设备(ha_port, tag是由哪个值决定的?),把它绑定到br-int上,并将它放到namespace里面,同时配置相应的ip地址,169.254.192.x/18
             $ ovs-vsctl --timeout=10 --oneline --format=json -- --if-exists del-port ha-255eb1bf-7d -- add-port  br-int ha-255eb1bf-7d -- set Interface ha-255eb1bf-7d type=internal external_ids:iface-id=255eb1bf-7ba7-41d7-bc36-029e541bedfd external_ids:iface-status=active external_ids:attached-mac=fa:16:3e:3d:3e:ce  这个居然会创建tag ?? 应该是ovs-agent会创建相应的tag,得验证, external_ids只是为了保存信息。
              2.2.2.4 update_initial_state, 判断是否keepalived的vip (vip的值怎么决定的?初始化的时候哪个节点作为vip节点?vip是由第一个可用的cidr为24的范围决定,初始化时所有的节点都为backup节点 )在当前agent的ha设置上来判断当前节点是master还是slave,同时会回调ensure_state_change来设置状态值。
              2.2.2.5 spawn_state_change_monitor  创建neutron-keepalived-state-change进程, 参数包括router_id,  namespace ,conf_dir, monitor_interface, monitor_cidr, pid_file, state_path, user 以及group
         2.2.3 调用ha_router的 process
              2.2.3.1  _ process_internal_ports,  处理router绑定的内部interface的port,刚创建的router还没有绑定interface,所以忽略。
              2.2.3.2  process_external, 处理floatingip的绑定,同时执行iptables相关的规则。
              2.2.3.3  enable_keepalived,  启动keepalived的进程

直到这整个创建router的过程结束。

二 neutron-keepalived-state-change服务是怎么判断节点状态的变化

1. 首先neutron-keepalived-state-change会启动一个异步进程( ip -o monitor address)去监听router namespace下ip地址的变化
2. 遍历所有地址的变化,有地址的增加则认为是master, 其它地址变化都是backup
3. 更改keepalived文件夹下的state文件, state文件保存了router在当前agent的状态(master/backup)
4. 通过unix domain socket来通知l3_agent 服务节点状态的变化。 (unix domain socket的server在初始化l3_agent的时候创建.ha.AgentMixin)

参考文档: https://wiki.openstack.org/wiki/Neutron/L3_High_Availability_VRRP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值