/etc/libvirt/qemu.conf:

/etc/libvirt/qemu.conf:

Ubuntu Server 14.04 主机通过 libvirt/qemu-kvm 托管 Ubuntu Server 14.04 客户机。系统运行良好,但作为客户机,我在写入共享文件夹 ( <filesystem>) 时遇到了问题,这让我很恼火。两台机器都是相对原始的安装。

我像这样附加了给定的文件夹:

[host] $ virsh edit guest-vm-name
# ...
<filesystem type='mount' accessmode='mapped'>
  <source dir='/data'/>
  <target dir='/data'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</filesystem>
# ...

从客户机上我挂载文件系统如下:

[guest] $ sudo -u www-data mkdir /tmp/mnt
[guest] $ sudo mount -t 9p -otrans=virtio,rw,version=9p2000.L /data /tmp/mnt

我使用www-data用户,因为稍后这将是有效用户,并且如果使用 p9,则组和用户 ID 必须匹配,据我所知。这也意味着在主机上,/data(顺便说一下,是 ext4 分区,RAID 上的 LVM)看起来像

[host] $ ls -lha /data
[host] $ drwxrwxr-x  4 www-data www-data 4.0K Nov 11 08:34 .
[host] $ drwxr-xr-x 24 root     root     4.0K Nov  7 16:58 ..
[host] $ drwxr-xr-x  2 www-data www-data 4.0K Nov 11 08:34 jail
# ...

在客户机中,如果我尝试写入共享文件系统上的任何内容,我会收到权限错误(无论使用哪个用户):

[guest] $ sudo -u www-data touch /tmp/mnt/jail/letmeout
touch: cannot touch ‘/tmp/mnt/jail/letmeout’: Permission denied

我可以读取文件

[guest] $ cat /tmp/mnt/jail/throughthewindow
Great Weather!

我尝试了各种各样的方法,特别是:

  • 停止 apparmor 服务并致电 aa-complain(我希望这有效)
  • 将安全性设置为无/etc/libvirt/qemu.conf
  • 将用户和组设置为 root/etc/libvirt/qemu.conf

/var/log/syslog 和 dmesg 没有显示任何可疑内容。

有什么指点吗?!谢谢。

答案1

我知道这是一个老话题,但我刚刚遇到了类似的问题并找到了一个有效的解决方案至少部分

我还将用户和组值更改/etc/libvirt/qemu.conf,就像你一样。
但我也改变了dynamic_ownership设置,因为描述听起来很有希望:

# libvirt 是否应动态更改文件所有权
# 以匹配上面配置的用户/组。默认为 1。
# 设置为 0 以禁用文件所有权更改。

我的设置是:

  • 主机:Debian 8(Jessie)
  • 嘉宾:Debian 8 (Jessie)
  • 主机上的共享文件夹属于root
  • ID 为 1000 的本地用户是该组的成员libvirt(可能很重要)
  • 来宾上的挂载点 ( /mnt/data) 属于用户 1000(“alexander”)

我现在终于可以使用以下方法在已挂载的共享文件夹中写入文件两个都root(0) 和 alexander(1000)。(在我这样做之前,只有 root 才被允许在此处写入文件)

dynamic_ownership在“映射”访问模式下必须将其设置为 0。

以下是有关我的设置的更多信息:

/etc/libvirt/qemu.conf:

user = "root"
group = "root"
dynamic_ownership = 0

文件系统(virsh 编辑):

<!-- ... -->
    <filesystem type='mount' accessmode='mapped'>
      <source dir='/share/vm.localdomain/owncloud_data'/>
      <target dir='/data'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </filesystem>
<!-- ... -->

主持人:

ls -al /share/vm.localdomain/owncloud_data/
total 8
drwxr-xr-x 2 root      root      4096 Sep  8 00:15 .
drwxr-xr-x 7 root      root      4096 Sep  8 00:10 ..

来宾上的 fstab:

/data  /mnt/data/  9p  trans=virtio  0  0

客人:

root@debian:~# cd /mnt/data
root@debian:/mnt/data# touch touched_by_root
root@debian:/mnt/data# su - alexander
alexander@debian:~$ cd /mnt/data
alexander@debian:/mnt/data$ touch touched_by_user
alexander@debian:/mnt/data$ ls -al
total 16
drwxr-xr-x 2 alexander alexander 4096 Sep  8 00:30 .
drwxr-xr-x 6 root      root      4096 Sep  7 18:13 ..
-rw-r--r-- 1 root      root         0 Sep  8 00:30 touched_by_root
-rw-r--r-- 1 alexander alexander    0 Sep  8 00:30 touched_by_user

回到主机:

