nova创建虚机网卡实际设备的代码调用流程为
_create_domain_and_network---->plug_vifs-->LibvirtGenericVIFDriver.plug-----> plug_ovs_hybrid--->_plug_bridge_with_port。
virtualinterface使用的dirver,由vif_driver参数决定,默认值为vif_driver=nova.virt.libvirt.vif.LibvirtGenericVIFDriver
D:code-program官网nova-ocata ovavirtlibvirtvif.py def plug_ovs_hybrid(self, instance, vif): """Plug using hybrid strategy Create a per-VIF linux bridge, then link that bridge to the OVS integration bridge via a veth device, setting up the other end of the veth device just like a normal OVS port. Then boot the VIF on the linux bridge using standard libvirt mechanisms. 创建一个per-VIF linux网桥,然后通过一个veth设备将该网桥链接到OVS集成网桥, 将veth设备的另一端设置为正常的OVS端口。 然后使用标准libvirt机制在linux桥上引导VIF """ self._plug_bridge_with_port(instance, vif, port='ovs') def _plug_bridge_with_port(self, instance, vif, port): iface_id = self.get_ovs_interfaceid(vif) # 获取br_name, 以qbr开头 br_name = self.get_br_name(vif['id']) # 获取veth_pair_name, 以qvb,qvo开头 v1_name, v2_name = self.get_veth_pair_names(vif['id']) #v1_name是qvb,v2_name是qvo # 添加一个 qbr 网桥 if not linux_net.device_exists(br_name): utils.execute('brctl', 'addbr', br_name, run_as_root=True) utils.execute('brctl', 'setfd', br_name, 0, run_as_root=True) utils.execute('brctl', 'stp', br_name, 'off', run_as_root=True) utils.execute('tee', ('/sys/class/net/%s/bridge/multicast_snooping' % br_name), process_input='0', run_as_root=True, check_exit_code=[0, 1]) disv6 = '/proc/sys/net/ipv6/conf/%s/disable_ipv6' % br_name if os.path.exists(disv6): utils.execute('tee', disv6, process_input='1', run_as_root=True, check_exit_code=[0, 1]) # 创建添加一个 qvo设备 if not linux_net.device_exists(v2_name): mtu = vif['network'].get_meta('mtu') #v1_name是qvb,v2_name是qvo # 将两个veth创建为一个peer-port linux_net._create_veth_pair(v1_name, v2_name, mtu)-----s1创建peer-port设备 utils.execute('ip', 'link', 'set', br_name, 'up', run_as_root=True) # 将qvb接口添加到qbr上 utils.execute('brctl', 'addif', br_name, v1_name, run_as_root=True) if port == 'ovs': # 将接口qvo桥接到br-int上 # 分别传入的参数为:br-int, qvo, port['id'], port的mac地址, instance-uuid linux_net.create_ovs_vif_port(self.get_bridge_name(vif),------s2 将qvo桥接到br-int上 v2_name, iface_id, vif['address'], instance.uuid, mtu) elif port == 'ivs': linux_net.create_ivs_vif_port(v2_name, iface_id, vif['address'], instance.uuid) s1创建peer-port设备 def _create_veth_pair(dev1_name, dev2_name, mtu=None): """Create a pair of veth devices with the specified names, deleting any previous devices with those names. """ for dev in [dev1_name, dev2_name]: delete_net_dev(dev) utils.execute('ip', 'link', 'add', dev1_name, 'type', 'veth', 'peer', 'name', dev2_name, run_as_root=True) for dev in [dev1_name, dev2_name]: utils.execute('ip', 'link', 'set', dev, 'up', run_as_root=True) utils.execute('ip', 'link', 'set', dev, 'promisc', 'on', run_as_root=True) _set_device_mtu(dev, mtu) s2 将qvo桥接到br-int上 def _create_ovs_vif_cmd(bridge, dev, iface_id, mac, instance_id, interface_type=None): # 将接口qvo桥接到br-int上 # 分别传入的参数为:br-int, qvo, port['id'], port的mac地址, instance-uuid cmd = ['--', '--if-exists', 'del-port', dev, '--', 'add-port', bridge, dev, '--', 'set', 'Interface', dev, 'external-ids:iface-id=%s' % iface_id, 'external-ids:iface-status=active', 'external-ids:attached-mac=%s' % mac, 'external-ids:vm-uuid=%s' % instance_id] if interface_type: cmd += ['type=%s' % interface_type] return cmd def create_ovs_vif_port(bridge, dev, iface_id, mac, instance_id, mtu=None, interface_type=None): _ovs_vsctl(_create_ovs_vif_cmd(bridge, dev, iface_id, mac, instance_id, interface_type)) # Note at present there is no support for setting the # mtu for vhost-user type ports. if interface_type != network_model.OVS_VHOSTUSER_INTERFACE_TYPE: _set_device_mtu(dev, mtu) else: LOG.debug("MTU not set on %(interface_name)s interface " "of type %(interface_type)s.", {'interface_name': dev, 'interface_type': interface_type})
由代码可以看出,至此,<qbr>--(qvb)--(qvo)--<br-int>就已经连接上了,至于虚机是如何与<qbr>连上的,这个就是在virt内部做的了,执行以下的命令, 其中的source字段是你提供的qbr, tap则是virt生成的.
[root@test ~]# virsh domiflist 33 Interface Type Source Model MAC ------------------------------------------------------- tap437153df-04 bridge qbr437153df-04 virtio fa:16:3e:e6:99:cd
从代码中可以了解到,Nova创建虚拟机时,网络设备的创建,本质上,执行,brctl,ovs-vsctl及ip link的命令行