【nova4】nova vCenter Driver创建虚机与网络不一致解决办法

更新时间:2019-10-24    来源:网络相关    手机版     字体:

【www.bbyears.com--网络相关】


上周将VMware mech driver实现完成后,发现一个问题。测试时发现,neutron创建的网络,与nova创建的虚拟机被创建在不同的ESXi主机上,当然cluster中只有一个ESXi主机时,不会存在这个问题。

切换到nova-network下,发现也存在这个问题。launchpad上有人报了这个bug:
 

跟了下/nova/virt/vmwareapi的代码,错误大概是这样子的:
nova在创建虚拟机时,通过_get_vif_infos()获取vif_infos。
在_get_vif_infos方法中,调用vif.py的get_network_ref方法获取network_ref。
如果使用不用neutron nsx,调用ensure_vlan_bridge。

ensure_vlan_bridge在cluster中查找是否存在要创建的网络(在ESXi主机上为端口组),这个查找是在cluster中指定的1台ESXi主机上查找,比如ESXi A。如果不存在就去创建网络。
创建成功后继续调用network_util.get_network_with_the_name进行查询,此时应该可以查询到新建的网络,但是这个地方有bug,新建的网络还是查询不到,因此network_ref返回为空。
所以创建虚拟机时,虚拟机不会加入新建的网络(端口组)。

def ensure_vlan_bridge(session, vif, cluster=None, create_vlan=True):

    """Create a vlan and bridge unless they already exist."""

    vlan_num = vif['network'].get_meta('vlan')

    bridge = vif['network']['bridge']

    vlan_interface = CONF.vmware.vlan_interface

 

    network_ref = network_util.get_network_with_the_name(session, bridge,

                                                         cluster)

    if network_ref and network_ref['type'] == 'DistributedVirtualPortgroup':

        return network_ref

 

    if not network_ref:

        # Create a port group on the vSwitch associated with the

        # vlan_interface corresponding physical network adapter on the ESX

        # host.

        vswitch_associated = _get_associated_vswitch_for_interface(session,

                                 vlan_interface, cluster)

        network_util.create_port_group(session, bridge,

                                       vswitch_associated,

                                       vlan_num if create_vlan else 0,

                                       cluster)

        # bug就出在这里,上一步创建的port group,这里没有获取到。

        network_ref = network_util.get_network_with_the_name(session,

                                                             bridge,

                                                             cluster)

    elif create_vlan:

        # Get the vSwitch associated with the Physical Adapter

        vswitch_associated = _get_associated_vswitch_for_interface(session,

                                 vlan_interface, cluster)

        # Get the vlan id and vswitch corresponding to the port group

        _get_pg_info = network_util.get_vlanid_and_vswitch_for_portgroup

        pg_vlanid, pg_vswitch = _get_pg_info(session, bridge, cluster)

 

        # Check if the vswitch associated is proper

        if pg_vswitch != vswitch_associated:

            raise exception.InvalidVLANPortGroup(

                bridge=bridge, expected=vswitch_associated,

                actual=pg_vswitch)

 

        # Check if the vlan id is proper for the port group

        if pg_vlanid != vlan_num:

            raise exception.InvalidVLANTag(bridge=bridge, tag=vlan_num,

                                       pgroup=pg_vlanid)

    return network_ref


至于这个新建的网络查询为什么会失败,我还没想明白。

之后我就想,既然ESXi的标准交换机不支持分布式端口组,那么可以在cluster中的每一台标准交换机上创建端口组(即网络),这样就不存在之前的调度失败的问题。

尝试着修改了vm_util.py中get_host_ref的代码,将cluster中的所有ESXi主机都返回。由于有一些函数调用到get_host_ref,所以如果此时不修改之前的代码逻辑,调用suds client去调用vSphere API获取vSphere中某些对象属性的时候,肯定会报错。

这个时候,由于自己的粗心,没有仔细分析日志,认为在一个session中不能获取vSphere的多个对象。认为在每一个ESXi主机上创建端口组的方法不可行。

突然又想不能这么轻易放弃,如果不去这样实现,那么就没有更好的办法了。静下心来好好看了日志,发现之前的报错,还没有走到create_port_group这一步,于是从报错的地方开始,把代码逻辑逐个修改了。
最后创建网络,创建虚机,发现一切OK。

本文来源:http://www.bbyears.com/jiaocheng/75205.html

热门标签

更多>>

本类排行