「KVM」- Networking @20210226_<interface type='network'>,指定ip-程序员宅基地

本文介绍基于libvirt的应用程序使用的常见网络配置。 此信息适用于所有「Hypervisor」,无论是Xen,还是KVM,又或者其他。

两种常见设置是:

	* 虚拟网络:「NAT转发」。开箱即用,无需过多设置。
	* 共享设备:「桥接网络」。需要进行特定的手动配置。

本文主要介绍这两种网络。最后一部分是「网络设备直通」相关的内容。

虚拟网络:NAT转发

#1 对Host配置

如果libvirt是标准安装的,那它默认提供基于NAT的虚拟机连接,开箱即用:

# virsh net-list --all
 Name      State      Autostart   Persistent
----------------------------------------------
 default   inactive   yes         yes

如果不存在,可以进行定义或者激活:

# virsh net-define /usr/share/libvirt/networks/default.xml
Network default defined from /usr/share/libvirt/networks/default.xml

# virsh net-autostart default
Network default marked as autostarted

# virsh net-start default
Network default started

上面的default.xml文件内容类似于:

<!-- virsh net-dumpxml --inactive --network default -->
<network>
  <name>default</name>
  <uuid>aa81e36e-28c6-4ba7-87d1-4599b2671550</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:a3:b6:d1'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

有关的网络定义方面的内容,参考官方「Network XML format」一文。

在网络启动后,你会看到网桥「virbr0」和网卡「virbr0-nic」。注意,这张网卡没有添加任何物理设备,因为它通过「NAT」+「转发」来访外部,不要添加设备

# brctl show
bridge name     bridge id               STP enabled     interfaces
virbr0          8000.525400a3b6d1       yes             virbr0-nic

同时libvirt会在INPUT, FORWARD, OUTPUT, POSTROUTING链中添加防火墙规则,以允许来自(或发往)绑定到virbr0设备的Guest的流量。它也会尝试启用ip_forward设置(net.ipv4.ip_forward = 1)。

和「虚拟网络」有关的另一个东西是dnsmasq服务,每个虚拟网络都会有一个对应的dnsmasq实例。参考「Libvirtd and dnsmasq」一文。

#2 对Guest配置

网络启动之后,就可以进行Guest的配置:

<!-- virsh edit --domain <guest> -->
<interface type='network'>
  <source network='default'/>
  <mac address='00:16:3e:1a:b3:4a'/>
</interface>

其中<mac>是可选的,如果没有设置会自动定义。

有关网络接口的定义,可以参考「Network interfaces」一文。

#3 生效网络修改

有时,需要编辑网络定义,并动态应用更改。最常见的场景是:为网络的DHCP服务器添加新的静态MAC IP映射。如果使用virsh net-edit编辑网络,则在网络被销毁并重新启动之后才会生效,但是这会导致所有Guest网络接口在重新连接之前失去与主机的网络连接。

对于这个问题,可以使用virsh net-update来解决。例如,添加MAC IP绑定:

virsh net-update default add ip-dhcp-host \
    "<host mac='52:54:00:00:00:01' name='bob' ip='192.168.122.45' />" \
    --live --config

除了add命令以外,还有deletemodifyadd-firstadd-last命令。除了ip-dhcp-host配置项,还有ip-dhcp-rangeforward-interfaceportgroupdns-hostdns-txtdns-srv配置项。详细的使用方法可以参考man 1 virsh手册。

注意:命令行中XML的内容应该是你要修改或者添加的内容;并且留意XML的转义;

当然,有些网络修改就是需要重启网络,这些修改无法通过virsh net-update来更新。重启会导致所有运行中的Guest从网络上断开连接。其中一个解决方案是在重启后连接所有的网络,官方给了一个「脚本」,但是那个连接打不开……应该是这个「脚本」。

# 转发“传入连接”

默认情况下,通过<forward mode='nat'/>的虚拟网络,「Guest」可以随意访问外部网络,也可以接受来自「Host」或者「同网络的Guest」的连接。

但是除了上述几种的连接,其他的“传入连接”都会被iptables规则屏蔽。

如果要解决这个问题,你可以为qemu设置libvirt的“钩子”脚本来设置必要的iptables规则(DNAT),来转发传入的连接,从指定的端口到Guest的端口。

实际上就是:使用libvirt的钩子在Guest启动(停止)时,添加(移除)防火墙规则。参考「Forwarding_Incoming_Connections」手册。

共享设备:网络桥接

#1 对Host配置

基于NAT的连接在“快速简单的部署”或者“动态网络”方面非常有用。但更高级的用户将希望使用「完全桥接」,其中Guest直接连接到LAN中。此设置依赖于发行版,不同的发行版在操作上有所不同。

