我们知道dvr模式下,l3-agent在每个计算节点生成了一个vrouter,服务于此计算节点上的虚机,计算和网络结合的地方在于port,虚机在哪个计算节点是通过port的binding:hostid知道的。虚机绑定floating ip,外出流量到qrouter namespace做SNAT,再根据ip rule查路由到fip namespace,在fip namespace配置一条路由,开启proxy_arp,把回来的流量先引到fip namespace,再转给qrouter namespace做DNAT。
baremetal采用vxlan network,需要L2GW打通vxlan和vlan,L2GW实现了ovs vtep schema,有physical switch, logical switch, physical port, physical locator, local mac, remote mac等概念,其中最重要是就是remote mac和physical locator的关联关系,就是一个目的mac要从哪个tunnel发送出去打个哪个vni。这些对应关系都是l2gw-agent通过ovsdb协议写给l2gw。
baremetal port没有绑定的hostid,LBaas中的vip有可能漂移,也没有绑定的host_id,它是怎么绑定floating ip的。看代码发现是这样的:给port绑定floatingip时,如果port有host_id,那么通知host_id指向的物理机上的l3 agent,没有host_id通知snat l3 agent,天然还支持router的ha功能。
那么只要允许neutron中给vnic_type=baremetal的port绑定floating ip,再在ironic创建baremetal时update_port时把host_id设置为空,那么就可以给baremetal绑定floating ip了,试一下还真可以。
最后baremetal绑定floating ip后流量如下图所示,红色是baremetal出外网的流量,绿色是外网回来的流量,有点不对称,可能影响firewall有状态的检测,不过router ha也可以搞定,不再需要做额外的工作。
L2GW根据l2gw-agent配置的remote mac和physical locator发送给右边的网络节点的qrouter,qrouter根据ip rule发送给左边网络节点的snat namespace,再做SNAT发送外网。外网回来的流量在snat namespace做DNAT,到qrouter namespace直接通过vxlan到l2gw,再到baremetal节点。
总结一下,openstack原生不能给baremetal绑定floating ip,只要两点很小的修改就可以实现了,但不知道有没有什么风险?欢迎留言指出。