Skip to content

Commit b6650e0

Browse files
committed
drivers: Add VirtioFS support for vfkit and krunkit
Add --virtio-fs flag for specifying one or more shared directories separated by comma. The shared directories are be mounted in the guest using virtio-fs. Testing with krunkit shows that virtio-fs mount is 10 times faster compared with 9p mount. Usage: --virtio-fs HOST_PATH:MOUNT_TAG[,HOST_PATH:MOUNT_TAG,...] Example: minikube start --vrtio-fs /Users/joe/models:my-models Using a new flag since none of the mount options matches virtio-fs usage, and it will be too confusing to use using mount options. In krunkit and vfkit, every virtio-fs shared directory will be added as: --device virtio-fs,sharedDir=/host-path,mountTag=mount-tag In the guest the shared directory will be mounted using: sudo mount -t virtiofs my-models /mnt/my-models This change only adds the options and configure vfkit and krunkit. The next step is connecting to the guest and mounting the shared directories. More work is needed to add VirtioFS to qemu. I'm starting with fkit and krunkit since they have identical interface (krunkit was designed as drop-in replacement for vfkit).
1 parent f0519e4 commit b6650e0

File tree

7 files changed

+62
-0
lines changed

7 files changed

+62
-0
lines changed

cmd/minikube/cmd/start_flags.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ const (
145145
staticIP = "static-ip"
146146
gpus = "gpus"
147147
autoPauseInterval = "auto-pause-interval"
148+
virtioFS = "virtio-fs"
148149
)
149150

150151
var (
@@ -209,6 +210,7 @@ func initMinikubeFlags() {
209210
startCmd.Flags().String(staticIP, "", "Set a static IP for the minikube cluster, the IP must be: private, IPv4, and the last octet must be between 2 and 254, for example 192.168.200.200 (Docker and Podman drivers only)")
210211
startCmd.Flags().StringP(gpus, "g", "", "Allow pods to use your GPUs. Options include: [all,nvidia,amd] (Docker driver with Docker container-runtime only)")
211212
startCmd.Flags().Duration(autoPauseInterval, time.Minute*1, "Duration of inactivity before the minikube VM is paused (default 1m0s)")
213+
startCmd.Flags().StringSlice(virtioFS, nil, "virtio-fs shared directories '/host-path:mount-tag,...' (vfkkit and krunkit drivers only)")
212214
}
213215

214216
// initKubernetesFlags inits the commandline flags for Kubernetes related options
@@ -650,6 +652,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime str
650652
MultiNodeRequested: viper.GetInt(nodes) > 1 || viper.GetBool(ha),
651653
GPUs: viper.GetString(gpus),
652654
AutoPauseInterval: viper.GetDuration(autoPauseInterval),
655+
VirtioFS: viper.GetStringSlice(virtioFS),
653656
}
654657
cc.VerifyComponents = interpretWaitFlag(*cmd)
655658
if viper.GetBool(createMount) && driver.IsKIC(drvName) {
@@ -880,6 +883,7 @@ func updateExistingConfigFromFlags(cmd *cobra.Command, existing *config.ClusterC
880883
updateStringFromFlag(cmd, &cc.SocketVMnetClientPath, socketVMnetClientPath)
881884
updateStringFromFlag(cmd, &cc.SocketVMnetPath, socketVMnetPath)
882885
updateDurationFromFlag(cmd, &cc.AutoPauseInterval, autoPauseInterval)
886+
updateStringSliceFromFlag(cmd, &cc.VirtioFS, virtioFS)
883887

884888
if cmd.Flags().Changed(kubernetesVersion) {
885889
kubeVer, err := getKubernetesVersion(existing)

pkg/drivers/krunkit/krunkit.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ type Driver struct {
7171
CPU int
7272
Memory int
7373
ExtraDisks int
74+
VirtioFS []string
7475
MACAddress string
7576
VmnetHelper vmnet.Helper
7677
}
@@ -231,6 +232,15 @@ func (d *Driver) startKrunkit(socketPath string) error {
231232
"--device", fmt.Sprintf("virtio-blk,path=%s", pkgdrivers.ExtraDiskPath(d.BaseDriver, i)))
232233
}
233234

235+
for _, s := range d.VirtioFS {
236+
fs, err := pkgdrivers.ParseVirtioFS(s)
237+
if err != nil {
238+
return err
239+
}
240+
args = append(args,
241+
"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", fs.SharedDir, fs.MountTag))
242+
}
243+
234244
log.Debugf("executing: krunkit %s", strings.Join(args, " "))
235245
cmd := exec.Command(driverName, args...)
236246

pkg/drivers/vfkit/vfkit.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ type Driver struct {
7272
CPU int
7373
Memory int
7474
ExtraDisks int
75+
VirtioFS []string
7576
Network string // "", "nat", "vmnet-shared"
7677
MACAddress string // For network=nat, network=""
7778
VmnetHelper *vmnet.Helper // For network=vmnet-shared
@@ -312,6 +313,15 @@ func (d *Driver) startVfkit(socketPath string) error {
312313
startCmd = append(startCmd,
313314
"--device", fmt.Sprintf("virtio-serial,logFilePath=%s", serialPath))
314315

316+
for _, s := range d.VirtioFS {
317+
fs, err := pkgdrivers.ParseVirtioFS(s)
318+
if err != nil {
319+
return err
320+
}
321+
startCmd = append(startCmd,
322+
"--device", fmt.Sprintf("virtio-fs,sharedDir=%s,mountTag=%s", fs.SharedDir, fs.MountTag))
323+
}
324+
315325
log.Debugf("executing: vfkit %s", strings.Join(startCmd, " "))
316326
os.Remove(d.sockfilePath())
317327
cmd := exec.Command("vfkit", startCmd...)

pkg/drivers/virtiofs.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package drivers
18+
19+
import (
20+
"fmt"
21+
"strings"
22+
)
23+
24+
type VirtioFS struct {
25+
SharedDir string
26+
MountTag string
27+
}
28+
29+
func ParseVirtioFS(s string) (*VirtioFS, error) {
30+
items := strings.SplitN(s, ":", 2)
31+
if len(items) != 2 {
32+
return nil, fmt.Errorf("invalid virtio-fs %q", s)
33+
}
34+
return &VirtioFS{SharedDir: items[0], MountTag: items[1]}, nil
35+
}

pkg/minikube/config/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ type ClusterConfig struct {
109109
SSHAgentPID int
110110
GPUs string
111111
AutoPauseInterval time.Duration // Specifies interval of time to wait before checking if cluster should be paused
112+
VirtioFS []string
112113
}
113114

114115
// KubernetesConfig contains the parameters used to configure the VM Kubernetes.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
7676
Memory: cfg.Memory,
7777
CPU: cfg.CPUs,
7878
ExtraDisks: cfg.ExtraDisks,
79+
VirtioFS: cfg.VirtioFS,
7980
VmnetHelper: vmnet.Helper{
8081
MachineDir: filepath.Join(storePath, "machines", machineName),
8182
InterfaceID: u,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ func configure(cfg config.ClusterConfig, n config.Node) (interface{}, error) {
9999
Memory: cfg.Memory,
100100
CPU: cfg.CPUs,
101101
ExtraDisks: cfg.ExtraDisks,
102+
VirtioFS: cfg.VirtioFS,
102103
Network: cfg.Network,
103104
MACAddress: mac,
104105
VmnetHelper: helper,

0 commit comments

Comments
 (0)