!!!遗憾的是,如果通过无线接口(“wlanX”)连接到外部网络,则无线接口无法连接到Linux主机桥接器,因此,无法为Guest虚拟机使用此网络模式。

!!!如果在尝试使用网桥接口后,您发现网络链路已经死亡并且拒绝再次工作,则可能是上游路由器/交换机阻止网络中的“未授权交换机”(例如,通过检测BPDU数据包)。 您必须更改其配置以明确允许主机/网络端口作为“交换机”。

在Host上,如果使用NetworkManager来管理网络:

	* [[https://www.happyassassin.net/2014/07/23/bridged-networking-for-libvirt-with-networkmanager-2014-fedora-21/|Using nm-connection-editor UI]]
	* [[https://lukas.zapletalovi.com/2015/09/fedora-22-libvirt-with-bridge.html|Using the command line]]

在Host上,不使用NetworkManager来管理网络:

	* 对于RHEL/Fedora系列,使用传统的网桥配置方式及
	* 对于Debian系列,参考「[[https://wiki.debian.org/BridgeNetworkConnections|BridgeNetworkConnections]]」手册
	* 对于其他的发行版,也是类似的操作思路

这一步的目的是:添加桥接网卡「br0接口」(或其他),桥接到「eth0接口」(或其他)上。配置Guest时要用到该网卡。

#2 对Guest配置

为了让Guest使用此网桥,其配置应包括接口定义,如「Bridge to LAN」中所述。实质上,是在指定要连接的网桥名称。假设桥接器是名为“br0”的共享物理设备,则Guest虚拟机XML为:

<interface type='bridge'>
	<source bridge='br0'/>
	<mac address='00:16:3e:1a:b3:4a'/>
	<model type='virtio'/> <!-- # try this if you experience problems with VLANs -->
</interface>

其中,mac地址是可选的,如果忽略会自动生成。

使用virsh edit <VM name>来修改配置文件。

更多的问题参见FAQ中的条目「Where are VM config files stored? How do I edit a VM's XML config?

关于网络设备直通

可以把PCI网络设备“直通(Passthrough)”给Guest虚拟机。前提是Host必须支持「Intel VT-d」或「AMD IOMMU」技术。

有两种分配设备的方法:

	* 使用''<hostdev>''分配
	* 使用''<interface type='hostdev'>''分配(仅SRIOV设备)

#1 使用<hostdev>分配

设置一种传统的分配PCI设备的方法,不仅限于网卡,参考「libvirt PCI Device Assignment」一文

#2 使用<interface type='hostdev'>分配(仅SRIOV设备)

SRIOV网卡提供多个“虚拟功能”(VF),每个VF都可以使用“PCI设备分配”单独分配给Guest,每个都将充当完整的物理网络设备。 这允许许多Guest获得直接PCI设备分配的性能优势,而仅使用物理机器上的单个插槽。

这些VF可以使用<hostdev>以传统方式分配给Guest,但是这种方法最终会出现问题,因为(与常规网络设备不同)SRIOV VF网络设备没有永久唯一的MAC地址,而是每次重启Host操作系统时给出了一个新的随机MAC地址。结果是,即使每次为Guest虚拟机分配相同的VF,在每次重新启动主机后,Guest虚拟机都会看到其网络适配器具有新的MAC地址,这将导致guest虚拟机认为连接了新硬件, 需要重新配置Guest的网络设置。

主机可以在将VF分配给Guest虚拟机之前设置MAC地址,但是在<hostdev>设置中没有为此设置(因为<hostdev>用于通用PCI设备,它对特定功能项目,如MAC地址,一无所知)。 为了解决这个问题,libvirt-0.9.10添加了一个新的<interface type ='hostdev'>(「文档」)。 这种新型接口设备表现为<interface><hostdev>的混合体 - libvirt将首先执行任何特定于网络的硬件/交换机初始化(例如设置MAC地址,并与802.1Qbh交换机关联),然后执行PCI设备分配给Guest。

要使用<interface type ='hostdev'>,你必须具有支持SRIOV的网卡,并且支持Intel VT-d或AMD IOMMU扩展的Host硬件,并且您必须了解您希望分配的VF的PCI地址 (有关如何执行此操作的说明,请参阅此文档)。

验证/了解上述信息后,您可以编辑Guest的域配置,设置如下设备条目:

<interface type='hostdev' managed='yes'>
  <source>
    <address type='pci' domain='0x0' bus='0x00' slot='0x07' function='0x0'/>
  </source>
  <mac address='52:54:00:6d:90:02' />
  <virtualport type='802.1Qbh'>
    <parameters profileid='finance'/>
  </virtualport>
</interface>

请注意,如果您不提供mac地址,则会自动生成一个mac地址,就像使用任何其他类型的接口设备一样。此外,仅当您连接到802.11Qgh硬件交换机(802.11)时才会使用<virtualport>元素。此模式当前不支持Qbg(也称为“VEPA”)交换机。

当Guest虚拟机启动时,它应该看到物理适配器提供的类型的网络设备,具有配置的MAC地址。在Guest和Host重新启动后,此MAC地址将保持不变。

# 从“在libvirt的<network>定义的SRIOV VF池”中分配

将特定VF的PCI地址硬编码到Guest虚拟机配置中有两个严重的限制:

	(1)、在Guest虚拟机启动时,指定的VF必须可用,这意味着管理员必须将每个VF永久分配给单个Guest虚拟机(或者每次启动Guest虚拟机时修改Guest虚拟机的配置以指定当前未使用的VF的PCI地址)。
	(2)、如果将Guest虚拟机移动到另一台主机,则该主机必须在PCI总线上的相同位置具有完全相同的硬件(或者,同样必须在启动之前修改Guest虚拟机配置)。

从libvirt 0.10.0开始,可以避免这两个问题,通过创建一个“包含SRIOV设备的所有VF的设备池”的“libvirt网络”,然后配置Guest虚拟机以引用该网络。每次启动Guest时,将从池中分配一个VF并分配给Guest;当Guest停止时,VF将返回到池中以供另一位访客使用。

以下是一个示例网络定义,它将为SR-IOV适配器提供所有VF池,其PF(物理功能)位于主机上的“eth3”:

 <network>
   <name>passthrough</name>
   <forward mode='hostdev' managed='yes'>
     <pf dev='eth3'/>
   </forward>
 </network>

要使用此网络,请将上述文本放在例如/tmp/passthrough.xml中(将“eth3”替换为您自己的SR-IOV设备的PF的netdev名称),然后执行以下命令:

#!/bin/sh

virsh net-define /tmp/passthrough.xml
virsh net-autostart passthrough
virsh net-start passthrough.

虽然只显示了一个设备,但libvirt将在第一次使用接口定义启动Guest虚拟机时自动派生与该PF关联的所有VF的列表,如下所示:

  <interface type='network'>
    <source network='passthrough'>
  </interface>

您可以在启动使用网络的第一个Guest虚拟机后运行“virsh net-dumpxml passthrough”来验证这一点;将获得类似于以下内容的输出:

 <network connections='1'>
   <name>passthrough</name>
   <uuid>a6b49429-d353-d7ad-3185-4451cc786437</uuid>
   <forward mode='hostdev' managed='yes'>
     <pf dev='eth3'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x1'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x3'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x5'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x10' function='0x7'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x1'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x3'/>
     <address type='pci' domain='0x0000' bus='0x02' slot='0x11' function='0x5'/>
   </forward>
 </network>

相关文章

「KVM」- 常见错误及注意事项
「KVM」- CPU model and topology(未完)
「KVM」- 虚拟机迁移
「KVM」- Virt-Manager
「libvirt」- 离线迁移
「KVM」- Kimchi(Web管理工具)
「QEMU, KVM and libvirt」- 杂记
「KVM」- 环境搭建

参考文献

libvirt/Networking

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u013670453/article/details/114127117

智能推荐

class和struct的区别-程序员宅基地

文章浏览阅读101次。4.class可以有⽆参的构造函数,struct不可以,必须是有参的构造函数,⽽且在有参的构造函数必须初始。2.Struct适⽤于作为经常使⽤的⼀些数据组合成的新类型,表示诸如点、矩形等主要⽤来存储数据的轻量。1.Class⽐较适合⼤的和复杂的数据,表现抽象和多级别的对象层次时。2.class允许继承、被继承,struct不允许,只能继承接⼝。3.Struct有性能优势,Class有⾯向对象的扩展优势。3.class可以初始化变量,struct不可以。1.class是引⽤类型,struct是值类型。

android使用json后闪退,应用闪退问题:从json信息的解析开始就会闪退-程序员宅基地

文章浏览阅读586次。想实现的功能是点击顶部按钮之后按关键字进行搜索,已经可以从服务器收到反馈的json信息,但从json信息的解析开始就会闪退,加载listview也不知道行不行public abstract class loadlistview{public ListView plv;public String js;public int listlength;public int listvisit;public..._rton转json为什么会闪退

如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet-程序员宅基地

文章浏览阅读219次。如何使用wordnet词典,得到英文句子的同义句_get_synonyms wordnet

系统项目报表导出功能开发_积木报表 多线程-程序员宅基地

文章浏览阅读521次。系统项目报表导出 导出任务队列表 + 定时扫描 + 多线程_积木报表 多线程

ajax 如何从服务器上获取数据?_ajax 获取http数据-程序员宅基地

文章浏览阅读1.1k次,点赞9次,收藏9次。使用AJAX技术的好处之一是它能够提供更好的用户体验,因为它允许在不重新加载整个页面的情况下更新网页的某一部分。另外,AJAX还使得开发人员能够创建更复杂、更动态的Web应用程序,因为它们可以在后台与服务器进行通信,而不需要打断用户的浏览体验。在Web开发中,AJAX(Asynchronous JavaScript and XML)是一种常用的技术,用于在不重新加载整个页面的情况下,从服务器获取数据并更新网页的某一部分。使用AJAX,你可以创建异步请求,从而提供更快的响应和更好的用户体验。_ajax 获取http数据

Linux图形终端与字符终端-程序员宅基地

文章浏览阅读2.8k次。登录退出、修改密码、关机重启_字符终端

随便推点

Python与Arduino绘制超声波雷达扫描_超声波扫描建模 python库-程序员宅基地

文章浏览阅读3.8k次,点赞3次,收藏51次。前段时间看到一位发烧友制作的超声波雷达扫描神器,用到了Arduino和Processing,可惜啊,我不会Processing更看不懂人家的程序,咋办呢?嘿嘿,所以我就换了个思路解决,因为我会一点Python啊,那就动手吧!在做这个案例之前先要搞明白一个问题:怎么将Arduino通过超声波检测到的距离反馈到Python端?这个嘛,我首先想到了串行通信接口。没错!就是串口。只要Arduino将数据发送给COM口,然后Python能从COM口读取到这个数据就可以啦!我先写了一个测试程序试了一下,OK!搞定_超声波扫描建模 python库

凯撒加密方法介绍及实例说明-程序员宅基地

文章浏览阅读4.2k次。端—端加密指信息由发送端自动加密,并且由TCP/IP进行数据包封装,然后作为不可阅读和不可识别的数据穿过互联网,当这些信息到达目的地,将被自动重组、解密,而成为可读的数据。不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。2.使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。_凯撒加密

工控协议--cip--协议解析基本记录_cip协议embedded_service_error-程序员宅基地

文章浏览阅读5.7k次。CIP报文解析常用到的几个字段:普通类型服务类型:[0x00], CIP对象:[0x02 Message Router], ioi segments:[XX]PCCC(带cmd和func)服务类型:[0x00], CIP对象:[0x02 Message Router], cmd:[0x101], fnc:[0x101]..._cip协议embedded_service_error

如何在vs2019及以后版本(如vs2022)上添加 添加ActiveX控件中的MFC类_vs添加mfc库-程序员宅基地

文章浏览阅读2.4k次,点赞9次,收藏13次。有时候我们在MFC项目开发过程中,需要用到一些微软已经提供的功能,如VC++使用EXCEL功能,这时候我们就能直接通过VS2019到如EXCEL.EXE方式,生成对应的OLE头文件,然后直接使用功能,那么,我们上篇文章中介绍了vs2017及以前的版本如何来添加。但由于微软某些方面考虑,这种方式已被放弃。从上图中可以看出,这一功能,在从vs2017版本15.9开始,后续版本已经删除了此功能。那么我们如果仍需要此功能,我们如何在新版本中添加呢。_vs添加mfc库

frame_size (1536) was not respected for a non-last frame_frame_size (1024) was not respected for a non-last-程序员宅基地

文章浏览阅读785次。用ac3编码,执行编码函数时报错入如下:[ac3 @ 0x7fed7800f200] frame_size (1536) was not respected for anon-last frame (avcodec_encode_audio2)用ac3编码时每次送入编码器的音频采样数应该是1536个采样,不然就会报上述错误。这个数字并非刻意固定,而是跟ac3内部的编码算法原理相关。全网找不到,国内音视频之路还有很长的路,音视频人一起加油吧~......_frame_size (1024) was not respected for a non-last frame

Android移动应用开发入门_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量-程序员宅基地

文章浏览阅读230次,点赞2次,收藏2次。创建Android应用程序一个项目里面可以有很多模块,而每一个模块就对应了一个应用程序。项目结构介绍_在安卓移动应用开发中要在活动类文件中声迷你一个复选框变量

推荐文章

热门文章

相关标签