Skip to content

Commit ca9eb87

Browse files
committed
drivers: Add Virtiofs mounts for vfkit and krunkit
Replace 9p mounts with virtiofs for vfkit and krunkit. Testing shows that virtiofs mount is 23 times faster with krunkit, and 8 times faster with vfkit. vfkit and krunkit support multiple virtiofs mounts but minikube --mount-* flags are not ready for multiple mounts. We have the same issue with KIC drivers, supporting multiple mounts but using only one. We hope to improve this in the next release. Example usage: minikube start --mount-string ~/models:/mnt/models The arguments are parsed and validated when configuring the driver, so invalid arguments fail quickly without starting the driver. The validated mounts are stored in the machine config: $ jq '.Driver.VirtiofsMounts' < ~/.minikube/machines/minikube/config.json [ { "HostPath": "/Users/joe/models", "GuestPath": "/mnt/models", "Tag": "f845b54d-00e3-493d-9541-3b37490b96db" } ] Minikube generates a new random UUID for every virtiofs mount to identify the file system inside the guest. In krunkit and vfkit, every mount is add as: --device virtio-fs,sharedDir=/host-path,mountTag=f845b54d-00e3-493d-9541-3b37490b96db When the guest is started the shared directory is mounted via SSH using: sudo mkdir -p /mnt/models sudo mount -t virtiofs f845b54d-00e3-493d-9541-3b37490b96db /mnt/models Example mount: $ minikube ssh findmnt /mnt/models TARGET SOURCE FSTYPE OPTIONS /mnt/models f845b54d-00e3-493d-9541-3b37490b96db virtiofs rw,relatime More work is needed to add VirtioFS to qemu. I'm starting with vfkit and krunkit since they have identical interface (krunkit was designed as drop-in replacement for vfkit).
1 parent 2a6c3f3 commit ca9eb87

File tree

6 files changed

+57
-3
lines changed

6 files changed

+57
-3
lines changed

pkg/drivers/krunkit/krunkit.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import (
4242

4343
"k8s.io/klog/v2"
4444
"k8s.io/minikube/pkg/drivers/common"
45+
"k8s.io/minikube/pkg/drivers/common/virtiofs"
4546
"k8s.io/minikube/pkg/drivers/common/vmnet"
4647
"k8s.io/minikube/pkg/minikube/exit"
4748
"k8s.io/minikube/pkg/minikube/firewall"
@@ -71,6 +72,7 @@ type Driver struct {
7172
CPU int
7273
Memory int
7374
ExtraDisks int
75+
VirtiofsMounts []*virtiofs.Mount
7476
MACAddress string
7577
VmnetHelper vmnet.Helper
7678
}
@@ -207,8 +209,18 @@ func (d *Driver) Start() error {
207209
}
208210

209211
log.Infof("Waiting for VM to start (ssh -p %d docker@%s)...", d.SSHPort, d.IPAddress)
212+
if err := WaitForTCPWithDelay(fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), time.Second); err != nil {
213+
return err
214+
}
215+
216+
if len(d.VirtiofsMounts) > 0 {
217+
log.Infof("Setup virtiofs mounts ...")
218+
if err := virtiofs.SetupMounts(d, d.VirtiofsMounts); err != nil {
219+
return err
220+
}
221+
}
210222

211-
return WaitForTCPWithDelay(fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), time.Second)
223+
return nil
212224
}
213225

214226
// startKrunkit starts the krunkit child process.
@@ -231,6 +243,11 @@ func (d *Driver) startKrunkit(socketPath string) error {
231243
"--device", fmt.Sprintf("virtio-blk,path=%s", common.ExtraDiskPath(d.BaseDriver, i)))
232244
}
233245

246+
for _, mount := range d.VirtiofsMounts {
247+
args = append(args,
248+
"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", mount.HostPath, mount.Tag))
249+
}
250+
234251
log.Debugf("executing: krunkit %s", strings.Join(args, " "))
235252
cmd := exec.Command(driverName, args...)
236253

pkg/drivers/vfkit/vfkit.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444

4545
"k8s.io/klog/v2"
4646
"k8s.io/minikube/pkg/drivers/common"
47+
"k8s.io/minikube/pkg/drivers/common/virtiofs"
4748
"k8s.io/minikube/pkg/drivers/common/vmnet"
4849
"k8s.io/minikube/pkg/minikube/detect"
4950
"k8s.io/minikube/pkg/minikube/exit"
@@ -72,6 +73,7 @@ type Driver struct {
7273
CPU int
7374
Memory int
7475
ExtraDisks int
76+
VirtiofsMounts []*virtiofs.Mount
7577
Network string // "", "nat", "vmnet-shared"
7678
MACAddress string // For network=nat, network=""
7779
VmnetHelper *vmnet.Helper // For network=vmnet-shared
@@ -250,8 +252,18 @@ func (d *Driver) Start() error {
250252
}
251253

252254
log.Infof("Waiting for VM to start (ssh -p %d docker@%s)...", d.SSHPort, d.IPAddress)
255+
if err := WaitForTCPWithDelay(fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), time.Second); err != nil {
256+
return err
257+
}
258+
259+
if len(d.VirtiofsMounts) > 0 {
260+
log.Infof("Setup virtiofs mounts ...")
261+
if err := virtiofs.SetupMounts(d, d.VirtiofsMounts); err != nil {
262+
return err
263+
}
264+
}
253265

