我已经使用 libvirt 在 KVM/qemu 中运行了多个虚拟机,并且大多数时候网络都可以正常工作。
现在,当虚拟机以非 root 用户身份运行时,网络已停止工作。我在 libvirt 和类似的文档页面中发现了一些有用的信息 - 大多数人似乎认为我希望以系统用户身份运行虚拟机,但事实并非如此。
所以:以非 root 身份运行带有网络的虚拟机(例如来宾中的网页浏览)到底有哪些先决条件?
我有,在myvm.xml
:
94 <interface type='user'>
95 <mac address='52:54:00:82:f1:27'/>
96 <model type='virtio'/>
97 <link state='up'/>
98 <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
99 </interface>
该接口在访客内部可见,并且启用 DHCP 客户端会提供地址 10.0.2.5。默认路由是 10.0.2.2,我可以从网络内部 ping 通该路由。超出这个范围的任何事情都会失败。
我的主机没有网桥(或 libvirtd 的任何设备),但我不需要在 user-libvirtd 中进行用户模式 NAT,对吧?从技术上讲,网络访问来自 user-libvirtd?
运行 libvirtd 的用户位于组kvm
和中libvirt
。 我需要哪一个来做什么? 后者对于运行虚拟机来说不是必需的,并且对我的问题没有影响。
我已libvirtd
在主机上以 root 身份启用并启动。这提供了一个网桥,virbr0
但似乎我的非 root 用户无法访问它,所以这没有任何区别。 我libvirtd
到底需要吗?
请注意,该虚拟机可能无法以 root 身份运行,因此这对我来说不是一个解决方案。用户可能没有提升的权限或访问同一主机上其他人的虚拟机的权限。
答案1
哇!我们来进行第三轮!让我们看看最终能否让它发挥作用。开始。
首先,我的虚拟机实际上曾是在 qemu:///system 中,而不是在 qemu:///session 中。因此,即使我不必输入 root 密码,虚拟机也必须以 root 身份运行(?!他们为什么要这样做?!)。因此,这里尝试在 qemu:///session 中尝试虚拟机。 (我在执行步骤时输入此内容是为了看看是否可以重现您的问题并解决它,所以如果我这样做时看起来有点计划外,那是因为它确实如此。)
因此,首先我进入 virt-manager,并开始建立与默认连接不同的 QEMU/KVM 新连接 - 这次我使用“QEMU/KVM 用户会话”。当我在 virt-manager 中选择它时,它告诉我“网络选项非常有限”。所以这看起来就是问题开始的地方。让我们看看我是否能绕过它。
建立连接后,现在我将在其中创建一个新的 KolibriOS VM,看看会发生什么。
因此,在 VM 创建过程中,virt-manager 不再看到包含 VM 安装程序的 ISO 文件目录。因此,我将添加一个指向 ISO 文件的新存储池,以便我可以实际创建虚拟机。 (目录:/home/user/ISO 文件)
好的,现在我可以访问我的 ISO 了。现在,我将使用我的“kolibri.iso”文件创建新的 KolibriOS VM。 (操作系统类型:通用默认值,CPU 数量:1,内存:256 MB。Kolibri 是一个小型操作系统。)
我不会为虚拟机提供任何磁盘存储,因为 KolibriOS 设计为直接脱离 ISO 使用。
现在,终于到了最后,我注意到一件有趣的事情。我可以选择使用用户模式网络或共享设备名称。我将从用户模式网络开始,如果这不起作用,我们将使用共享设备“virbr0”再次尝试,看看会发生什么。
我点击了“完成”按钮。现在我的虚拟机应该很快就能启动。
好的,它启动了,我收到“您现在已连接到网络”。看起来很有希望。
现在我已经打开了 WebView,我将转到“Kolibri Stuff”,看看会发生什么。如果可行的话,我会看看是否可以访问 Google。
“Kolibri Stuff”按钮起作用了 - 现在我看到了页面“http://store.kolibri-n.org/en.html”。现在让我们尝试一下谷歌。
果然,有谷歌,还有它的隐私政策链接。让我们看看如果我点击它会发生什么。
嗯,很明显 WebView 不明白这个页面到底在说什么,但我的屏幕上确实看到了一大堆复杂的 JavaScript,所以显然它下载了一些东西。让我们尝试一下 NSInstall。
好的,必须下载 NetSurf 应用程序。如果可以下载,我认为网络正常。
下载完成。现在让我们再次尝试谷歌。
好吧,NetSurf 不喜欢 Google。让我们试试德多梅多。这基本上是一堆 Linux 评论之类的东西。
最终结论——NetSurf 太臭了!我要回到 WebView。 (http://www.dedoimedo.com/index.html)。最后!它开了!
因此,由于我可以成功地浏览我的用户模式虚拟机内部,我认为这是有效的。 “virsh -c qemu:///session list”现在显示我的“UserKolibriOS”虚拟机正在运行。这是它显示的内容:
Id Name State
-------------------------------
1 UserKolibriOS running
“virsh -c qemu:///system list”现在显示:
Id Name State
--------------------
所以,我有一个用户模式虚拟机可以很好地访问互联网。现在,让我们再试一次,做同样的事情,但这次使用 Lubuntu 18.04,以便我们获得 virtio 网络适配器。 (我正在做这一系列测试,因为我想在向您倾倒大量配置文件之前绝对确保一切正常。)
这是我的 Lubuntu 18.04 VM 配置:2 个 CPU、1024 MB RAM、用户模式网络、无虚拟硬盘。
好的,VM 正在启动。让我们看看发生了什么。
虚拟机已启动。它似乎认为它已连接到网络。我要打开谷歌并搜索“蓝屏死机”,看看会发生什么。
哇!我的虚拟机中的互联网似乎比我的物理系统上的互联网运行得更快。我能够从我的搜索中找到维基百科上的“蓝屏死机”,并将其打开。我现在正盯着虚拟机窗口上一张相对严峻的 Windows 10 画面。因此,我得出的结论是,用户模式网络对于虚拟机中的网页浏览工作得很好。现在,让我们看看我的配置正在做什么。
首先,我注意到当我启动 KolibriOS VM 以及启动 Lubuntu 18.04 VM 时,屏幕上没有出现“connected to tun vnet0”。
现在,这是网络适配器配置,首先是 KolibriOS:
<interface type="user">
<mac address="52:54:00:6f:ab:33"/>
<model type="e1000"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0"/>
</interface>
现在,Lubuntu 18.04 如下所示:
<interface type="user">
<mac address="52:54:00:7d:63:ba"/>
<model type="virtio"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</interface>
所以现在我的配置看起来与你的相同,除了我的配置缺少有关“link state =“up””的位。然而,我的网络有效,而你的却无效。唔...
我现在能想到的是,您的虚拟机操作系统中的网络设置一定无法正常工作,并且您的虚拟机本身必须配置完美。
最后,我将使用共享设备“virbr0”运行最后一项测试 - Lubuntu 18.04。让我们看看它是否可以与网桥一起使用,即使它是一个用户模式虚拟机。
彻底失败!当我尝试时,我的屏幕上出现了这样的混乱:
Unable to complete install: 'internal error: /usr/lib/qemu/qemu-bridge/helper
--br=virbr0 --fd=29: failed to communicate with bridge helper: Transport
endpoint is not connectedH001F007F stderr=failed to parse default acl file`/
-etc/qemu/bridge.conf''
什么?!显然它不想连接到我的网桥。我认为你是对的,桥接网络根本无法在用户模式虚拟机上工作。但用户模式网络确实有效,所以没有必要。
我确实注意到您给我的有关用户模式网络信息的链接上的一些内容。它有一个关于 QEMU 网络的页面的链接,该页面以用户模式网络结束。它最后表示,“这个选项确实提供了一个非常有用的默认值,因为来宾操作系统将具有基本上透明的网络访问,几乎就像主机上运行的任何其他应用程序一样。” (这是在“https://people.gnome.org/~markmc/qemu-networking.html”。)QEMU 实际上允许连接到互联网吗?或者它被某种方式阻止了?不确定是否有可能在 Linux 中阻止单个进程访问 Internet,但也许吧。如果 QEMU 无法连接,VM 将无法连接。
所以,最终结论 - 我认为这是虚拟操作系统的问题,而不是虚拟机的配置问题。尝试 Lubuntu 18.04 - 它立即可用,开箱即用。您可以从这里下载:“https://lubuntu.me/downloads/”。看看那里的网络是否有效。除此之外,看起来你做的一切都是正确的。
编辑 - 这个问题最终通过编辑虚拟操作系统中“/etc/resolv.conf”中的一些内容得到解决。这适用于 Ubuntu 和 Arch Linux。用户模式网络现在可以工作了。谢谢内德64! (有关详细信息,请参阅下面 Ned64 的评论。)
希望这可以帮助!
答案2
我正在使用最新版本的 QEMU/KVM/LibVirt。我的网络在非 root 用户上运行得很好,但我做我的系统上有一个网桥。此外,当我启动虚拟机时,我会收到一条“连接已建立”消息,表明虚拟机启动时主机系统已连接到“tun vnet0”。 (当然,我同时运行的每个附加虚拟机的数量都会增加 - 第二个虚拟机会导致与 vnet1 的连接,等等)您缺少网桥可能是问题所在。
这就是我测试这个理论时发生的情况。我有一个运行 KolibriOS 的虚拟机(安装起来有点痛苦,但它最终工作了!)我最初是在网桥打开时创建它的。互联网一开始就运行得很好。我在网桥仍然打开的情况下启动了 KolibriOS,然后在完全启动后关闭了网桥。然后我无法从虚拟机内访问互联网。我注意到主机上的 vnet0 连接丢失。我重新打开网桥,虚拟机仍然无法连接。然后我关闭了虚拟机,并关闭了网桥。然后我什至无法启动虚拟机,因为它的“默认”网络有问题。我重新打开网桥,然后尝试启动虚拟机。它打开了,并再次可以访问互联网。
因此,这使我得出这样的结论:为了访问任何类型的网络,都需要网桥。尝试打开网桥。您可能还需要对 VM 的虚拟网络适配器 (NAT) 进行一些更改,以使其使用网桥。
此外,只有当虚拟网络适配器的链接状态处于活动状态时,我的虚拟机才能连接到网络。转至 VM 窗口上的“详细信息”屏幕,单击 NIC 条目,然后查看“链接状态:活动”复选框是否已选中。不过,我怀疑这就是问题所在,因为您的 XML 代码说 .
最后,这是我的 KolibriOS VM 的虚拟网络适配器中能够连接到 Internet 的 XML 代码:
<interface type="network">
<mac address="52:54:00:18:a8:56"/>
<source network="default" portid="2090855d-4e56-4e55-ad97-9fad39d782ba" bridge="virbr0"/>
<target dev="vnet0"/>
<model type="e1000"/>
<link state="up"/>
<alias name="net0"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0"/>
</interface>
我希望这有帮助!访客中的网页浏览与此设置完美配合 - 我可以通过 WebView 工具访问 KolibriOS 主页和 Google,而当网桥关闭时我无法访问。
我以非 root 用户的身份完成了所有这一切 - 我从来不需要输入密码来完成整个实验,所以即使没有 root 访问权限,这也应该可以正常工作。
答案3
这是对 Ned64 对我上一个答案的两条评论的回应。我以访客用户身份发帖,所以我不能只回复评论 - 我必须写一个全新的答案,所以如果您想知道“为什么不直接回复评论?”,现在您知道了。另外,我的回答事实证明非常有力,所以无论如何它都不适合评论部分。
好的,开始了。
一些可能有用的信息 - 我正在使用 virt-manager 来管理和使用我的虚拟机。我的计算机上使用的是 Lubuntu 20.04 64 位操作系统。我的所有虚拟机(KolibriOS、PuppyLinux 和 Lubuntu 18.04)都可以访问 Internet。
我没有让其他人为我创建网桥。从我安装 QEMU、libvirt 和 virt-manager 时起,它就在那里。然而,当我安装所有这些东西时,出现了一个新用户(称为 libvirt-qemu),以及三个新组(称为 libvirt、libvirt-qemu 和 libvirt-dnsmasq),并且我注意到它可以访问一些我的标准用户无法访问的目录(如 /var/lib/libvirt/images),因此我假设 libvirt-qemu 负责我的网桥。另外,我的默认用户位于 libvirt 组中,这是我不必自己做的事情 - 同样,安装例程一定已经为我完成了这件事。
这是我的“brctl show”的输出:
bridge name bridge id STP enabled interfaces
virbr0 8000.5254006b64fb yes virbr0-nic
无论如何,如果我单击网络图标,我可以在活动连接列表中看到“virbr0”,因此我的物理计算机连接到“virbr0”网络,就像连接到真正的以太网一样。
我注意到,如果我在虚拟机启动并连接到互联网时执行“brctl show”,那么它看起来会有点不同;如果我这样做,会发生以下情况:
bridge name bridge id STP enabled interfaces
virbr0 8000.5254006b64fb yes virbr0-nic
vnet0
此外,当虚拟机打开时,“vnet0”会出现在我的活动连接中,而当我关闭虚拟机时,它就会消失。
以下是我在没有运行虚拟机的情况下从“virsh net-dumpxml default”获得的信息:
<network>
<name>default</name>
<uuid>940f02c2-f3ba-4f25-ad0f-5876a41b5d3b</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr0' stp='on' delay='0'/>
<mac address='52:54:00:6b:64:fb'/>
<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>
我还在虚拟机运行时执行了“virsh net-dumpxml default” - 这没有什么区别。
另一个可能有用的注释 - 我的用户位于 libvirt 组中,但不在 kvm 组中。这可能会有所帮助,或者可能只是令人困惑。
最后一点 - 我看到具有正确网络的虚拟机的 XML 代码使用“e1000”模型类型,但您的虚拟机使用“virtio”。以下是使用 virtio 网络适配器且具有工作互联网的虚拟机的代码:
<interface type="network">
<mac address="52:54:00:97:df:ec"/>
<source network="default" portid="59b9b7c2-9453-43b6-8420-99961b5065c7" bridge="virbr0"/>
<target dev="vnet0"/>
<model type="virtio"/>
<alias name="net0"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</interface>
这是一个运行 ISO 文件的实时 Lubuntu 18.04 64 位虚拟机 - 我可以在其中正常访问互联网。
希望这可以帮助!