root@Host /share/vm.localdomain # ls -al /share/vm.localdomain/owncloud_data/
total 16
drwxr-xr-x 2 root      root         4096 Sep  8 00:30 .
drwxr-xr-x 7 root      root         4096 Sep  8 00:10 ..
-rw------- 1 root      libvirt-qemu    0 Sep  8 00:30 touched_by_root
-rw------- 1 root      libvirt-qemu    0 Sep  8 00:30 touched_by_user

结论

奇怪的是,在客户机上,这两个文件属于不同的用户(root 与 alexander),而在主机上,两个文件都属于同一个用户(root:libvirt-qemu)。:-O
我不知道具体情况魔法是如何运作的,但显然确实如此。

希望这有帮助,
亚历山大

答案2

@Alexander 的回答很棒。我没有像他那样做所有事情,但我确实做了以下事情来获得同一用户权限在 9p 文件系统中双向工作。(此方法旨在使 9p 双向工作,而不会出现安全问题。为了获得更高的安全性,您将需要不同的方法或设置)

主持人(顺序不重要)

  • 我将我的主机用户添加到以下组:<虚拟机> (我也是 <libvirtd>)。此步骤可能没有必要,因为:

  • 在文件中/etc/libvirt/qemu.conf您可以更改所有虚拟机进行身份验证和执行的用户和组。

这是一个强大的变化不大,如果你尝试在生产服务器等设备上实现此操作,则需要规划出其影响

user = "billy"    #### No, my name isn't billy, but it's cute. 
                  #### Alternatively you can declare your <uid>, like
                  ## user = "+1000" ####        << That's what I did.
                  #### (They tell you everything you need to know about
                  #### this stuff inside /etc/libvirt/qemu.conf)
group = "billy"
dynamic_ownership = 1

(上述更改的作用是告诉虚拟机主机将您正在运行的任何客户虚拟机的所有 libvirt 跨虚拟机请求转换为 <用户> 您设置的;包括 guest-VM <>。*笔记 再次这是一个系统范围的设置,涉及虚拟器并延伸而言库姆如果虚拟器你唯一的库姆界面。)

(顺便说一下,“Squash” 指的是 9p 安全模型。它的意思是“无”,是此上下文中最宽松的设置)

客人

(我还添加了一个选项,如下面文档中所述)我的挂载命令是:

mount -t 9p -o trans=virtio,access=any,version=9p2000.L /hostshare /tmp/host_files

请记住,如果您在设置后没有权限写入共享或权限有限,@randomocean 的回答中的出色建议应该会有所帮助。也就是说,有 <> 在共享下创建一个文件夹,并设置chmod 777它。

-更多信息:https://wiki.qemu.org/Documentation/9psetup

答案3

当我尝试将目录从 Ubuntu 主机挂载到 Minikube 的 VM 时,我遇到了同样的问题。问题没有指定 Minikube,但这并不重要,因为它是由 QEMU/KVM 运行的 VM。以下说明应适用于任何 QEMU/KVM VM。我找不到有关如何将主机目录挂载到 KVM VM 的具体说明。我搜索了很多,非常累人。我将解释我如何处理权限错误以及符号链接错误或“未知错误 526”错误。我将简要说明为什么需要进行此设置,只是为了包含一些关键字,遇到相同问题的人在搜索解决方案时可能会使用它们。

问题

我通过 VirtualBox 运行 Minikube。VirtualBox 可以/Users在 MacOS 或/homeLinux 上安装到 VM 中,而且您不需要像使用 KVM 那样处理安装问题。我需要开发一个 Android 应用程序,其后端应在 Kubernetes 上运行。为了测试 Android 应用程序,我需要运行虚拟设备,这些设备通过 Linux 上的 KVM 运行。不能同时在 VirtualBox 上运行 VM 和在 KVM 上运行 VM,因为它们中一次只能有一个可以使用 CPU 的虚拟化技术。当我需要在 Android 应用程序中检查某些内容时关闭 Minikube 会非常不方便,反之亦然。由于可以同时在 KVM 上运行许多 VM,因此我决定在 KVM 上运行 Minikube,只是为了同时运行 Minikube 和 Android 虚拟设备。也可以使用 VirtualBox 同时运行许多 VM,但默认的 Android 虚拟设备不在 VirtualBox 上运行。看起来 Genymotion 使用 VirtualBox,但它是一种付费解决方案。

目标

我的目标是像 VirtualBox 一样挂载包含我的应用程序文件的目录。Minikube 可以通过命令从主机挂载目录minikube mount,但在撰写本文时,由于某种原因,它并不可靠。Unknown error 526当我尝试访问文件时,它给了我提示。它也非常慢。

事实上,@Alexander 的回答帮助我解决了这个问题。但是,这还不够,因为我不想以 的身份运行虚拟机root。当它们以 的身份运行时root,在虚拟机内创建的文件和/或目录在主机中具有root:root权限,这是我不想要的。

解决方案

定义运行虚拟机的用户

