I came across the same problem when I was trying to mount a directory from Ubuntu host to Minikube's VM. The question does not specify Minikube, but it does not matter since it is a VM run by QEMU/KVM. The instructions below should apply to any QEMU/KVM VM. I could not find specific instructions on how to mount host directories into KVM VMs. I searched a lot and it was quite tiresome. I will explain what I did to handle permission errors as well as symlink errors or "Unknown error 526" errors. I am going to mention briefly why it was necessary to have this setup, just to include a few keywords that someone having the same issues might use when searching for a solution.
Problem
I was running Minikube via VirtualBox. VirtualBox can mount /Users
on MacOS, or /home
on Linux, into the VM, and you do not need to tackle mounting problems as much as you have to do with KVM. I needed to develop an Android application whose backend should run on Kubernetes. To test the Android application, I need to run virtual devices, which are run via KVM on Linux. One cannot run a VM on VirtualBox and a VM on KVM at the same time, because only one of them can use the CPU's virtualization technology at a time. It would be quite an inconvenience to shut down Minikube when I would need to check something in the Android application or vice versa. Since it is possible to run many VMs on KVM at the same time, I decided to run Minikube on KVM just for the sake of running both Minikube and Android virtual devices at the same time. It is also possible to run many VMs at the same time with VirtualBox, but the default Android virtual devices are not run on VirtualBox. It looks like Genymotion uses VirtualBox but it is a paid solution.
Goal
My goal was to mount the directory that contains my application files just like VirtualBox mounts. Minikube can mount directories from host via minikube mount
command, but, at the time of writing, it is not reliable for some reason. It gave me Unknown error 526
while I tried to access the files. It is also very slow.
@Alexander's answer helped me solve the issue, in fact. But, it was not quite enough, since I did not want to run the VMs as root
. When they are run as root
, the files and/or directories created inside the VMs have root:root
permission in the host, which I do not want.
Solution
Defining the user that runs VMs
First of all, I edited /etc/libvirt/qemu.conf
file (on the host) to change the user who runs the VM processes as my user, which is ubuntu
, and to disable dynamic_ownership
:
user = "ubuntu"
group = "ubuntu"
dynamic_ownership = 0
After making the change above, I restarted my host machine, since I do not know how to apply the changes otherwise. Without a restart, the VMs kept being run as the previous user, which was libvirt-qemu
. To ensure the change has been applied, do the following:
- On your host machine, run
ps aux | grep kvm
- Check the user that runs the VM processes. You should see
ubuntu
in this case.
Defining the mount volume
Next, add a Filesystem
hardware in Virtual Machine Manager
:
- On the host, open
Virtual Machine Manager
by running virt-manager
- Double click on the VM and select
View > Details
- In the
Details
window, click Add Hardware
.
- Select
Filesystem
and configure it like so:
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"
- Click
Apply
. If the VM was running, the changes will be applied at the next boot.
Squash
mode is important, because it can handle symbolic links. The other modes gave me too many levels of symbolic links
errors. Passthrough
mode solved the issues that Mapped
mode gave, but it was not enough. Squash
mode is the mode that did not give me any errors.
Solving permission issues that might occur when running the VM
Now, start (or restart if it was running) the VM. If you get permission errors while starting the VM, then you need to make sure that the files used to run the VM belong to the user you defined in qemu.conf
file. In my case, I changed the following files' permissions on the host by examining the error messages:
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
Mounting the volume to the VM
Next, the only thing left to do is to mount the volume into the VM. Get into the VM, in my case via minikube ssh
, and then mount the volume:
# 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
: This is for improved performance. You can change this to another value depending on your case. The values are explained here.
msize=262144
: This is for improved performance as well. This defines "the number of bytes to use for 9p packet payload", as explained here. This is the default value used by minikube mount
.
rw
: "Mount the filesystem read-write", as explained in man mount
. This is an option of mount
command.
That's it. You should be able to read and write files/directories from within the VM without any issues. If /etc/fstab
file inside the VM can be modified, the mounting logic can be added into the file so that the volume is mounted automatically after the VM starts. Unfortunately, this is not possible for Minikube (See Disadvantages
section).
What I gained with this setup
The problems this setup solved for me are:
minikube mount
was slow and unreliable, as it is explained in the documentation. The documentation says that 9p mounts are unreliable, but this setup is more reliable than minikube mount
.
- The files/directories created by Docker containers inside the mounted directory have
ubuntu:ubuntu
ownership on the host. So, I can access them from within the IDE and change them as I please. Previously, they had root:root
ownership, which my user on the host did not have.
- I no longer get
Unknown error 526
which I got with minikube mount
- The performance is higher than
minikube mount
- I can run virtual Android devices with hardware acceleration as well as a Kubernetes cluster at the same time such that the development is much more convenient. Actually, the development is "possible" now.
Disadvantages
- For Minikube, the volume should be mounted manually each time
minikube
is started. This is because Minikube does not persist the changes made to /etc/fstab
file. As a convenience workaround, a shell script that contains the mount
command can be created inside /data
directory, which survives through VM restarts, and it can be executed from within the VM, after the VM is started.
References