Repository: kubernetes/minikube
Pull request #14989 (2022-09-21 18:32:24)

Implement socket_vmnet network (QEMU)
Closes https://github.com/kubernetes/minikube/issues/15038
Closes https://github.com/kubernetes/minikube/issues/14692

Implemented socket_vmnet network for the QEMU driver

**minikube start:**
```
$ minikube start --driver qemu --network socket_vmnet
😄  minikube v1.27.0 on Darwin 12.6 (arm64)
✨  Using the qemu2 (experimental) driver based on user configuration
❗  Using qemu with 'socket_vmnet' network is experimental
👍  Starting control plane node minikube in cluster minikube
🔥  Creating qemu2 VM (CPUs=2, Memory=4000MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.25.1 on Docker 20.10.18 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```

**minikube service:**
```
$ kubectl create deployment hello-minikube --image=docker.io/nginx:1.23
$ kubectl expose deployment hello-minikube --type=NodePort --port=80
$ minikube service hello-minikube
|-----------|----------------|-------------|----------------------------|
| NAMESPACE |      NAME      | TARGET PORT |            URL             |
|-----------|----------------|-------------|----------------------------|
| default   | hello-minikube |          80 | http://192.168.105.2:32037 |
|-----------|----------------|-------------|----------------------------|
🎉  Opening service default/hello-minikube in default browser...
$ curl 192.168.105.2:32037
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
```

**minikube tunnel:**
```
$ kubectl create deployment balanced --image=docker.io/nginx:1.23
$ kubectl expose deployment balanced --type=LoadBalancer --port=80
$ minikube tunnel

# in new terminal window
$ kubectl get services balanced
NAME       TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE
balanced   LoadBalancer   10.101.76.73   10.101.76.73   80:30925/TCP   22s
$ curl 10.101.76.73:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
```

