可以使用virInterface类中的方法检查和修改物理主机上的网络接口配置。这可以用来设置主机来对想要直接连接网络的客户域共享一个物理接口(简要说——奴役一个物理接口,然后为每个虚拟机创建伐设备管理你想分享接口),以及通用主机网络接口管理。除了物理硬件,这些方法还可以用于配置网桥、绑定接口和vlan接口。
virInterface类不用于配置虚拟网络(用于在NAT后隐藏客户域的接口);虚拟网络是使用virNetwork类来配置的。
每个主机接口都由virInterface类的一个实例表示,每个实例都有一个唯一的标识符:
name方法返回一个主机上所有接口(活动的或不活动的)唯一的字符串。这与操作系统用来标识接口的字符串相同(例如:“eth0”或“br1”)。
每个接口对象还具有第二个非唯一索引,可以在同一主机上的其他接口中复制该索引.
MACString方法返回接口MAC地址的ASCII字符串表示形式。由于多个接口可以共享同一个MAC地址(例如,在vlan的情况下),这不是唯一的标识符。但是,它仍然可以用于搜索接口。
使用libvirt配置的所有接口都应该被认为是持久的,因为libvirt实际上是更改主机自己的持久配置数据(通常包含在/etc下的文件中),而不是接口本身。
当定义了新接口(使用interfaceDefineXML方法),或者更改了现有接口的配置(同样使用interfaceDefineXML方法)时,该配置将存储在主机上。在手动重启接口或重启主机之前,接口本身的动态配置不会被更改。
当前由interfaceDefineXML和XMLDesc生成和接受的XML的Relax NG定义可以在文件docs/schema/interface中找到。libvirt库的RNG,可以在https://gitlab.com/libvirt/libvirt/上获得。下面是一些常见的接口配置示例。
使用dhcp配置
<interface type='ethernet' name='eth0'>
<start mode='onboot'/>
<mac address='aa:bb:cc:dd:ee:ff'/>
<protocol family='ipv4'>
<dhcp/>
</protocol>
</interface>
静态配置
<interface type='ethernet' name='eth0'>
<start mode='onboot'/>
<mac address='aa:bb:cc:dd:ee:ff'/>
<protocol family='ipv4'>
<ip address="192.168.0.5" prefix="24"/>
<route gateway="192.168.0.1"/>
</protocol>
</interface>
桥接eth0和eth1
<interface type="bridge" name="br0">
<start mode="onboot"/>
<mtu size="1500"/>
<protocol family="ipv4">
<dhcp/>
</protocol>
<bridge stp="off" delay="0.01">
<interface type="ethernet" name="eth0">
<mac address="ab:bb:cc:dd:ee:ff"/>
</interface>
<interface type="ethernet" name="eth1"/>
</bridge>
</interface>
定义一个关联eth0的vlan接口
<interface type="vlan" name="eth0.42">
<start mode="onboot"/>
<protocol family="ipv4">
<dhcp peerdns="no"/>
</protocol>
<vlan tag="42">
<interface name="eth0"/>
</vlan>
</interface>
一旦您与主机建立了连接,您就可以使用numOfInterfaces和numOfDefinedInterfaces方法确定主机上的接口数量。这些接口的名称列表可以通过listInterfaces方法和listDefinedInterfaces方法获得(“defined”接口是那些已经定义,但目前不活动的接口)。list方法返回一个Python列表。如果遇到错误,所有四个函数都返回None。
import sys
import libvirt
conn = None
try:
conn = libvirt.open("qemu:///system")
except libvirt.libvirtError as e:
print(repr(e), file=sys.stderr)
exit(1)
ifaceNames = conn.listInterfaces()
print("Active host interfaces:")
for ifaceName in ifaceNames:
print(' '+ifaceName)
conn.close()
exit(0)
import sys
import libvirt
conn = None
try:
conn = libvirt.open("qemu:///system")
except libvirt.libvirtError as e:
print(repr(e), file=sys.stderr)
exit(1)
ifaceNames = conn.listDefinedInterfaces()
print("Inactive host interfaces:")
for ifaceName in ifaceNames:
print(' '+ifaceName)
conn.close()
exit(0)
许多操作需要您有一个virInterface实例,但您可能只有接口的名称或MAC地址。在这些情况下,可以使用interfaceLookupByName和interfaceLookupByMACString来获取virInterface实例。
import sys
import libvirt
conn = None
try:
conn = libvirt.open("qemu:///system")
except libvirt.libvirtError as e:
print(repr(e), file=sys.stderr)
exit(1)
iface = conn.interfaceLookupByName('eth0')
print("The interface name is: "+iface.name())
conn.close()
exit(0)
import sys
import libvirt
conn = None
try:
conn = libvirt.open("qemu:///system")
except libvirt.libvirtError as e:
print(repr(e), file=sys.stderr)
exit(1)
iface = conn.interfaceLookupByMACString('00:01:02:03:04:05')
print("The interface name is: "+iface.name())
conn.close()
exit(0)
您可能会发现自己有一个virDomain实例,需要一个或多个来宾域接口的IP地址。interfaceAddresses方法提供了这种功能。
在libvirt中,“define”接口意味着创建或更改配置,而“undefine”则意味着从系统中删除该配置。新手有时可能会把这两种操作与create/delete混淆(用于激活或使无效一个存在的接口)
interfaceDefineXML方法用于添加新的接口配置和修改现有配置。它要么添加一个新接口(包含XML数据中给出的所有信息,包括接口名称),要么修改现有接口的配置。新定义的接口将处于非活动状态,直到采取单独的操作使新配置生效(例如,重新启动主机,或调用create,在7.5节“接口生命周期管理”中描述)
如果在主机的配置中成功添加/修改了接口,interfaceDefineXML将返回一个virInterface实例。这可以用作句柄,用于在新接口上执行进一步的操作,例如使用create使其处于活动状态。
import sys
import libvirt
xml = """
<interface type='ethernet' name='eth0'>
<start mode='onboot'/>
<mac address='aa:bb:cc:dd:ee:ff'/>
<protocol family='ipv4'>
<ip address="192.168.0.5" prefix="24"/>
<route gateway="192.168.0.1"/>
</protocol>
</interface>"""
conn = None
try:
conn = libvirt.open('qemu:///system')
except libvirt.libvirtError as e:
print(repr(e), file=sys.stderr)
exit(1)
# create/modify a network interface
iface = conn.interfaceDefineXML(xml, 0)
# activate the interface
try:
iface.create(0)
except libvirt.libvirtError as e:
print(repr(e), file=sys.stderr)
iface.undefine()
conn.close()
exit(1)
print("The interface name is: "+iface.name())
iface.destroy()
iface.undefine()
conn.close()
exit(0)