首先,我编辑了/etc/libvirt/qemu.conf文件(在主机上),将运行 VM 进程的用户更改为我的用户,即ubuntu,并禁用dynamic_ownership

user = "ubuntu"
group = "ubuntu"
dynamic_ownership = 0

进行上述更改后,我重新启动了主机,因为我不知道如何应用更改。如果不重新启动,虚拟机将继续以前一个用户的身份运行,即libvirt-qemu。要确保更改已应用,请执行以下操作:

  1. 在主机上运行ps aux | grep kvm
  2. 检查运行 VM 进程的用户。ubuntu在这种情况下您应该会看到。

定义挂载卷

接下来,添加Filesystem硬件Virtual Machine Manager

  1. 在主机上,Virtual Machine Manager通过运行打开virt-manager
  2. 双击虚拟机并选择View > Details
  3. Details窗口中单击Add Hardware
  4. Filesystem像这样选择并配置它:
Type: mount (only option)
Driver: Path
Mode: Squash
Write Policy: Immediate
Source Path: <absolute path to the directory you want to mount into the VM>
Target Path: hosthome # Or any other keyword or path that will be used to define the mount so that we can reference it when mounting it in the VM

# Do not check "Export filesystem as readonly mount"
  1. 单击Apply。如果虚拟机正在运行,则更改将在下次启动时应用。

Squashmode 很重要,因为它可以处理符号链接。其他模式都给我带来了too many levels of symbolic links错误。modePassthrough解决了 mode 带来的问题Mapped,但这还不够。modeSquash是没有给我带来任何错误的模式。

解决运行虚拟机时可能出现的权限问题

现在,启动(或重新启动,如果正在运行)虚拟机。如果在启动虚拟机时出现权限错误,则需要确保用于运行虚拟机的文件属于您在qemu.conf文件中定义的用户。就我而言,我通过检查错误消息更改了主机上以下文件的权限:

chown ubuntu:kvm ~/.minikube/machines/minikube/boot2docker.iso # Previously belonged to "libvirt-qemu" user
chown ubuntu:root ~/.minikube/machines/minikube/minikube.rawdisk # Previously belonged to "root" user

将卷安装到虚拟机

接下来,剩下要做的就是将卷挂载到虚拟机中。进入虚拟机(在我的情况下是通过)minikube ssh,然后挂载卷:

# First, create the directory to which the the volume will be mounted. This might not be necessary in your case.
sudo mkdir -p /hosthome/ubuntu/Projects

# Then, mount the volume
sudo mount -t 9p -o trans=virtio,version=9p2000.L,cache=none,msize=262144,rw hosthome /hosthome/ubuntu/Projects
  • cache=none:这是为了提高性能。您可以根据自己的情况将其更改为其他值。这些值的解释如下这里
  • msize=262144:这也是为了提高性能。这定义了“9p 数据包有效负载使用的字节数”,如解释的那样这里。这是 使用的默认值minikube mount
  • rw: “以读写方式挂载文件系统”,如 中所述man mount。这是命令的一个选项mount

就是这样。您应该能够从虚拟机内部读取和写入文件/目录而不会出现任何问题。如果/etc/fstab可以修改虚拟机内的文件,则可以将安装逻辑添加到文件中,以便在虚拟机启动后自动安装卷。不幸的是,这对于 Minikube 来说是不可能的(请参阅Disadvantages章节)。

通过此设置我获得了什么

此设置帮我解决的问题是:

  • minikube mount速度慢,而且不可靠,正如文档。文档说 9p 支架不可靠,但这种设置比更可靠minikube mount
  • 挂载目录中 Docker 容器创建的文件/目录在ubuntu:ubuntu主机上具有所有权。因此,我可以从 IDE 内部访问它们并根据需要进行更改。以前,它们具有root:root所有权,而主机上的用户没有。
  • 我不再得到Unknown error 526我曾经得到过的东西minikube mount
  • 性能高于minikube mount
  • 我可以同时运行带有硬件加速的虚拟 Android 设备以及 Kubernetes 集群,这样开发就方便多了。实际上,开发现在“可能”了。

缺点

  • 对于 Minikube,每次启动时都应手动挂载卷minikube。这是因为 Minikube 不会保留对/etc/fstab文件所做的更改。作为一种方便的解决方法,mount可以在目录中创建一个包含命令的 shell 脚本/data,该脚本在 VM 重新启动后仍然存在,并且可以在 VM 启动后从 VM 内部执行它。

参考

答案4

对我来说,在主机上调整适当的 ACL 掩码就可以了:

sudo setfacl -Rm u:libvirt-qemu:rwx /data

(Ubuntu Server 20.04 主机、Debian 10 客户机和直通访问模式)

更新2023/09/14:

现在,我使用虚拟而不是提供更好体验的 9p(性能更高、没有权限问题、适用于 Linux 和 Windows 客户机)。

相关内容