**starting with user network (backwards-compatibility)**
```
$ minikube start --driver qemu
😄  minikube v1.27.0 on Darwin 12.6 (arm64)
✨  Using the qemu2 (experimental) driver based on user configuration
❗  The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release
❗  You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` & `minikube tunnel` commands.
To try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking
👍  Starting control plane node minikube in cluster minikube
🔥  Creating qemu2 VM (CPUs=2, Memory=4000MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.25.1 on Docker 20.10.18 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
```

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes/minikube/pull/14989#" title="Author self-approved">spowelljr</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes%2Fminikube).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubernetes/minikube/blob/master/OWNERS)~~ [spowelljr]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
k8s-ci-robot: @spowelljr: The following test **failed**, say `/retest` to rerun all failed tests or `/retest-required` to rerun all mandatory failed tests:

Test name | Commit | Details | Required | Rerun command
--- | --- | --- | --- | ---
pull-minikube-build | 4cd483c06b8e09ab743dd8ee0225496f6ea4094b | [link](https://prow.k8s.io/view/gs/kubernetes-jenkins/pr-logs/pull/minikube/14989/pull-minikube-build/1572655005591146496) | true | `/test pull-minikube-build`

[Full PR test history](https://prow.k8s.io/pr-history?org=kubernetes&repo=minikube&pr=14989). [Your PR dashboard](https://prow.k8s.io/pr?query=is%3Apr%20state%3Aopen%20author%3Aspowelljr). Please help us cut down on flakes by [linking to](https://git.k8s.io/community/contributors/devel/sig-testing/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/kubernetes/minikube/issues?q=is:issue+is:open) when you hit one in your PR.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
k8s-ci-robot: @spowelljr: PR needs rebase.

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

Patch:
diff --git a/cmd/minikube/cmd/docker-env.go b/cmd/minikube/cmd/docker-env.go
index 2c436b44e..bebbb7f5e 100644
--- a/cmd/minikube/cmd/docker-env.go
+++ b/cmd/minikube/cmd/docker-env.go
@@ -50,6 +50,7 @@ import (
 	"k8s.io/minikube/pkg/minikube/reason"
 	"k8s.io/minikube/pkg/minikube/shell"
 	"k8s.io/minikube/pkg/minikube/sysinit"
+	pkgnetwork "k8s.io/minikube/pkg/network"
 	kconst "k8s.io/minikube/third_party/kubeadm/app/constants"
 )
 
@@ -296,12 +297,12 @@ docker-cli install instructions: https://minikube.sigs.k8s.io/docs/tutorials/doc
 
 		d := co.CP.Host.Driver
 		port := constants.DockerDaemonPort
-		if driver.NeedsPortForward(driverName) && driver.IsKIC(driverName) {
+		if driver.NeedsPortForward(driverName) {
 			port, err = oci.ForwardedPort(driverName, cname, port)
 			if err != nil {
 				exit.Message(reason.DrvPortForward, "Error getting port binding for '{{.driver_name}} driver: {{.error}}", out.V{"driver_name": driverName, "error": err})
 			}
-		} else if driver.NeedsPortForward(driverName) && driverName == driver.QEMU2 {
+		} else if driver.IsQEMU(driverName) && pkgnetwork.IsUser(co.Config.Network) {
 			port = d.(*qemu.Driver).EnginePort
 		}
 
diff --git a/cmd/minikube/cmd/service.go b/cmd/minikube/cmd/service.go
index bbba3d545..12a2e9492 100644
--- a/cmd/minikube/cmd/service.go
+++ b/cmd/minikube/cmd/service.go
@@ -44,6 +44,7 @@ import (
 	"k8s.io/minikube/pkg/minikube/service"
 	"k8s.io/minikube/pkg/minikube/style"
 	"k8s.io/minikube/pkg/minikube/tunnel/kic"
+	pkgnetwork "k8s.io/minikube/pkg/network"
 )
 
 const defaultServiceFormatTemplate = "http://{{.IP}}:{{.Port}}"
@@ -86,9 +87,12 @@ var serviceCmd = &cobra.Command{
 		cname := ClusterFlagValue()
 		co := mustload.Healthy(cname)
 
-		// Bail cleanly for qemu2 until implemented
-		if driver.IsQEMU(co.Config.Driver) {
-			exit.Message(reason.Unimplemented, "minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.")
+		if driver.IsQEMU(co.Config.Driver) && pkgnetwork.IsUser(co.Config.Network) {
+			msg := "minikube service is not currently implemented with the user network on QEMU"
+			if runtime.GOOS == "darwin" {
+				msg += ", try starting minikube with '--network=socket_vmnet'"
+			}
+			exit.Message(reason.Unimplemented, msg)
 		}
 
 		var services service.URLs
@@ -146,10 +150,8 @@ You may select another namespace by using 'minikube service {{.service}} -n <nam
 			}
 		}
 
-		if driver.NeedsPortForward(co.Config.Driver) && driver.IsKIC(co.Config.Driver) && services != nil {
+		if driver.NeedsPortForward(co.Config.Driver) && services != nil {
 			startKicServiceTunnel(services, cname, co.Config.Driver)
-		} else if driver.NeedsPortForward(co.Config.Driver) && driver.IsQEMU(co.Config.Driver) && services != nil {
-			startQemuServiceTunnel(services, cname, co.Config.Driver)
 		} else if !serviceURLMode {
 			openURLs(data)
 		}
@@ -222,9 +224,6 @@ func startKicServiceTunnel(services service.URLs, configName, driverName string)
 	<-ctrlC
 }
 
-func startQemuServiceTunnel(services service.URLs, configName, driverName string) {
-}
-
 func mutateURLs(serviceName string, urls []string) ([]string, error) {
 	formattedUrls := make([]string, 0)
 	for _, rawURL := range urls {
diff --git a/cmd/minikube/cmd/start_flags.go b/cmd/minikube/cmd/start_flags.go
index eee53fad4..281ca9634 100644
--- a/cmd/minikube/cmd/start_flags.go
+++ b/cmd/minikube/cmd/start_flags.go
@@ -18,6 +18,7 @@ package cmd
 
 import (
 	"fmt"
+	"runtime"
 	"strings"
 	"time"
 
@@ -457,6 +458,23 @@ func getCNIConfig(cmd *cobra.Command) string {
 	return chosenCNI
 }
 
+func getNetwork(driverName string) string {
+	n := viper.GetString(network)
+	if !driver.IsQEMU(driverName) {
+		return n
+	}
+	if n == "" {
+		if runtime.GOOS == "darwin" {
+			out.WarningT("The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release")
+		}
+		n = "user"
+	}
+	if n == "user" && runtime.GOOS == "darwin" {
+		out.WarningT("You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` & `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking")
+	}
+	return n
+}
+
 // generateNewConfigFromFlags generate a config.ClusterConfig based on flags
 func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime string, drvName string) config.ClusterConfig {
 	var cc config.ClusterConfig
@@ -471,8 +489,8 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime str
 		out.WarningT("--network flag is only valid with the docker/podman, KVM and Qemu drivers, it will be ignored")
 	}
 
-	if driver.IsQEMU(drvName) && viper.GetString(network) == "socket" {
-		out.WarningT("Using qemu with --network=socket for 'socket_vmnet' is experimental")
+	if driver.IsQEMU(drvName) && viper.GetString(network) == "socket_vmnet" {
+		out.WarningT("Using qemu with 'socket_vmnet' network is experimental")
 	}
 
 	checkNumaCount(k8sVersion)
@@ -485,7 +503,7 @@ func generateNewConfigFromFlags(cmd *cobra.Command, k8sVersion string, rtime str
 		EmbedCerts:              viper.GetBool(embedCerts),
 		MinikubeISO:             viper.GetString(isoURL),
 		KicBaseImage:            viper.GetString(kicBaseImage),
-		Network:                 viper.GetString(network),
+		Network:                 getNetwork(drvName),
 		Subnet:                  viper.GetString(subnet),
 		Memory:                  getMemorySize(cmd, drvName),
 		CPUs:                    getCPUCount(drvName),
diff --git a/cmd/minikube/cmd/tunnel.go b/cmd/minikube/cmd/tunnel.go
index c2e984cf7..50ea8c80d 100644
--- a/cmd/minikube/cmd/tunnel.go
+++ b/cmd/minikube/cmd/tunnel.go
@@ -21,6 +21,7 @@ import (
 	"os"
 	"os/signal"
 	"path/filepath"
+	"runtime"
 	"strconv"
 
 	"github.com/spf13/cobra"
@@ -38,6 +39,7 @@ import (
 	"k8s.io/minikube/pkg/minikube/style"
 	"k8s.io/minikube/pkg/minikube/tunnel"
 	"k8s.io/minikube/pkg/minikube/tunnel/kic"
+	pkgnetwork "k8s.io/minikube/pkg/network"
 )
 
 var cleanup bool
@@ -56,9 +58,12 @@ var tunnelCmd = &cobra.Command{
 		cname := ClusterFlagValue()
 		co := mustload.Healthy(cname)
 
-		// Bail cleanly for qemu2 until implemented
-		if driver.IsQEMU(co.Config.Driver) {
-			exit.Message(reason.Unimplemented, "minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.")
+		if driver.IsQEMU(co.Config.Driver) && pkgnetwork.IsUser(co.Config.Network) {
+			msg := "minikube tunnel is not currently implemented with the user network on QEMU"
+			if runtime.GOOS == "darwin" {
+				msg += ", try starting minikube with '--network=socket_vmnet'"
+			}
+			exit.Message(reason.Unimplemented, msg)
 		}
 
 		if cleanup {
@@ -85,7 +90,7 @@ var tunnelCmd = &cobra.Command{
 			cancel()
 		}()
 
-		if useSSHTunnel(co.Config.Driver) {
+		if driver.NeedsPortForward(co.Config.Driver) || bindAddress != "" {
 			port, err := oci.ForwardedPort(co.Config.Driver, cname, 22)
 			if err != nil {
 				exit.Error(reason.DrvPortForward, "error getting ssh port", err)
@@ -111,16 +116,6 @@ var tunnelCmd = &cobra.Command{
 	},
 }
 
-func useSSHTunnel(driverName string) bool {
-	if !driver.IsKIC(driverName) {
-		return false
-	}
-	if driver.NeedsPortForward(driverName) {
-		return true
-	}
-	return bindAddress != ""
-}
-
 func outputTunnelStarted() {
 	out.Styled(style.Success, "Tunnel successfully started")
 	out.Ln("")
diff --git a/pkg/addons/addons.go b/pkg/addons/addons.go
index ec07d8cdf..60ce74d34 100644
--- a/pkg/addons/addons.go
+++ b/pkg/addons/addons.go
@@ -247,7 +247,7 @@ func addonSpecificChecks(cc *config.ClusterConfig, name string, enable bool, run
 	}
 
 	if name == "registry" {
-		if driver.NeedsPortForward(cc.Driver) && driver.IsKIC(cc.Driver) {
+		if driver.NeedsPortForward(cc.Driver) {
 			port, err := oci.ForwardedPort(cc.Driver, cc.Name, constants.RegistryAddonPort)
 			if err != nil {
 				return false, errors.Wrap(err, "registry port")
diff --git a/pkg/addons/addons_autopause.go b/pkg/addons/addons_autopause.go
index 2e5faf86e..3b33b7f9b 100644
--- a/pkg/addons/addons_autopause.go
+++ b/pkg/addons/addons_autopause.go
@@ -51,7 +51,7 @@ func enableOrDisableAutoPause(cc *config.ClusterConfig, name, val string) error
 	port := co.CP.Port // API server port
 	if enable {        // if enable, calculate the forwarded port
 		port = constants.AutoPauseProxyPort
-		if driver.NeedsPortForward(cc.Driver) && driver.IsKIC(cc.Driver) {
+		if driver.NeedsPortForward(cc.Driver) {
 			port, err = oci.ForwardedPort(cc.Driver, cc.Name, port)
 			if err != nil {
 				klog.ErrorS(err, "failed to get forwarded port for", "auto-pause port", port)
diff --git a/pkg/drivers/common.go b/pkg/drivers/common.go
index 6fbed2803..74ed70e37 100644
--- a/pkg/drivers/common.go
+++ b/pkg/drivers/common.go
@@ -17,13 +17,17 @@ limitations under the License.
 package drivers
 
 import (
+	"bufio"
 	"fmt"
 	"io"
 	"os"
 	"path/filepath"
+	"regexp"
+	"strings"
 	"syscall"
 
 	"github.com/docker/machine/libmachine/drivers"
+	"github.com/docker/machine/libmachine/log"
 	"github.com/docker/machine/libmachine/mcnflag"
 	"github.com/docker/machine/libmachine/mcnutils"
 	"github.com/docker/machine/libmachine/ssh"
@@ -33,6 +37,11 @@ import (
 	"k8s.io/minikube/pkg/util"
 )
 
+// LeasesPath is the path to dhcpd leases
+const LeasesPath = "/var/db/dhcpd_leases"
+
+var leadingZeroRegexp = regexp.MustCompile(`0([A-Fa-f0-9](:|$))`)
+
 // This file is for common code shared among internal machine drivers
 // Code here should not be called from within minikube
 
@@ -147,3 +156,86 @@ func fixMachinePermissions(path string) error {
 	}
 	return nil
 }
+
+// DHCPEntry holds a parsed DNS entry
+type DHCPEntry struct {
+	Name      string
+	IPAddress string
+	HWAddress string
+	ID        string
+	Lease     string
+}
+
+// GetIPAddressByMACAddress gets the IP address of a MAC address
+func GetIPAddressByMACAddress(mac string) (string, error) {
+	return getIPAddressFromFile(mac, LeasesPath)
+}
+
+func getIPAddressFromFile(mac, path string) (string, error) {
+	log.Debugf("Searching for %s in %s ...", mac, path)
+	file, err := os.Open(path)
+	if err != nil {
+		return "", err
+	}
+	defer file.Close()
+
+	dhcpEntries, err := parseDHCPdLeasesFile(file)
+	if err != nil {
+		return "", err
+	}
+	log.Debugf("Found %d entries in %s!", len(dhcpEntries), path)
+	for _, dhcpEntry := range dhcpEntries {
+		log.Debugf("dhcp entry: %+v", dhcpEntry)
+		if dhcpEntry.HWAddress == mac {
+			log.Debugf("Found match: %s", mac)
+			return dhcpEntry.IPAddress, nil
+		}
+	}
+	return "", fmt.Errorf("could not find an IP address for %s", mac)
+}
+
+func parseDHCPdLeasesFile(file io.Reader) ([]DHCPEntry, error) {
+	var (
+		dhcpEntry   *DHCPEntry
+		dhcpEntries []DHCPEntry
+	)
+
+	scanner := bufio.NewScanner(file)
+	for scanner.Scan() {
+		line := strings.TrimSpace(scanner.Text())
+		if line == "{" {
+			dhcpEntry = new(DHCPEntry)
+			continue
+		} else if line == "}" {
+			dhcpEntries = append(dhcpEntries, *dhcpEntry)
+			continue
+		}
+
+		split := strings.SplitN(line, "=", 2)
+		if len(split) != 2 {
+			return nil, fmt.Errorf("invalid line in dhcp leases file: %s", line)
+		}
+		key, val := split[0], split[1]
+		switch key {
+		case "name":
+			dhcpEntry.Name = val
+		case "ip_address":
+			dhcpEntry.IPAddress = val
+		case "hw_address":
+			// The mac addresses have a '1,' at the start.
+			dhcpEntry.HWAddress = val[2:]
+		case "identifier":
+			dhcpEntry.ID = val
+		case "lease":
+			dhcpEntry.Lease = val
+		default:
+			return dhcpEntries, fmt.Errorf("unable to parse line: %s", line)
+		}
+	}
+	return dhcpEntries, scanner.Err()
+}
+
+// TrimMacAddress trimming "0" of the ten's digit
+func TrimMacAddress(rawUUID string) string {
+	return leadingZeroRegexp.ReplaceAllString(rawUUID, "$1")
+}
diff --git a/pkg/drivers/hyperkit/driver.go b/pkg/drivers/hyperkit/driver.go
index 236336518..9d78461a7 100644
--- a/pkg/drivers/hyperkit/driver.go
+++ b/pkg/drivers/hyperkit/driver.go
@@ -262,7 +262,7 @@ func (d *Driver) Start() error {
 	}
 
 	// Need to strip 0's
-	mac = trimMacAddress(mac)
+	mac = pkgdrivers.TrimMacAddress(mac)
 	log.Debugf("Generated MAC %s", mac)
 
 	log.Debugf("Starting with cmdline: %s", d.Cmdline)
@@ -288,7 +288,7 @@ func (d *Driver) setupIP(mac string) error {
 			return fmt.Errorf("hyperkit crashed! command line:\n  hyperkit %s", d.Cmdline)
 		}
 
-		d.IPAddress, err = GetIPAddressByMACAddress(mac)
+		d.IPAddress, err = pkgdrivers.GetIPAddressByMACAddress(mac)
 		if err != nil {
 			return &tempError{err}
 		}
diff --git a/pkg/drivers/hyperkit/network.go b/pkg/drivers/hyperkit/network.go
index a3597a6a5..bcc7b40df 100644
--- a/pkg/drivers/hyperkit/network.go
+++ b/pkg/drivers/hyperkit/network.go
@@ -19,114 +19,20 @@ limitations under the License.
 package hyperkit
 
 import (
-	"bufio"
 	"fmt"
-	"io"
 	"net"
 	"os"
 	"os/exec"
-	"regexp"
 	"strings"
-
-	"github.com/docker/machine/libmachine/log"
 )
 
 const (
-	// LeasesPath is the path to dhcpd leases
-	LeasesPath = "/var/db/dhcpd_leases"
 	// VMNetDomain is the domain for vmnet
 	VMNetDomain = "/Library/Preferences/SystemConfiguration/com.apple.vmnet"
 	// SharedNetAddrKey is the key for the network address
 	SharedNetAddrKey = "Shared_Net_Address"
 )
 
-var (
-	leadingZeroRegexp = regexp.MustCompile(`0([A-Fa-f0-9](:|$))`)
-)
-
-// DHCPEntry holds a parsed DNS entry
-type DHCPEntry struct {
-	Name      string
-	IPAddress string
-	HWAddress string
-	ID        string
-	Lease     string
-}
-
-// GetIPAddressByMACAddress gets the IP address of a MAC address
-func GetIPAddressByMACAddress(mac string) (string, error) {
-	return getIPAddressFromFile(mac, LeasesPath)
-}
-
-func getIPAddressFromFile(mac, path string) (string, error) {
-	log.Debugf("Searching for %s in %s ...", mac, path)
-	file, err := os.Open(path)
-	if err != nil {
-		return "", err
-	}
-	defer file.Close()
-
-	dhcpEntries, err := parseDHCPdLeasesFile(file)
-	if err != nil {
-		return "", err
-	}
-	log.Debugf("Found %d entries in %s!", len(dhcpEntries), path)
-	for _, dhcpEntry := range dhcpEntries {
-		log.Debugf("dhcp entry: %+v", dhcpEntry)
-		if dhcpEntry.HWAddress == mac {
-			log.Debugf("Found match: %s", mac)
-			return dhcpEntry.IPAddress, nil
-		}
-	}
-	return "", fmt.Errorf("could not find an IP address for %s", mac)
-}
-
-func parseDHCPdLeasesFile(file io.Reader) ([]DHCPEntry, error) {
-	var (
-		dhcpEntry   *DHCPEntry
-		dhcpEntries []DHCPEntry
-	)
-
-	scanner := bufio.NewScanner(file)
-	for scanner.Scan() {
-		line := strings.TrimSpace(scanner.Text())
-		if line == "{" {
-			dhcpEntry = new(DHCPEntry)
-			continue
-		} else if line == "}" {
-			dhcpEntries = append(dhcpEntries, *dhcpEntry)
-			continue
-		}
-
-		split := strings.SplitN(line, "=", 2)
-		if len(split) != 2 {
-			return nil, fmt.Errorf("invalid line in dhcp leases file: %s", line)
-		}
-		key, val := split[0], split[1]
-		switch key {
-		case "name":
-			dhcpEntry.Name = val
-		case "ip_address":
-			dhcpEntry.IPAddress = val
-		case "hw_address":
-			// The mac addresses have a '1,' at the start.
-			dhcpEntry.HWAddress = val[2:]
-		case "identifier":
-			dhcpEntry.ID = val
-		case "lease":
-			dhcpEntry.Lease = val
-		default:
-			return dhcpEntries, fmt.Errorf("unable to parse line: %s", line)
-		}
-	}
-	return dhcpEntries, scanner.Err()
-}
-
-// trimMacAddress trimming "0" of the ten's digit
-func trimMacAddress(rawUUID string) string {
-	return leadingZeroRegexp.ReplaceAllString(rawUUID, "$1")
-}
-
 // GetNetAddr gets the network address for vmnet
 func GetNetAddr() (net.IP, error) {
 	plistPath := VMNetDomain + ".plist"
diff --git a/pkg/drivers/qemu/qemu.go b/pkg/drivers/qemu/qemu.go
index 089a597b1..02489ccb7 100644
--- a/pkg/drivers/qemu/qemu.go
+++ b/pkg/drivers/qemu/qemu.go
@@ -41,8 +41,6 @@ import (
 	"github.com/spf13/viper"
 
 	pkgdrivers "k8s.io/minikube/pkg/drivers"
-	"k8s.io/minikube/pkg/minikube/exit"
-	"k8s.io/minikube/pkg/minikube/reason"
 )
 
 const (
@@ -58,33 +56,30 @@ type Driver struct {
 	EnginePort int
 	FirstQuery bool
 
-	Memory           int
-	DiskSize         int
-	CPU              int
-	Program          string
-	BIOS             bool
-	CPUType          string
-	MachineType      string
-	Firmware         string
-	Display          bool
-	DisplayType      string
-	Nographic        bool
-	VirtioDrives     bool
-	Network          string
-	PrivateNetwork   string
-	Boot2DockerURL   string
-	NetworkInterface string
-	NetworkAddress   string
-	NetworkSocket    string
-	NetworkBridge    string
-	CaCertPath       string
-	PrivateKeyPath   string
-	DiskPath         string
-	CacheMode        string
-	IOMode           string
-	UserDataFile     string
-	CloudConfigRoot  string
-	LocalPorts       string
+	Memory          int
+	DiskSize        int
+	CPU             int
+	Program         string
+	BIOS            bool
+	CPUType         string
+	MachineType     string
+	Firmware        string
+	Display         bool
+	DisplayType     string
+	Nographic       bool
+	VirtioDrives    bool
+	Network         string
+	PrivateNetwork  string
+	Boot2DockerURL  string
+	CaCertPath      string
+	PrivateKeyPath  string
+	DiskPath        string
+	CacheMode       string
+	IOMode          string
+	UserDataFile    string
+	CloudConfigRoot string
+	LocalPorts      string
+	MACAddress      string
 }
 
 func (d *Driver) GetMachineName() string {
@@ -92,7 +87,10 @@ func (d *Driver) GetMachineName() string {
 }
 
 func (d *Driver) GetSSHHostname() (string, error) {
-	return "localhost", nil
+	if d.Network == "user" {
+		return "localhost", nil
+	}
+	return d.IPAddress, nil
 }
 
 func (d *Driver) GetSSHKeyPath() string {
@@ -149,7 +147,7 @@ func (d *Driver) GetIP() (string, error) {
 	if d.Network == "user" {
 		return "127.0.0.1", nil
 	}
-	return d.NetworkAddress, nil
+	return d.IPAddress, nil
 }
 
 func (d *Driver) GetPort() int {
@@ -213,7 +211,8 @@ func (d *Driver) PreCreateCheck() error {
 
 func (d *Driver) Create() error {
 	var err error
-	if d.Network == "user" {
+	switch d.Network {
+	case "user":
 		minPort, maxPort, err := parsePortRange(d.LocalPorts)
 		log.Debugf("port range: %d -> %d", minPort, maxPort)
 		if err != nil {
@@ -235,6 +234,11 @@ func (d *Driver) Create() error {
 			}
 			break
 		}
+	case "socket_vmnet":
+		d.SSHPort, err = d.GetSSHPort()
+		if err != nil {
+			return err
+		}
 	}
 	b2dutils := mcnutils.NewB2dUtils(d.StorePath)
 	if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil {
@@ -411,23 +415,12 @@ func (d *Driver) Start() error {
 		startCmd = append(startCmd,
 			"-nic", fmt.Sprintf("user,model=virtio,hostfwd=tcp::%d-:22,hostfwd=tcp::%d-:2376,hostname=%s", d.SSHPort, d.EnginePort, d.GetMachineName()),
 		)
-	case "socket":
-		// TODO: implement final socket_vmnet network flags.
-		exit.Message(reason.Unimplemented, "socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.")
-	case "tap":
-		startCmd = append(startCmd,
-			"-nic", fmt.Sprintf("tap,model=virtio,ifname=%s,script=no,downscript=no", d.NetworkInterface),
-		)
-	case "vde":
+	case "socket_vmnet":
 		startCmd = append(startCmd,
-			"-nic", fmt.Sprintf("vde,model=virtio,sock=%s", d.NetworkSocket),
-		)
-	case "bridge":
-		startCmd = append(startCmd,
-			"-nic", fmt.Sprintf("bridge,model=virtio,br=%s", d.NetworkBridge),
+			"-device", fmt.Sprintf("virtio-net-pci,netdev=net0,mac=%s", d.MACAddress), "-netdev", "socket,id=net0,fd=3",
 		)
 	default:
-		log.Errorf("unknown network: %s", d.Network)
+		return fmt.Errorf("unknown network: %s", d.Network)
 	}
 
 	startCmd = append(startCmd,
@@ -453,7 +446,7 @@ func (d *Driver) Start() error {
 
 	// If socket network, start with socket_vmnet.
 	startProgram := d.Program
-	if d.Network == "socket" {
+	if d.Network == "socket_vmnet" {
 		startProgram = viper.GetString("socket-vmnet-client-path")
 		socketVMnetPath := viper.GetString("socket-vmnet-path")
 		startCmd = append([]string{socketVMnetPath, d.Program}, startCmd...)
@@ -465,9 +458,40 @@ func (d *Driver) Start() error {
 		return err
 	}
 
-	log.Infof("Waiting for VM to start (ssh -p %d docker@localhost)...", d.SSHPort)
+	switch d.Network {
+	case "user":
+		d.IPAddress = "127.0.0.1"
+	case "socket_vmnet":
+		var err error
+		getIP := func() error {
+			// QEMU requires MAC address with leading 0s
+			// But socket_vmnet writes the MAC address to the dhcp leases file with leading 0s stripped
+			mac := pkgdrivers.TrimMacAddress(d.MACAddress)
+			d.IPAddress, err = pkgdrivers.GetIPAddressByMACAddress(mac)
+			if err != nil {
+				return errors.Wrap(err, "failed to get IP address")
+			}
+			return nil
+		}
+		// Implement a retry loop because IP address isn't added to dhcp leases file immediately
+		for i := 0; i < 30; i++ {
+			log.Debugf("Attempt %d", i)
+			err = getIP()
+			if err == nil {
+				break
+			}
+			time.Sleep(2 * time.Second)
+		}
+
+		if err != nil {
+			return errors.Wrap(err, "IP address never found in dhcp leases file")
+		}
+		log.Debugf("IP: %s", d.IPAddress)
+	}
+
+	log.Infof("Waiting for VM to start (ssh -p %d docker@%s)...", d.SSHPort, d.IPAddress)
 
-	return WaitForTCPWithDelay(fmt.Sprintf("localhost:%d", d.SSHPort), time.Second)
+	return WaitForTCPWithDelay(fmt.Sprintf("%s:%d", d.IPAddress, d.SSHPort), time.Second)
 }
 
 func cmdOutErr(cmdStr string, args ...string) (string, string, error) {
diff --git a/pkg/minikube/cluster/ip.go b/pkg/minikube/cluster/ip.go
index 313fb7265..ccfa77217 100644
--- a/pkg/minikube/cluster/ip.go
+++ b/pkg/minikube/cluster/ip.go
@@ -58,10 +58,22 @@ func HostIP(host *host.Host, clusterName string) (net.IP, error) {
 			return []byte{}, errors.Wrap(err, "Error converting VM/Host IP address to IPv4 address")
 		}
 		return net.IPv4(vmIP[0], vmIP[1], vmIP[2], byte(1)), nil
-	case driver.QEMU2:
-		return net.ParseIP("10.0.2.2"), nil
 	case driver.QEMU:
-		return net.ParseIP("10.0.2.2"), nil
+		fallthrough
+	case driver.QEMU2:
+		ipString, err := host.Driver.GetIP()
+		if err != nil {
+			return []byte{}, errors.Wrap(err, "Error getting IP address")
+		}
+		// user network case
+		if ipString == "127.0.0.1" {
+			return net.ParseIP("10.0.2.2"), nil
+		}
+		ip := net.ParseIP(ipString).To4()
+		if ip == nil {
+			return []byte{}, errors.Wrap(err, "Error converting IP address to IPv4 address")
+		}
+		return ip, nil
 	case driver.HyperV:
 		v := reflect.ValueOf(host.Driver).Elem()
 		var hypervVirtualSwitch string
@@ -151,9 +163,6 @@ func DriverIP(api libmachine.API, machineName string) (net.IP, error) {
 	if driver.IsKIC(host.DriverName) {
 		ipStr = oci.DefaultBindIPV4
 	}
-	if driver.IsQEMU(host.DriverName) {
-		ipStr = "127.0.0.1"
-	}
 	ip := net.ParseIP(ipStr)
 	if ip == nil {
 		return nil, fmt.Errorf("parsing IP: %s", ipStr)
diff --git a/pkg/minikube/driver/driver.go b/pkg/minikube/driver/driver.go
index 332daf753..c58e985e5 100644
--- a/pkg/minikube/driver/driver.go
+++ b/pkg/minikube/driver/driver.go
@@ -197,9 +197,6 @@ func AllowsPreload(driverName string) bool {
 
 // NeedsPortForward returns true if driver is unable provide direct IP connectivity
 func NeedsPortForward(name string) bool {
-	if IsQEMU(name) {
-		return true
-	}
 	if !IsKIC(name) {
 		return false
 	}
diff --git a/pkg/minikube/driver/endpoint.go b/pkg/minikube/driver/endpoint.go
index aa02afc9a..0fb86c3c9 100644
--- a/pkg/minikube/driver/endpoint.go
+++ b/pkg/minikube/driver/endpoint.go
@@ -24,11 +24,12 @@ import (
 	"k8s.io/minikube/pkg/drivers/kic/oci"
 	"k8s.io/minikube/pkg/minikube/config"
 	"k8s.io/minikube/pkg/minikube/constants"
+	"k8s.io/minikube/pkg/network"
 )
 
 // ControlPlaneEndpoint returns the location where callers can reach this cluster
 func ControlPlaneEndpoint(cc *config.ClusterConfig, cp *config.Node, driverName string) (string, net.IP, int, error) {
-	if NeedsPortForward(driverName) && IsKIC(driverName) {
+	if NeedsPortForward(driverName) {
 		port, err := oci.ForwardedPort(cc.Driver, cc.Name, cp.Port)
 		if err != nil {
 			klog.Warningf("failed to get forwarded control plane port %v", err)
@@ -45,7 +46,7 @@ func ControlPlaneEndpoint(cc *config.ClusterConfig, cp *config.Node, driverName
 			hostname = cc.KubernetesConfig.APIServerName
 		}
 		return hostname, ips[0], port, err
-	} else if NeedsPortForward(driverName) && IsQEMU(driverName) {
+	} else if IsQEMU(driverName) && network.IsUser(cc.Network) {
 		return "localhost", net.IPv4(127, 0, 0, 1), cc.APIServerPort, nil
 	}
 
diff --git a/pkg/minikube/node/start.go b/pkg/minikube/node/start.go
index 2217f52f2..5c86184b1 100644
--- a/pkg/minikube/node/start.go
+++ b/pkg/minikube/node/start.go
@@ -64,6 +64,7 @@ import (
 	"k8s.io/minikube/pkg/minikube/registry"
 	"k8s.io/minikube/pkg/minikube/style"
 	"k8s.io/minikube/pkg/minikube/vmpath"
+	"k8s.io/minikube/pkg/network"
 	"k8s.io/minikube/pkg/util"
 	"k8s.io/minikube/pkg/util/retry"
 	kconst "k8s.io/minikube/third_party/kubeadm/app/constants"
@@ -561,7 +562,7 @@ func startMachine(cfg *config.ClusterConfig, node *config.Node, delOnFail bool)
 		return runner, preExists, m, host, errors.Wrap(err, "Failed to validate network")
 	}
 
-	if driver.IsQEMU(host.Driver.DriverName()) {
+	if driver.IsQEMU(host.Driver.DriverName()) && network.IsUser(cfg.Network) {
 		apiServerPort, err := getPort()
 		if err != nil {
 			return runner, preExists, m, host, errors.Wrap(err, "Failed to find apiserver port")
@@ -664,7 +665,7 @@ func validateNetwork(h *host.Host, r command.Runner, imageRepository string, kub
 		}
 	}
 
-	if !driver.BareMetal(h.Driver.DriverName()) && !driver.IsKIC(h.Driver.DriverName()) && !driver.IsQEMU(h.Driver.DriverName()) {
+	if shouldTrySSH(h.Driver.DriverName(), ip) {
 		if err := trySSH(h, ip); err != nil {
 			return ip, err
 		}
@@ -675,6 +676,17 @@ func validateNetwork(h *host.Host, r command.Runner, imageRepository string, kub
 	return ip, nil
 }
 
+func shouldTrySSH(driverName, ip string) bool {
+	if driver.BareMetal(driverName) || driver.IsKIC(driverName) {
+		return false
+	}
+	// QEMU with user network
+	if driver.IsQEMU(driverName) && ip == "127.0.0.1" {
+		return false
+	}
+	return true
+}
+
 func trySSH(h *host.Host, ip string) error {
 	if viper.GetBool("force") {
 		return nil
diff --git a/pkg/minikube/registry/drvs/qemu2/qemu2.go b/pkg/minikube/registry/drvs/qemu2/qemu2.go
index 40305eb1d..d5264136c 100644
--- a/pkg/minikube/registry/drvs/qemu2/qemu2.go
+++ b/pkg/minikube/registry/drvs/qemu2/qemu2.go
@@ -17,6 +17,7 @@ limitations under the License.
 package qemu2
 
 import (
+	"crypto/rand"
 	"fmt"
 	"os"
 	"os/exec"
@@ -158,10 +159,9 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
 	if err != nil {
 		return nil, err
 	}
-	qemuNetwork := cc.Network
-	if qemuNetwork == "" {
-		qemuNetwork = "user"
-		// TODO: on next minor release, default to "socket".
+	mac, err := generateMACAddress()
+	if err != nil {
+		return nil, fmt.Errorf("generating MAC address: %v", err)
 	}
 
 	return qemu.Driver{
@@ -183,9 +183,10 @@ func configure(cc config.ClusterConfig, n config.Node) (interface{}, error) {
 		CPUType:        qemuCPU,
 		Firmware:       qemuFirmware,
 		VirtioDrives:   false,
-		Network:        qemuNetwork,
+		Network:        cc.Network,
 		CacheMode:      "default",
 		IOMode:         "threads",
+		MACAddress:     mac,
 	}, nil
 }
 
@@ -210,3 +211,14 @@ func status() registry.State {
 
 	return registry.State{Installed: true, Healthy: true, Running: true}
 }
+
+func generateMACAddress() (string, error) {
+	buf := make([]byte, 6)
+	if _, err := rand.Read(buf); err != nil {
+		return "", err
+	}
+	// Set local bit, ensure unicast address, socket_vmnet doesn't support multicast
+	buf[0] = (buf[0] | 2) & 0xfe
+	mac := fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5])
+	return mac, nil
+}
diff --git a/pkg/network/network.go b/pkg/network/network.go
index cc5ba15f5..bf7b1d644 100644
--- a/pkg/network/network.go
+++ b/pkg/network/network.go
@@ -218,6 +218,11 @@ func isSubnetPrivate(subnet string) bool {
 	return false
 }
 
+// IsUser returns if network is user.
+func IsUser(network string) bool {
+	return network == "user"
+}
+
 // FreeSubnet will try to find free private network beginning with startSubnet, incrementing it in steps up to number of tries.
 func FreeSubnet(startSubnet string, step, tries int) (*Parameters, error) {
 	for try := 0; try < tries; try++ {
diff --git a/site/content/en/docs/drivers/qemu.md b/site/content/en/docs/drivers/qemu.md
index e48a23308..b3933d75e 100644
--- a/site/content/en/docs/drivers/qemu.md
+++ b/site/content/en/docs/drivers/qemu.md
@@ -29,6 +29,34 @@ minikube start supports some qemu specific flags:
   * Note: while the flag should override the config, if the flag does not take effect try running `minikube delete`.
   * MacPorts: if you are installing [minikube](https://ports.macports.org/port/minikube/) and [qemu](https://ports.macports.org/port/qemu/) via MacPorts on a Mac with M1, use the following flag: `--qemu-firmware-path=/opt/local/share/qemu/edk2-aarch64-code.fd`
 
+## Networking
+
+The QEMU driver has two networking options, `user` & `socket_vmnet`.
+
+{{% tabs %}}
+{{% tab "user - limited functionality" %}}
+The `user` network is not a dedicated network, it doesn't support some networking commands such as `minikube service` and `minikube tunnel`, and its IP address is not reachable from the host.
+{{% /tab %}}
+{{% tab "socket_vmnet - experimental/needs installation" %}}
+##### Requirements
+
+Requires macOS 10.15 or later and socket_vmnet.
+
+[lima-vm/socket_vmnet](https://github.com/lima-vm/socket_vmnet) install instructions:
+```shell
+git clone https://github.com/lima-vm/socket_vmnet.git && cd socket_vmnet
+sudo make PREFIX=/opt/socket_vmnet install
+```
+
+##### Usage
+```shell
+minikube start --driver qemu --network socket_vmnet
+```
+
+The `socket_vmnet` network is a dedicated network and supports the `minikube service` and `minikube tunnel` commands.
+{{% /tab %}}
+{{% /tabs %}}
+
 ## Known Issues
 
 ### 1. Start stuck with `user` network on corp machine or custom DNS
diff --git a/translations/de.json b/translations/de.json
index a9c48b5e1..54a30bd96 100644
--- a/translations/de.json
+++ b/translations/de.json
@@ -689,6 +689,7 @@
 	"The control plane node must be running for this command": "Der Kontroll-Ebenen-Node muss für diesen Befehl laufen",
 	"The cri socket path to be used": "Der zu verwendende Cri-Socket-Pfad",
 	"The cri socket path to be used.": "Der zu verwendende Cri-Socket-Pfad.",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "Der docker-env Befehl ist inkompatibel mit multi-node Clustern. Bitte verwende das 'registry' Addon: https://minikube.sigs.k8s.io/docs/handbook/registry/",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "Der docker-env Befehl ist nur mit der \"Docker\" Laufzeitsumgebung kompatibel, aber dieser Cluster ist für die\"{{.runtime}}\" Laufzeitumgebung konfiguriert.",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "Der Treiber '{{.driver}}' wird auf {{.os}}/{{.arch}} nicht unterstützt",
@@ -848,7 +849,7 @@
 	"Using image repository {{.name}}": "Verwenden des Image-Repositorys {{.name}}",
 	"Using image {{.registry}}{{.image}}": "Verwende Image {{.registry}}{{.image}}",
 	"Using image {{.registry}}{{.image}} (global image repository)": "Verwende das Image {{.registry}}{{.image}} (globale Image Repository)",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -882,6 +883,7 @@
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "Sie versuchen eine Windows .exe Binärdatei innerhalb von WSL auszuführen. Bitte verwenden Sie stattdessen eine Linux Binärdatei für eine bessere Integration (Download-Möglichkeit: https://minikube.sigs.k8s.io/docs/start/.). Alternativ, wenn Sie dies wirklich möchten, können Sie dies mit --force erzwingen",
 	"You are trying to run amd64 binary on M1 system. Please consider running darwin/arm64 binary instead (Download at {{.url}}.)": "Sie versuchen ein amd64-Binärformat auf einem M1 System auszuführen. Bitte erwägen Sie eine darwin/amd64 Binärdatei stattdessen zu verwenden (Download-Möglichkeit: {{.url}})",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "Sie können einen mit 'minikube start' erstellen.\n\t\t",
 	"You can delete them using the following command(s): ": "Sie können diese mit dem folgenden Befehl/den folgenden Befehlen löschen:",
 	"You can force an unsupported Kubernetes version via the --force flag": "Sie können das Verwenden einer nicht unterstützten Kubernetes Version mit dem --force Parameter erzwingen",
@@ -973,10 +975,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "Minikube Profil wurde erfolgreich gesetzt auf {{.profile_name}}",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "Minikube provisioniert und managed lokale Kubernetes Cluster optimiert für Entwicklungs-Workflows.",
 	"minikube quickly sets up a local Kubernetes cluster": "Minikube installiert schnell einen lokalen Kubernetes Cluster",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "Minikube überspringt diverse Validierungen wenn --force angegeben ist; das könnte zu unerwartetem Verhalten führen",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "Minikube {{.version}} ist verfügbar. Lade es herunter: {{.url}}",
 	"mkcmp is used to compare performance of two minikube binaries": "mkcmp wird verwendet um die Performance von zwei Minikube Binaries zu vergleichen",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "Das Argument \"{{.value}}\" für Mount muss in der Form \u003cQuell Verzeichnis\u003e:\u003cZiel Verzeichnis\u003e",
@@ -1000,7 +1002,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "Das geplante Stoppen wird von none Treiber nicht unterstützt, überspringe Planung",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "Service {{.namespace_name}}/{{.service_name}} hat keinen Node Port",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "state Fehler",
 	"status json failure": "Status json Fehler",
 	"status text failure": "Status text Fehler",
diff --git a/translations/es.json b/translations/es.json
index 876c2e085..73ea9f833 100644
--- a/translations/es.json
+++ b/translations/es.json
@@ -690,6 +690,7 @@
 	"The control plane node must be running for this command": "",
 	"The cri socket path to be used": "La ruta del socket de cri",
 	"The cri socket path to be used.": "",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "El controlador \"{{.driver}}\" no se puede utilizar en {{.os}}/{{.arch}}",
@@ -849,7 +850,7 @@
 	"Using image repository {{.name}}": "Utilizando el repositorio de imágenes {{.name}}",
 	"Using image {{.registry}}{{.image}}": "",
 	"Using image {{.registry}}{{.image}} (global image repository)": "",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -882,6 +883,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}). Please see {{.documentation_url}} for more details": "Parece que estás usando un proxy, pero tu entorno NO_PROXY no incluye la dirección IP de minikube ({{.ip_address}}). Consulta {{.documentation_url}} para obtener más información",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "",
 	"You can delete them using the following command(s): ": "",
 	"You can force an unsupported Kubernetes version via the --force flag": "",
@@ -968,10 +970,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "",
 	"minikube quickly sets up a local Kubernetes cluster": "",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "",
 	"mkcmp is used to compare performance of two minikube binaries": "",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
@@ -994,7 +996,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "",
 	"status json failure": "",
 	"status text failure": "",
diff --git a/translations/fr.json b/translations/fr.json
index ea91d51a5..38488d1bc 100644
--- a/translations/fr.json
+++ b/translations/fr.json
@@ -668,6 +668,7 @@
 	"The control plane node is not running (state={{.state}})": "Le nœud du plan de contrôle n'est pas en cours d'exécution (state={{.state}})",
 	"The control plane node must be running for this command": "Le nœud du plan de contrôle doit être en cours d'exécution pour cette commande",
 	"The cri socket path to be used.": "Le chemin de socket cri à utiliser.",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "La commande docker-env est incompatible avec les clusters multi-nœuds. Utilisez le module 'registry' : https://minikube.sigs.k8s.io/docs/handbook/registry/",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "La commande docker-env n'est compatible qu'avec le runtime \"docker\", mais ce cluster a été configuré pour utiliser le runtime \"{{.runtime}}\".",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "Le pilote \"{{.driver}}\" n'est pas compatible avec {{.os}}/{{.arch}}.",
@@ -820,6 +821,7 @@
 	"Using image repository {{.name}}": "Utilisation du dépôt d'images {{.name}}…",
 	"Using image {{.registry}}{{.image}}": "Utilisation de l'image {{.registry}}{{.image}}",
 	"Using image {{.registry}}{{.image}} (global image repository)": "Utilisation de l'image {{.registry}}{{.image}} (référentiel d'images global)",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "L'utilisation de qemu avec --network=socket pour 'socket_vmnet' est expérimentale",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "L'utilisation du pilote Docker sans root était nécessaire, mais le Docker actuel ne semble pas sans root. Essayez 'docker context use rootless' .",
 	"Using rootless driver was required, but the current driver does not seem rootless": "L'utilisation d'un pilote sans root était nécessaire, mais le pilote actuel ne semble pas sans root",
@@ -851,6 +853,7 @@
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "Vous essayez d'exécuter un binaire Windows .exe dans WSL. Pour une meilleure intégration, veuillez utiliser un binaire Linux à la place (Télécharger sur https://minikube.sigs.k8s.io/docs/start/.). Sinon, si vous voulez toujours le faire, vous pouvez le faire en utilisant --force",
 	"You are trying to run amd64 binary on M1 system. Please consider running darwin/arm64 binary instead (Download at {{.url}}.)": "Vous essayez d'exécuter le binaire amd64 sur le système M1. Veuillez utiliser le binaire darwin/arm64 à la place (télécharger sur {{.url}}.)",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "Vous essayez d'exécuter le binaire amd64 sur un système M1.\nVeuillez envisager d'exécuter le binaire darwin/arm64 à la place.\nTéléchargez sur {{.url}}",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "Vous pouvez en créer un en utilisant 'minikube start'.\n\t\t",
 	"You can delete them using the following command(s): ": "Vous pouvez les supprimer à l'aide de la ou des commandes suivantes :",
 	"You can force an unsupported Kubernetes version via the --force flag": "Vous pouvez forcer une version Kubernetes non prise en charge via l'indicateur --force",
@@ -944,9 +947,11 @@
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "minikube provisionne et gère des clusters Kubernetes locaux optimisés pour les workflows de développement.",
 	"minikube quickly sets up a local Kubernetes cluster": "minikube configure rapidement un cluster Kubernetes local",
 	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Le service minikube n'est actuellement pas implémenté avec le pilote qemu2. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "minikube ignore diverses validations lorsque --force est fourni ; cela peut conduire à un comportement inattendu",
 	"minikube status --output OUTPUT. json, text": "état minikube --sortie SORTIE. json, texte",
 	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "Le tunnel minikube n'est actuellement pas implémenté avec le pilote qemu2. Voir https://github.com/kubernetes/minikube/issues/14146 pour plus de détails.",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "minikube {{.version}} est disponible ! Téléchargez-le ici : {{.url}}",
 	"mkcmp is used to compare performance of two minikube binaries": "mkcmp est utilisé pour comparer les performances de deux binaires minikube",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "argument de montage \"{{.value}}\" doit être de la forme : \u003cdossier source\u003e:\u003cdossier de destination\u003e",
@@ -969,7 +974,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "l'arrêt programmé n'est pas pris en charge sur le pilote none, programmation non prise en compte",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "le service {{.namespace_name}}/{{.service_name}} n'a pas de port de nœud",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "définit l'adresse de liaison du tunnel, vide ou '*' indique que le tunnel doit être disponible pour toutes les interfaces",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "Les indicateurs de réseau socket_vmnet ne sont pas encore implémentés avec le pilote qemu2.\n Voir https://github.com/kubernetes/minikube/pull/14890 pour plus de détails.",
 	"stat failed": "stat en échec",
 	"status json failure": "état du JSON en échec",
 	"status text failure": "état du texte en échec",
diff --git a/translations/ja.json b/translations/ja.json
index c6b3acd66..bb127a46c 100644
--- a/translations/ja.json
+++ b/translations/ja.json
@@ -641,6 +641,7 @@
 	"The control plane node is not running (state={{.state}})": "コントロールプレーンノードは実行中ではありません (state={{.state}})",
 	"The control plane node must be running for this command": "このコマンドではコントロールプレーンノードが実行中でなければなりません",
 	"The cri socket path to be used.": "使用される CRI ソケットパス。",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "docker-env コマンドはマルチノードクラスターと互換性がありません。'registry' アドオンを使用してください: https://minikube.sigs.k8s.io/docs/handbook/registry/",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "docker-env コマンドは「docker」ランタイムとだけ互換性がありますが、このクラスターは「{{.runtime}}」ランタイムを使用するよう設定されています。",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "'{{.driver}}' ドライバーは {{.os}}/{{.arch}} に対応していません",
@@ -788,7 +789,7 @@
 	"Using image repository {{.name}}": "{{.name}} イメージリポジトリーを使用しています",
 	"Using image {{.registry}}{{.image}}": "{{.registry}}{{.image}} イメージを使用しています",
 	"Using image {{.registry}}{{.image}} (global image repository)": "{{.registry}}{{.image}} イメージ (グローバルイメージリポジトリー) を使用しています",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "rootless Docker ドライバー使用が必要でしたが、現在の Docker は rootless が必要ないようです。'docker context use rootless' を試してみてください。",
 	"Using rootless driver was required, but the current driver does not seem rootless": "rootless ドライバー使用が必要でしたが、現在のドライバーは rootless が必要ないようです",
 	"Using rootless {{.driver_name}} driver": "rootless {{.driver_name}} ドライバー使用",
@@ -818,6 +819,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).": "プロキシーを使用しようとしていますが、minikube の IP ({{.ip_address}}) が NO_PROXY 環境変数に含まれていません。",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "WSL 内で Windows の .exe バイナリーを実行しようとしています。これより優れた統合として、Linux バイナリーを代わりに使用してください (https://minikube.sigs.k8s.io/docs/start/ でダウンロードしてください)。そうではなく、引き続きこのバイナリーを使用したい場合、--force オプションを使用してください",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "M1 システム上で amd64 バイナリーを実行しようとしています。\ndarwin/arm64 バイナリーを代わりに実行することをご検討ください。\n{{.url}} でダウンロードしてください。",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "'minikube start' を使って新しいものを作成できます。\n\t\t",
 	"You can delete them using the following command(s): ": "次のコマンドで削除できます: ",
 	"You can force an unsupported Kubernetes version via the --force flag": "--force フラグを介して、サポート外の Kubernetes バージョンを強制的に使用できます",
@@ -905,9 +907,11 @@
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "minikube は、開発ワークフロー用に最適化されたローカル Kubernetes クラスターを構築・管理します。",
 	"minikube quickly sets up a local Kubernetes cluster": "minikube はローカル Kubernetes クラスターを迅速にセットアップします",
 	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "minikube サービスは現在、qemu2 ドライバーでは実装されていません。詳細については、https://github.com/kubernetes/minikube/issues/14146 を参照してください。",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "minikube は --force が付与された場合、様々な検証をスキップします (これは予期せぬ挙動を引き起こすかも知れません)",
 	"minikube status --output OUTPUT. json, text": "minikube status --output OUTPUT. json, text",
 	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "minikube トンネルは現在、qemu2 ドライバーでは実装されていません。 詳細については、https://github.com/kubernetes/minikube/issues/14146 を参照してください。",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "minikube {{.version}} が利用可能です！次の URL からダウンロードしてください: {{.url}}",
 	"mkcmp is used to compare performance of two minikube binaries": "mkcmp で 2 つの minikube のバイナリーのパフォーマンスを比較できます",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "マウント引数「{{.value}}」は次の形式でなければなりません: \u003cソースディレクトリー\u003e:\u003cターゲットディレクトリー\u003e",
@@ -930,7 +934,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "none ドライバーでは予定停止がサポートされていません (予約をスキップします)",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "サービス {{.namespace_name}}/{{.service_name}} は NodePort がありません",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "トンネル バインド アドレスを設定します。空または '*' は、トンネルがすべてのインターフェイスで使用可能であることを示します",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "stat に失敗しました",
 	"status json failure": "status json に失敗しました",
 	"status text failure": "status text に失敗しました",
diff --git a/translations/ko.json b/translations/ko.json
index 92046c658..e8bc5951b 100644
--- a/translations/ko.json
+++ b/translations/ko.json
@@ -695,6 +695,7 @@
 	"The control plane node is not running (state={{.state}})": "컨트롤 플레인 노드가 실행 상태가 아닙니다 (상태={{.state}})",
 	"The control plane node must be running for this command": "컨트롤 플레인 노드는 실행 상태여야 합니다",
 	"The cri socket path to be used.": "",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "",
@@ -848,7 +849,7 @@
 	"Using image repository {{.name}}": "",
 	"Using image {{.registry}}{{.image}}": "",
 	"Using image {{.registry}}{{.image}} (global image repository)": "",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -879,6 +880,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).": "",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can also use 'minikube kubectl -- get pods' to invoke a matching version": "맞는 버전의 kubectl 을 사용하기 위해서는 다음과 같이 사용 가능합니다. minikube kubectl -- get pods'",
 	"You can create one using 'minikube start'.\n\t\t": "",
 	"You can delete them using the following command(s):": "다음 명령어(들)을 사용하여 제거할 수 있습니다",
@@ -976,10 +978,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "minikube는 개발 워크플로우에 최적화된 로컬 쿠버네티스를 제공하고 관리합니다.",
 	"minikube quickly sets up a local Kubernetes cluster": "",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "minikube {{.version}} 이 사용가능합니다! 다음 경로에서 다운받으세요: {{.url}}",
 	"mkcmp is used to compare performance of two minikube binaries": "",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
@@ -1002,7 +1004,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "",
 	"status json failure": "",
 	"status text failure": "",
diff --git a/translations/pl.json b/translations/pl.json
index faca6040d..1d0a99f63 100644
--- a/translations/pl.json
+++ b/translations/pl.json
@@ -702,6 +702,7 @@
 	"The control plane node is not running (state={{.state}})": "",
 	"The control plane node must be running for this command": "",
 	"The cri socket path to be used.": "",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker service is currently not active": "Serwis docker jest nieaktywny",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "",
@@ -858,7 +859,7 @@
 	"Using image repository {{.name}}": "",
 	"Using image {{.registry}}{{.image}}": "",
 	"Using image {{.registry}}{{.image}} (global image repository)": "",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -893,6 +894,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).": "",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "",
 	"You can delete them using the following command(s): ": "",
 	"You can force an unsupported Kubernetes version via the --force flag": "",
@@ -981,10 +983,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "profil minikube został z powodzeniem zmieniony na: {{.profile_name}}",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "minikube dostarcza lokalne klastry Kubernetesa zoptymalizowane do celów rozwoju oprogramowania oraz zarządza nimi",
 	"minikube quickly sets up a local Kubernetes cluster": "minikube szybko inicjalizuje lokalny klaster Kubernetesa",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "użycie flagi --force sprawia, że minikube pomija pewne walidacje, co może skutkować niespodziewanym zachowaniem",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "minikube {{.version}} jest dostępne! Pobierz je z: {{.url}}",
 	"mkcmp is used to compare performance of two minikube binaries": "",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
@@ -1007,7 +1009,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "wykonanie komendy stat nie powiodło się",
 	"status json failure": "",
 	"status text failure": "",
diff --git a/translations/ru.json b/translations/ru.json
index 789279108..c93eb21a4 100644
--- a/translations/ru.json
+++ b/translations/ru.json
@@ -637,6 +637,7 @@
 	"The control plane node is not running (state={{.state}})": "",
 	"The control plane node must be running for this command": "",
 	"The cri socket path to be used.": "",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "",
@@ -784,7 +785,7 @@
 	"Using image repository {{.name}}": "",
 	"Using image {{.registry}}{{.image}}": "Используется образ {{.registry}}{{.image}}",
 	"Using image {{.registry}}{{.image}} (global image repository)": "",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -814,6 +815,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).": "",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "",
 	"You can delete them using the following command(s): ": "",
 	"You can force an unsupported Kubernetes version via the --force flag": "",
@@ -900,10 +902,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "",
 	"minikube quickly sets up a local Kubernetes cluster": "",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "",
 	"mkcmp is used to compare performance of two minikube binaries": "",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
@@ -926,7 +928,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "",
 	"status json failure": "",
 	"status text failure": "",
diff --git a/translations/strings.txt b/translations/strings.txt
index 7eedf237a..5cf8d39da 100644
--- a/translations/strings.txt
+++ b/translations/strings.txt
@@ -637,6 +637,7 @@
 	"The control plane node is not running (state={{.state}})": "",
 	"The control plane node must be running for this command": "",
 	"The cri socket path to be used.": "",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "",
@@ -784,7 +785,7 @@
 	"Using image repository {{.name}}": "",
 	"Using image {{.registry}}{{.image}}": "",
 	"Using image {{.registry}}{{.image}} (global image repository)": "",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -814,6 +815,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}).": "",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "",
 	"You can delete them using the following command(s): ": "",
 	"You can force an unsupported Kubernetes version via the --force flag": "",
@@ -900,10 +902,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "",
 	"minikube quickly sets up a local Kubernetes cluster": "",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "",
 	"mkcmp is used to compare performance of two minikube binaries": "",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
@@ -926,7 +928,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "",
 	"status json failure": "",
 	"status text failure": "",
diff --git a/translations/zh-CN.json b/translations/zh-CN.json
index 7e7447ddf..0afd6f312 100644
--- a/translations/zh-CN.json
+++ b/translations/zh-CN.json
@@ -793,6 +793,7 @@
 	"The control plane node must be running for this command": "",
 	"The cri socket path to be used": "需要使用的 cri 套接字路径",
 	"The cri socket path to be used.": "",
+	"The default network for QEMU will change from 'user' to 'socket_vmnet' in a future release": "",
 	"The docker-env command is incompatible with multi-node clusters. Use the 'registry' add-on: https://minikube.sigs.k8s.io/docs/handbook/registry/": "",
 	"The docker-env command is only compatible with the \"docker\" runtime, but this cluster was configured to use the \"{{.runtime}}\" runtime.": "",
 	"The driver '{{.driver}}' is not supported on {{.os}}/{{.arch}}": "{{.os}} 不支持驱动程序“{{.driver}}/{{.arch}}”",
@@ -959,7 +960,7 @@
 	"Using image repository {{.name}}": "正在使用镜像存储库 {{.name}}",
 	"Using image {{.registry}}{{.image}}": "",
 	"Using image {{.registry}}{{.image}} (global image repository)": "",
-	"Using qemu with --network=socket for 'socket_vmnet' is experimental": "",
+	"Using qemu with 'socket_vmnet' network is experimental": "",
 	"Using rootless Docker driver was required, but the current Docker does not seem rootless. Try 'docker context use rootless' .": "",
 	"Using rootless driver was required, but the current driver does not seem rootless": "",
 	"Using rootless {{.driver_name}} driver": "",
@@ -1001,6 +1002,7 @@
 	"You appear to be using a proxy, but your NO_PROXY environment does not include the minikube IP ({{.ip_address}}). Please see {{.documentation_url}} for more details": "您似乎正在使用代理，但您的 NO_PROXY 环境不包含 minikube IP ({{.ip_address}})。如需了解详情，请参阅 {{.documentation_url}}",
 	"You are trying to run a windows .exe binary inside WSL. For better integration please use a Linux binary instead (Download at https://minikube.sigs.k8s.io/docs/start/.). Otherwise if you still want to do this, you can do it using --force": "",
 	"You are trying to run the amd64 binary on an M1 system.\nPlease consider running the darwin/arm64 binary instead.\nDownload at {{.url}}": "",
+	"You are using the QEMU driver without a dedicated network, which doesn't support `minikube service` \u0026 `minikube tunnel` commands.\nTo try the experimental dedicated network see: https://minikube.sigs.k8s.io/docs/drivers/qemu/#networking": "",
 	"You can create one using 'minikube start'.\n\t\t": "",
 	"You can delete them using the following command(s): ": "",
 	"You can force an unsupported Kubernetes version via the --force flag": "",
@@ -1091,10 +1093,10 @@
 	"minikube profile was successfully set to {{.profile_name}}": "",
 	"minikube provisions and manages local Kubernetes clusters optimized for development workflows.": "",
 	"minikube quickly sets up a local Kubernetes cluster": "",
-	"minikube service is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube service is not currently implemented with the user network on QEMU": "",
 	"minikube skips various validations when --force is supplied; this may lead to unexpected behavior": "",
 	"minikube status --output OUTPUT. json, text": "",
-	"minikube tunnel is not currently implemented with the qemu2 driver. See https://github.com/kubernetes/minikube/issues/14146 for details.": "",
+	"minikube tunnel is not currently implemented with the user network on QEMU": "",
 	"minikube {{.version}} is available! Download it: {{.url}}": "",
 	"mkcmp is used to compare performance of two minikube binaries": "mkcmp 用于对比两个 minikube 二进制的性能",
 	"mount argument \"{{.value}}\" must be in form: \u003csource directory\u003e:\u003ctarget directory\u003e": "",
@@ -1118,7 +1120,6 @@
 	"scheduled stop is not supported on the none driver, skipping scheduling": "",
 	"service {{.namespace_name}}/{{.service_name}} has no node port": "",
 	"set tunnel bind address, empty or '*' indicates the tunnel should be available for all interfaces": "",
-	"socket_vmnet network flags are not yet implemented with the qemu2 driver.\n    See https://github.com/kubernetes/minikube/pull/14890 for details.": "",
 	"stat failed": "",
 	"status json failure": "",
 	"status text failure": "",


Test patch:
diff --git a/pkg/drivers/common_test.go b/pkg/drivers/common_test.go
index 60fe1b574..3a6d0569e 100644
--- a/pkg/drivers/common_test.go
+++ b/pkg/drivers/common_test.go
@@ -46,3 +46,81 @@ func Test_createDiskImage(t *testing.T) {
 		t.Errorf("Disk size is %v, want %v", fi.Size(), sizeInBytes)
 	}
 }
+
+var validLeases = []byte(`{
+        name=foo
+        ip_address=1.2.3.4
+        hw_address=1,a1:b2:c3:d4:e5:f6
+        identifier=1,a2:b3:c4:d5:e6:f7
+        lease=0x597e1267
+}
+{
+        name=bar
+        ip_address=192.168.64.3
+        hw_address=1,a4:b5:c6:d7:e8:f9
+        identifier=1,a0:b0:c0:d0:e0:f0
+        lease=0x597e1267
+}
+{
+        name=bar
+        ip_address=192.168.64.4
+        hw_address=1,a5:b6:c7:d8:e9:f1
+        identifier=1,a5:b6:c7:d8:e9:f1
+        lease=0x597e1268
+}`)
+
+func Test_getIpAddressFromFile(t *testing.T) {
+	tmpdir := tests.MakeTempDir(t)
+
+	dhcpFile := filepath.Join(tmpdir, "dhcp")
+	if err := os.WriteFile(dhcpFile, validLeases, 0644); err != nil {
+		t.Fatalf("writefile: %v", err)
+	}
+
+	invalidFile := filepath.Join(tmpdir, "invalid")
+	if err := os.WriteFile(invalidFile, []byte("foo"), 0644); err != nil {
+		t.Fatalf("writefile: %v", err)
+	}
+
+	type args struct {
+		mac  string
+		path string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    string
+		wantErr bool
+	}{
+		{
+			"valid",
+			args{"a1:b2:c3:d4:e5:f6", dhcpFile},
+			"1.2.3.4",
+			false,
+		},
+		{
+			"duplicate",
+			args{"a4:b5:c6:d7:e8:f9", dhcpFile},
+			"192.168.64.3",
+			false,
+		},
+		{
+			"invalid",
+			args{"a1:b2:c3:d4:e5:f6", invalidFile},
+			"",
+			true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := getIPAddressFromFile(tt.args.mac, tt.args.path)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("getIPAddressFromFile() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("getIPAddressFromFile() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/pkg/drivers/hyperkit/network_test.go b/pkg/drivers/hyperkit/network_test.go
deleted file mode 100644
index 856e27ce4..000000000
--- a/pkg/drivers/hyperkit/network_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-//go:build darwin
-
-/*
-Copyright 2016 The Kubernetes Authors All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package hyperkit
-
-import (
-	"os"
-	"path/filepath"
-	"testing"
-
-	"k8s.io/minikube/pkg/minikube/tests"
-)
-
-var validLeases = []byte(`{
-	name=foo
-	ip_address=1.2.3.4
-	hw_address=1,a1:b2:c3:d4:e5:f6
-	identifier=1,a2:b3:c4:d5:e6:f7
-	lease=0x597e1267
-}
-{
-	name=bar
-	ip_address=192.168.64.3
-	hw_address=1,a4:b5:c6:d7:e8:f9
-	identifier=1,a0:b0:c0:d0:e0:f0
-	lease=0x597e1267
-}
-{
-	name=bar
-	ip_address=192.168.64.4
-	hw_address=1,a5:b6:c7:d8:e9:f1
-	identifier=1,a5:b6:c7:d8:e9:f1
-	lease=0x597e1268
-}`)
-
-func Test_getIpAddressFromFile(t *testing.T) {
-	tmpdir := tests.MakeTempDir(t)
-
-	dhcpFile := filepath.Join(tmpdir, "dhcp")
-	if err := os.WriteFile(dhcpFile, validLeases, 0644); err != nil {
-		t.Fatalf("writefile: %v", err)
-	}
-
-	invalidFile := filepath.Join(tmpdir, "invalid")
-	if err := os.WriteFile(invalidFile, []byte("foo"), 0644); err != nil {
-		t.Fatalf("writefile: %v", err)
-	}
-
-	type args struct {
-		mac  string
-		path string
-	}
-	tests := []struct {
-		name    string
-		args    args
-		want    string
-		wantErr bool
-	}{
-		{
-			"valid",
-			args{"a1:b2:c3:d4:e5:f6", dhcpFile},
-			"1.2.3.4",
-			false,
-		},
-		{
-			"duplicate",
-			args{"a4:b5:c6:d7:e8:f9", dhcpFile},
-			"192.168.64.3",
-			false,
-		},
-		{
-			"invalid",
-			args{"a1:b2:c3:d4:e5:f6", invalidFile},
-			"",
-			true,
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := getIPAddressFromFile(tt.args.mac, tt.args.path)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("getIPAddressFromFile() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if got != tt.want {
-				t.Errorf("getIPAddressFromFile() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}