254-
return WaitForTCPWithDelay(fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), time.Second)
266+
return nil
255267
}
256268

257269
// startVfkit starts the vfkit child process. If socketPath is not empty, vfkit
@@ -308,6 +320,12 @@ func (d *Driver) startVfkit(socketPath string) error {
308320
startCmd = append(startCmd,
309321
"--device", fmt.Sprintf("virtio-serial,logFilePath=%s", serialPath))
310322

323+
for _, mount := range d.VirtiofsMounts {
324+
startCmd = append(startCmd,
325+
"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", mount.HostPath, mount.Tag))
326+
327+
}
328+
311329
log.Debugf("executing: vfkit %s", strings.Join(startCmd, " "))
312330
os.Remove(d.sockfilePath())
313331
cmd := exec.Command("vfkit", startCmd...)

pkg/minikube/driver/driver.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ func SupportsNetworkFlag(name string) bool {
228228
return IsKIC(name) || IsKVM(name) || IsQEMU(name) || IsVFKit(name)
229229
}
230230

231+
// SupportsVirtiofsMounts returns if driver supports virtiofs mounts
232+
func SupportsVirtiofsMounts(name string) bool {
233+
return IsVFKit(name) || IsKrunkit(name)
234+
}
235+
231236
// AllowsPreload returns if preload is allowed for the driver
232237
func AllowsPreload(driverName string) bool {
233238
return !BareMetal(driverName) && !IsSSH(driverName)

pkg/minikube/node/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func configureMounts(wg *sync.WaitGroup, cc config.ClusterConfig) {
7373
wg.Add(1)
7474
defer wg.Done()
7575

76-
if cc.MountString == "" || driver.IsKIC(cc.Driver) {
76+
if cc.MountString == "" || driver.IsKIC(cc.Driver) || driver.SupportsVirtiofsMounts(cc.Driver) {
7777
return
7878
}
7979

pkg/minikube/registry/drvs/krunkit/krunkit.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/docker/machine/libmachine/drivers"
2929
"github.com/google/uuid"
3030

31+
"k8s.io/minikube/pkg/drivers/common/virtiofs"
3132
"k8s.io/minikube/pkg/drivers/common/vmnet"
3233
"k8s.io/minikube/pkg/drivers/krunkit"
3334
"k8s.io/minikube/pkg/minikube/config"
@@ -65,6 +66,11 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
6566
u = uuid.NewString()
6667
}
6768

69+
mounts, err := virtiofs.ValidateMountString(cfg.MountString)
70+
if err != nil {
71+
return nil, err
72+
}
73+
6874
return &krunkit.Driver{
6975
BaseDriver: &drivers.BaseDriver{
7076
MachineName: machineName,
@@ -76,6 +82,7 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
7682
Memory: cfg.Memory,
7783
CPU: cfg.CPUs,
7884
ExtraDisks: cfg.ExtraDisks,
85+
VirtiofsMounts: mounts,
7986
VmnetHelper: vmnet.Helper{
8087
MachineDir: filepath.Join(storePath, "machines", machineName),
8188
InterfaceID: u,

pkg/minikube/registry/drvs/vfkit/vfkit.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/docker/machine/libmachine/drivers"
2929
"github.com/google/uuid"
3030

31+
"k8s.io/minikube/pkg/drivers/common/virtiofs"
3132
"k8s.io/minikube/pkg/drivers/common/vmnet"
3233
"k8s.io/minikube/pkg/drivers/vfkit"
3334
"k8s.io/minikube/pkg/minikube/config"
@@ -88,6 +89,11 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
8889
return nil, fmt.Errorf("unsupported network: %q", cfg.Network)
8990
}
9091

92+
mounts, err := virtiofs.ValidateMountString(cfg.MountString)
93+
if err != nil {
94+
return nil, err
95+
}
96+
9197
return &vfkit.Driver{
9298
BaseDriver: &drivers.BaseDriver{
9399
MachineName: machineName,
@@ -99,6 +105,7 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
99105
Memory: cfg.Memory,
100106
CPU: cfg.CPUs,
101107
ExtraDisks: cfg.ExtraDisks,
108+
VirtiofsMounts: mounts,
102109
Network: cfg.Network,
103110
MACAddress: mac,
104111
VmnetHelper: helper,

0 commit comments

Comments
 (0)