Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new macOS vfkit driver, like hyperkit and qemu #19423

Merged
merged 8 commits into from
Sep 3, 2024

Conversation

afbjorklund
Copy link
Collaborator

@afbjorklund afbjorklund commented Aug 13, 2024

It uses the new Virtualization.framework from macOS 11, instead of the older Hypervisor.framework (hvf) in QEMU.

Closes #12826


The "hyperkit" binary was bundled with Docker for Mac, but is available stand-alone:

https://github.com/moby/hyperkit

The "vfkit" binary is bundled with Podman Desktop (macOS), and is available stand-alone:

https://github.com/crc-org/vfkit

@k8s-ci-robot k8s-ci-robot requested review from medyagh and prezha August 13, 2024 10:00
@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 13, 2024
@afbjorklund
Copy link
Collaborator Author

Some code is duplicated between pkg/drivers/hyperkit, pkg/drivers/qemu and pkg/drivers/vfkit.

It could be considered, to (later!) refactor this into the "common" part under pkg/drivers directly...

@afbjorklund afbjorklund requested review from spowelljr and removed request for prezha August 13, 2024 17:55
pkg/drivers/vfkit/iso.go Outdated Show resolved Hide resolved
@medyagh
Copy link
Member

medyagh commented Aug 15, 2024

This is a very exciting PR ! thank you for thinking about it
it is not working for me on macos M1 (arm64)

I0815 15:38:39.293989   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.2 HWAddress:ca:96:e9:43:b9:43 ID:1,ca:96:e9:43:b9:43 Lease:0x646e4c8e}
I0815 15:38:41.295145   63339 main.go:141] libmachine: Attempt 28
I0815 15:38:41.295195   63339 main.go:141] libmachine: Searching for 76:70:dd:1:99:e2 in /var/db/dhcpd_leases ...
I0815 15:38:41.295760   63339 main.go:141] libmachine: Found 34 entries in /var/db/dhcpd_leases!
I0815 15:38:41.295820   63339 main.go:141] libmachine: dhcp entry: {Name: IPAddress:192.168.106.2 HWAddress:7e:b:7b:f9:40:ae ID:1,7e:b:7b:f9:40:ae Lease:0x66aac1c1}
I0815 15:38:41.295843   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.34 HWAddress:8a:37:82:8d:50:f0 ID:1,8a:37:82:8d:50:f0 Lease:0x668d8331}
I0815 15:38:41.295863   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.33 HWAddress:a:94:4f:77:5f:83 ID:1,a:94:4f:77:5f:83 Lease:0x66649746}
I0815 15:38:41.295888   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.32 HWAddress:ea:cc:a6:94:f1:58 ID:1,ea:cc:a6:94:f1:58 Lease:0x66623678}
I0815 15:38:41.296047   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.31 HWAddress:f2:8f:83:8:6e:9e ID:1,f2:8f:83:8:6e:9e Lease:0x664e2690}
I0815 15:38:41.296081   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.30 HWAddress:2e:ee:ae:b:15:c5 ID:1,2e:ee:ae:b:15:c5 Lease:0x663eb6d8}
I0815 15:38:41.296119   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.29 HWAddress:6:8c:7d:21:84:7a ID:1,6:8c:7d:21:84:7a Lease:0x663eaece}
I0815 15:38:41.296142   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.28 HWAddress:a6:91:9b:ff:1a:c7 ID:1,a6:91:9b:ff:1a:c7 Lease:0x663eaddc}
I0815 15:38:41.296164   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.27 HWAddress:b6:15:58:c6:cf:c3 ID:1,b6:15:58:c6:cf:c3 Lease:0x663e9198}
I0815 15:38:41.296187   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.26 HWAddress:26:12:63:a2:cf:af ID:1,26:12:63:a2:cf:af Lease:0x6633c7b9}
I0815 15:38:41.296208   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.25 HWAddress:12:da:f7:50:c2:27 ID:1,12:da:f7:50:c2:27 Lease:0x66327ee3}
I0815 15:38:41.296230   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.24 HWAddress:82:1e:1:e2:6c:bb ID:1,82:1e:1:e2:6c:bb Lease:0x662c2929}
I0815 15:38:41.296272   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.23 HWAddress:ca:94:90:33:e1:19 ID:1,ca:94:90:33:e1:19 Lease:0x66280395}
I0815 15:38:41.296295   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.22 HWAddress:ce:1e:18:a6:2c:dc ID:1,ce:1e:18:a6:2c:dc Lease:0x6616bb16}
I0815 15:38:41.296316   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.21 HWAddress:fe:f9:df:2b:92:fd ID:1,fe:f9:df:2b:92:fd Lease:0x660dbec9}
I0815 15:38:41.296337   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.20 HWAddress:3a:5c:a4:60:23:dd ID:1,3a:5c:a4:60:23:dd Lease:0x660dbde6}
I0815 15:38:41.296359   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.19 HWAddress:9e:5:a1:b4:2:91 ID:1,9e:5:a1:b4:2:91 Lease:0x65678416}
I0815 15:38:41.296380   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.18 HWAddress:e:9d:a6:2:8:1d ID:1,e:9d:a6:2:8:1d Lease:0x65144f88}
I0815 15:38:41.296400   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.17 HWAddress:a6:2a:9b:f7:48:39 ID:1,a6:2a:9b:f7:48:39 Lease:0x65049be4}
I0815 15:38:41.296423   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.16 HWAddress:46:c9:95:80:5a:b8 ID:1,46:c9:95:80:5a:b8 Lease:0x64cb063b}
I0815 15:38:41.296444   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.15 HWAddress:6e:e7:c0:43:e5:e9 ID:1,6e:e7:c0:43:e5:e9 Lease:0x64c883fe}
I0815 15:38:41.296466   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.14 HWAddress:46:17:5b:20:e9:c1 ID:1,46:17:5b:20:e9:c1 Lease:0x64c883c3}
I0815 15:38:41.296486   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.13 HWAddress:be:4a:e3:61:22:87 ID:1,be:4a:e3:61:22:87 Lease:0x64c88180}
I0815 15:38:41.296506   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.12 HWAddress:ca:b6:91:14:9a:8f ID:1,ca:b6:91:14:9a:8f Lease:0x64c88095}
I0815 15:38:41.296527   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.11 HWAddress:92:c5:4a:cb:14:16 ID:1,92:c5:4a:cb:14:16 Lease:0x64add676}
I0815 15:38:41.296549   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.10 HWAddress:ea:dc:7e:e:52:e5 ID:1,ea:dc:7e:e:52:e5 Lease:0x649b2d96}
I0815 15:38:41.296570   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.9 HWAddress:3e:57:12:b8:5a:54 ID:1,3e:57:12:b8:5a:54 Lease:0x6491d686}
I0815 15:38:41.296591   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.8 HWAddress:82:cd:d8:88:50:40 ID:1,82:cd:d8:88:50:40 Lease:0x648c992a}
I0815 15:38:41.296612   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.7 HWAddress:fa:f3:26:f5:4:4d ID:1,fa:f3:26:f5:4:4d Lease:0x648a0ada}
I0815 15:38:41.296633   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.6 HWAddress:ae:62:32:86:d0:b ID:1,ae:62:32:86:d0:b Lease:0x648a0af2}
I0815 15:38:41.296653   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.5 HWAddress:ce:d5:f8:63:17:83 ID:1,ce:d5:f8:63:17:83 Lease:0x64821151}
I0815 15:38:41.296674   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.4 HWAddress:f6:b:8f:6e:42:1 ID:1,f6:b:8f:6e:42:1 Lease:0x646e4e12}
I0815 15:38:41.296695   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.3 HWAddress:1a:67:dd:6a:ac:b8 ID:1,1a:67:dd:6a:ac:b8 Lease:0x645a7ae8}
I0815 15:38:41.296718   63339 main.go:141] libmachine: dhcp entry: {Name:minikube IPAddress:192.168.105.2 HWAddress:ca:96:e9:43:b9:43 ID:1,ca:96:e9:43:b9:43 Lease:0x646e4c8e}
^C

here is the full log
lastStart.txt

@medyagh
Copy link
Member

medyagh commented Aug 15, 2024

update:
running same known issue for Qemu fixes it https://minikube.sigs.k8s.io/docs/drivers/qemu/#socket_vmnet

sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add /usr/libexec/bootpd
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --unblock /usr/libexec/bootpd

$ time mk start -d vfkit
😄 minikube v1.33.1 on Darwin 14.6.1 (arm64)
✨ Using the vfkit (experimental) driver based on user configuration
👍 Starting "minikube" primary control-plane node in "minikube" cluster
🔥 Creating vfkit VM (CPUs=2, Memory=4000MB, Disk=20000MB) ...
🐳 Preparing Kubernetes v1.30.3 on Docker 27.1.1 ...E0815 16:06:55.442876 71805 start.go:132] Unable to get host IP: HostIP not yet implemented for "vfkit" driver

▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...

🔗 Configuring bridge CNI (Container Networking Interface) ...
🔎 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

real 0m27.299s
user 0m1.218s
sys 0m1.105s

I do see one Log spam error though:

start.go:132] Unable to get host IP: HostIP not yet implemented for "vfkit" driver

Copy link
Member

@medyagh medyagh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to add a case for cluster/ip.go

func HostIP(host *host.Host, clusterName string) (net.IP, error) 

https://github.com/medyagh/minikube/blob/1447d5b36358e3f202d17e9617d61252eb85fa8e/pkg/minikube/cluster/ip.go#L61

I deployed a service to it and I can hit the minikbe IP directly

vfkit •1
$ mk service hello-minikube
|-----------|----------------|-------------|----------------------------|
| NAMESPACE |      NAME      | TARGET PORT |            URL             |
|-----------|----------------|-------------|----------------------------|
| default   | hello-minikube |        8080 | http://192.168.106.4:32500 |
|-----------|----------------|-------------|----------------------------|

so I could hit http://192.168.106.4:32500

@afbjorklund
Copy link
Collaborator Author

afbjorklund commented Aug 16, 2024

I do see one Log spam error though:

start.go:132] Unable to get host IP: HostIP not yet implemented for "vfkit" driver

These are hardcoded on driver name in minikube, so needs another case for vfkit

I think it can be copied from hyperkit

@afbjorklund
Copy link
Collaborator Author

/ok-to-test

There are no tests for vfkit, but nothing else should have broken either

@k8s-ci-robot k8s-ci-robot added the ok-to-test Indicates a non-member PR verified by an org member that is safe to test. label Aug 16, 2024
@minikube-pr-bot

This comment has been minimized.

@minikube-pr-bot
Copy link

Here are the number of top 10 failed tests in each environments with lowest flake rate.

Environment Test Name Flake Rate

Besides the following environments also have failed tests:

To see the flake rates of all tests by environment, click here.

pkg/drivers/vfkit/iso.go Outdated Show resolved Hide resolved
pkg/minikube/registry/drvs/vfkit/vfkit.go Show resolved Hide resolved
@spowelljr
Copy link
Member

Would be great to add functional and integration tests for this in a follow up PR so we can find any bugs and accelerate this out of experimental

nirs added a commit to nirs/ramen that referenced this pull request Aug 16, 2024
The new experimental vfkit driver[1] uses vfkit to start virtual
machines using Apple virtualisation framework when running on Apple
silicon.

This driver is not available in minikube release yet. To use it you need
to install vfkit and build minikube from the PR.

Issues:
- When terminating the process group, the vfkit process is terminated,
  and the vm is stopped. This should be fixed in minikube or vfkit by
  running the vfkit process in background or as a daemon.

[1] kubernetes/minikube#19423
[2] https://github.com/crc-org/vfkit

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
nirs added a commit to nirs/ramen that referenced this pull request Aug 16, 2024
The new experimental vfkit driver[1] uses vfkit to start virtual
machines using Apple virtualisation framework when running on Apple
silicon.

This driver is not available in minikube release yet. To use it you need
to install vfkit and build minikube from the PR.

Example run:

    % drenv start envs/example.yaml
    2024-08-16 23:31:18,271 INFO    [example] Starting environment
    2024-08-16 23:31:18,315 INFO    [ex2] Starting minikube cluster
    2024-08-16 23:31:18,320 INFO    [ex1] Starting minikube cluster
    2024-08-16 23:31:42,219 INFO    [ex2] Cluster started in 23.90 seconds
    2024-08-16 23:31:42,219 INFO    [ex2/0] Running addons/example/start
    2024-08-16 23:31:49,781 INFO    [ex2/0] addons/example/start completed in 7.56 seconds
    2024-08-16 23:31:49,781 INFO    [ex2/0] Running addons/example/test
    2024-08-16 23:31:49,917 INFO    [ex2/0] addons/example/test completed in 0.14 seconds
    2024-08-16 23:31:50,937 INFO    [ex1] Cluster started in 32.62 seconds
    2024-08-16 23:31:50,937 INFO    [ex1/0] Running addons/example/start
    2024-08-16 23:31:58,453 INFO    [ex1/0] addons/example/start completed in 7.52 seconds
    2024-08-16 23:31:58,453 INFO    [ex1/0] Running addons/example/test
    2024-08-16 23:31:58,582 INFO    [ex1/0] addons/example/test completed in 0.13 seconds
    2024-08-16 23:31:58,583 INFO    [example] Environment started in 40.31 seconds

    % minikube profile list
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | Profile | VM Driver |  Runtime   |       IP       | Port | Version | Status  | Nodes | Active Profile | Active Kubecontext |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | ex1     | vfkit     | containerd | 192.168.106.24 | 8443 | v1.31.0 | Running |     1 |                | *                  |
    | ex2     | vfkit     | containerd | 192.168.106.23 | 8443 | v1.31.0 | Running |     1 |                |                    |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|

Issues:

- When terminating the process group, the vfkit process is terminated,
  and the vm is stopped. This should be fixed in minikube or vfkit by
  running the vfkit process in background or as a daemon.

- rook does not work on arm now, likely due to
  rook/rook#14502

- We don't have arm64 images for OCM. Can be solved by enabling Rosetta
  2. This supported in vfkit but not implemented yet in the vfkit driver.

[1] kubernetes/minikube#19423
[2] https://github.com/crc-org/vfkit

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
nirs added a commit to nirs/ramen that referenced this pull request Aug 16, 2024
The new experimental vfkit driver[1] uses vfkit to start virtual
machines using Apple virtualisation framework when running on Apple
silicon.

This driver is not available in minikube release yet. To use it you need
to install vfkit and build minikube from the PR.

Example run:

    % drenv start envs/example.yaml
    2024-08-16 23:31:18,271 INFO    [example] Starting environment
    2024-08-16 23:31:18,315 INFO    [ex2] Starting minikube cluster
    2024-08-16 23:31:18,320 INFO    [ex1] Starting minikube cluster
    2024-08-16 23:31:42,219 INFO    [ex2] Cluster started in 23.90 seconds
    2024-08-16 23:31:42,219 INFO    [ex2/0] Running addons/example/start
    2024-08-16 23:31:49,781 INFO    [ex2/0] addons/example/start completed in 7.56 seconds
    2024-08-16 23:31:49,781 INFO    [ex2/0] Running addons/example/test
    2024-08-16 23:31:49,917 INFO    [ex2/0] addons/example/test completed in 0.14 seconds
    2024-08-16 23:31:50,937 INFO    [ex1] Cluster started in 32.62 seconds
    2024-08-16 23:31:50,937 INFO    [ex1/0] Running addons/example/start
    2024-08-16 23:31:58,453 INFO    [ex1/0] addons/example/start completed in 7.52 seconds
    2024-08-16 23:31:58,453 INFO    [ex1/0] Running addons/example/test
    2024-08-16 23:31:58,582 INFO    [ex1/0] addons/example/test completed in 0.13 seconds
    2024-08-16 23:31:58,583 INFO    [example] Environment started in 40.31 seconds

    % minikube profile list
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | Profile | VM Driver |  Runtime   |       IP       | Port | Version | Status  | Nodes | Active Profile | Active Kubecontext |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | ex1     | vfkit     | containerd | 192.168.106.24 | 8443 | v1.31.0 | Running |     1 |                | *                  |
    | ex2     | vfkit     | containerd | 192.168.106.23 | 8443 | v1.31.0 | Running |     1 |                |                    |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|

Issues:

- When terminating the process group, the vfkit process is terminated,
  and the vm is stopped. This should be fixed in minikube or vfkit by
  running the vfkit process in background or as a daemon.
  Fixed in my minikube fork: https://github.com/nirs/minikube/tree/vfkit-pg

- rook does not work on arm now, likely due to
  rook/rook#14502

- We don't have arm64 images for OCM. Can be solved by enabling Rosetta
  2. This supported in vfkit but not implemented yet in the vfkit driver.

[1] kubernetes/minikube#19423
[2] https://github.com/crc-org/vfkit

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
nirs added a commit to nirs/ramen that referenced this pull request Aug 16, 2024
The new experimental vfkit driver[1] uses vfkit to start virtual
machines using Apple virtualisation framework when running on Apple
silicon.

This driver is not available in minikube release yet. To use it you need
to install vfkit and build minikube from the PR.

Example run:

    % drenv start envs/example.yaml
    2024-08-16 23:31:18,271 INFO    [example] Starting environment
    2024-08-16 23:31:18,315 INFO    [ex2] Starting minikube cluster
    2024-08-16 23:31:18,320 INFO    [ex1] Starting minikube cluster
    2024-08-16 23:31:42,219 INFO    [ex2] Cluster started in 23.90 seconds
    2024-08-16 23:31:42,219 INFO    [ex2/0] Running addons/example/start
    2024-08-16 23:31:49,781 INFO    [ex2/0] addons/example/start completed in 7.56 seconds
    2024-08-16 23:31:49,781 INFO    [ex2/0] Running addons/example/test
    2024-08-16 23:31:49,917 INFO    [ex2/0] addons/example/test completed in 0.14 seconds
    2024-08-16 23:31:50,937 INFO    [ex1] Cluster started in 32.62 seconds
    2024-08-16 23:31:50,937 INFO    [ex1/0] Running addons/example/start
    2024-08-16 23:31:58,453 INFO    [ex1/0] addons/example/start completed in 7.52 seconds
    2024-08-16 23:31:58,453 INFO    [ex1/0] Running addons/example/test
    2024-08-16 23:31:58,582 INFO    [ex1/0] addons/example/test completed in 0.13 seconds
    2024-08-16 23:31:58,583 INFO    [example] Environment started in 40.31 seconds

    % minikube profile list
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | Profile | VM Driver |  Runtime   |       IP       | Port | Version | Status  | Nodes | Active Profile | Active Kubecontext |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | ex1     | vfkit     | containerd | 192.168.106.24 | 8443 | v1.31.0 | Running |     1 |                | *                  |
    | ex2     | vfkit     | containerd | 192.168.106.23 | 8443 | v1.31.0 | Running |     1 |                |                    |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|

Issues:

- When terminating the process group, the vfkit process is terminated,
  and the vm is stopped. This should be fixed in minikube or vfkit by
  running the vfkit process in background or as a daemon.
  Fixed in my minikube fork: https://github.com/nirs/minikube/tree/vfkit-pg

- rook does not work on arm now, likely due to
  rook/rook#14502

- We don't have arm64 images for OCM. Can be solved by enabling Rosetta
  2. This supported in vfkit but not implemented yet in the vfkit driver.

- Nested virtualization requires M3 CPU, and is not implemented yet in
  vfkit, so testing kubevirt VMs is not possible on Apple silicon.

[1] kubernetes/minikube#19423
[2] https://github.com/crc-org/vfkit

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
Copy link
Contributor

@nirs nirs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @afbjorklund, this is awesome!

I'm testing this now with drenv - it works great except one issue with the way the vfkit "daemon" is running.

The missing stuff for our use case is enabling rosetta, since we don't have arm64 images for OCM yet.

case driver.VFKit:
vmIPString, _ := host.Driver.GetIP()
gatewayIPString := vmIPString[:strings.LastIndex(vmIPString, ".")+1] + "1"
return net.ParseIP(gatewayIPString), nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This duplicates the hyperkit case, which is another implementation of the vmware case.

We can clean this later, but this add more work that nobody will have time to do. Why not do the simple refactoring now, and use the same helper function in all cases when we want to take an ipv4 address and replace the last component with 1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code should really be handled by the driver directly, instead of this switch case poking at driver internals

Notice how hard it is to add extra networking options to the driver, without fiddling around in minikube code

Didn't look into what part of "vanilla" uses HostIP

But using a helper function for hyperkit sounds fair.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, i would love to see a follow up refactor if someone interested, to move this logic to the driver code not in minikube code


return nil
func isBootpdError(err error) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isBoopdError() is too string, we don't have a proper way to tell, maybe use something like isLikelyBootpdError() to make our intent more clear.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably go into common, to be shared with qemu

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree this should be in the common to be reused and also renamed

pkg/drivers/vfkit/vfkit.go Show resolved Hide resolved
pkg/drivers/vfkit/iso_test.iso Outdated Show resolved Hide resolved
process, err := os.FindProcess(pid)
if err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is racy due to pid reuse, it would be less racy if we get get the process info from the kernel and verify that it is the expected vfkit executable found by exec.Cmd when starting the process.

We can use ps -o comm -p pid, or the same code it uses:
https://github.com/apple-oss-distributions/adv_cmds/blob/8744084ea0ff41ca4bb96b0f9c22407d0e48e9b7/ps/ps.c#L595

There is a Go implementation here:
https://github.com/mitchellh/go-ps/blob/master/process_darwin.go

We can also do this later, it is needed also for other drivers in macOS.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The -pidfile seems simpler

return state.Error, err
}
if err := checkPid(pid); err != nil {
// No pid, remove pidfile
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// No process with pid, remove pidfile

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably came straight from qemu

pkg/drivers/vfkit/vfkit.go Show resolved Hide resolved
startCmd = append(startCmd,
"--memory", fmt.Sprintf("%d", d.Memory),
"--cpus", fmt.Sprintf("%d", d.CPU),
"--restful-uri", fmt.Sprintf("unix://%s", d.sockfilePath()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add blank line for consistent whitespace.

}

startCmd = append(startCmd,
"--device", fmt.Sprintf("virtio-blk,path=%s", d.diskPath()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order of disks matter? If not why not add first the main disk, and then the extra disks?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most likely the order was just copied from another driver, whether it was hyperkit or qemu

pid := cmd.Process.Pid
if err := os.WriteFile(d.pidfilePath(), []byte(fmt.Sprintf("%v", pid)), 0600); err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating the pid file for vfkit is a bit racy, if we are killed after starting vfkit but before we create the pid file, we will never terminate vfkit.

I think we need to move this vfkit - it should provide a --pidfile option. It goes with the --daemonize option we also need.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another race which can happen is that vfkit can exit after cmd.Start() succeeds, for example if Apple's virtualization framework fails to start the VM and returns an error. If this happens, you'd have a pid file but no corresponding process.
I added this code in vfkit's test suite to catch this crc-org/vfkit@a38d84c
It probably would be useful to have a way to tell vfkit "do not exit by yourself, I'll explicitly stop/kill/.. you when I no longer need your process to be around"

nirs added a commit to nirs/ramen that referenced this pull request Aug 16, 2024
The new experimental vfkit driver[1] uses vfkit to start virtual
machines using Apple virtualisation framework when running on Apple
silicon.

This driver is not available in minikube release yet. To use it you need
to install vfkit and build minikube from the PR.

Example run:

    % drenv start envs/example.yaml
    2024-08-16 23:31:18,271 INFO    [example] Starting environment
    2024-08-16 23:31:18,315 INFO    [ex2] Starting minikube cluster
    2024-08-16 23:31:18,320 INFO    [ex1] Starting minikube cluster
    2024-08-16 23:31:42,219 INFO    [ex2] Cluster started in 23.90 seconds
    2024-08-16 23:31:42,219 INFO    [ex2/0] Running addons/example/start
    2024-08-16 23:31:49,781 INFO    [ex2/0] addons/example/start completed in 7.56 seconds
    2024-08-16 23:31:49,781 INFO    [ex2/0] Running addons/example/test
    2024-08-16 23:31:49,917 INFO    [ex2/0] addons/example/test completed in 0.14 seconds
    2024-08-16 23:31:50,937 INFO    [ex1] Cluster started in 32.62 seconds
    2024-08-16 23:31:50,937 INFO    [ex1/0] Running addons/example/start
    2024-08-16 23:31:58,453 INFO    [ex1/0] addons/example/start completed in 7.52 seconds
    2024-08-16 23:31:58,453 INFO    [ex1/0] Running addons/example/test
    2024-08-16 23:31:58,582 INFO    [ex1/0] addons/example/test completed in 0.13 seconds
    2024-08-16 23:31:58,583 INFO    [example] Environment started in 40.31 seconds

    % minikube profile list
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | Profile | VM Driver |  Runtime   |       IP       | Port | Version | Status  | Nodes | Active Profile | Active Kubecontext |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|
    | ex1     | vfkit     | containerd | 192.168.106.24 | 8443 | v1.31.0 | Running |     1 |                | *                  |
    | ex2     | vfkit     | containerd | 192.168.106.23 | 8443 | v1.31.0 | Running |     1 |                |                    |
    |---------|-----------|------------|----------------|------|---------|---------|-------|----------------|--------------------|

Issues:

- When terminating the process group, the vfkit process is terminated,
  and the vm is stopped. This should be fixed in minikube or vfkit by
  running the vfkit process in background or as a daemon.
  Fixed in my minikube fork: https://github.com/nirs/minikube/tree/vfkit-pg

- rook does not work on arm now, likely due to
  rook/rook#14502

- We don't have arm64 images for OCM. Can be solved by enabling Rosetta
  2. This supported in vfkit but not implemented yet in the vfkit driver.

- Nested virtualization requires M3 CPU, and is not implemented yet in
  vfkit, so testing kubevirt VMs is not possible on Apple silicon.

[1] kubernetes/minikube#19423
[2] https://github.com/crc-org/vfkit

Signed-off-by: Nir Soffer <nsoffer@redhat.com>
@afbjorklund
Copy link
Collaborator Author

afbjorklund commented Aug 17, 2024

I would like the refactoring of the hyperkit driver, including the iso "ExtractFile", to go in a separate PR.

But that can be done first, if you don't want the technical debt of simply copying the files to this driver.

diff -rs pkg/drivers/hyperkit/iso.go pkg/drivers/vfkit/iso.go
17c17
< package hyperkit
---
> package vfkit
diff -rs pkg/drivers/hyperkit/iso_test.go pkg/drivers/vfkit/iso_test.go
17c17
< package hyperkit
---
> package vfkit
Files pkg/drivers/hyperkit/iso_test.iso and pkg/drivers/vfkit/iso_test.iso are identical

It (extracting kernel) is only needed because the new vfkit "bootloader" didn't work with minikube.iso (?)

With the EFI bootloader, it is supposed to be able to read /boot/bzimage and /boot/initrd (on macOS 13)


The pidfile handling was mostly a quick hack when the --pidfile/--daemonize was missing (unlike qemu)

Those features can be driven to the CRC organization which is handling the "vfkit" (not Podman team, actually)

https://github.com/crc-org/vfkit/issues

It is mostly developed by one developer

@afbjorklund
Copy link
Collaborator Author

afbjorklund commented Aug 18, 2024

The driver probably needs a "Network" setting, in preparation for future options such as vmnet or
gvproxy. Even if it starts out with only one option

hyperkit has the (network is always "vmnet", since it doesn't do cross-platform - like qemu does)

                VpnKitSock:     cfg.HyperkitVpnKitSock,
                VSockPorts:     cfg.HyperkitVSockPorts,

qemu has the (network is user or socket, as in https://wiki.qemu.org/Documentation/Networking)

                Network:               cc.Network,
                SocketVMNetPath:       cc.SocketVMnetPath,
                SocketVMNetClientPath: cc.SocketVMnetClientPath,

vfkit options:

https://github.com/crc-org/vfkit/blob/main/doc/usage.md#networking

@minikube-pr-bot

This comment has been minimized.

@minikube-pr-bot
Copy link

Here are the number of top 10 failed tests in each environments with lowest flake rate.

Environment Test Name Flake Rate
KVM_Linux_containerd (1 failed) TestAddons/parallel/Ingress(gopogh) 0.58% (chart)
KVM_Linux (4 failed) TestGvisorAddon(gopogh) 0.00% (chart)
KVM_Linux (4 failed) TestNoKubernetes/serial/Start(gopogh) 0.00% (chart)
KVM_Linux (4 failed) TestFunctional/serial/ComponentHealth(gopogh) 0.58% (chart)
KVM_Linux (4 failed) TestNoKubernetes/serial/StartNoArgs(gopogh) 5.29% (chart)
Docker_Linux_containerd_arm64 (2 failed) TestStartStop/group/old-k8s-version/serial/SecondStart(gopogh) 45.98% (chart)

Besides the following environments also have failed tests:

To see the flake rates of all tests by environment, click here.

pathInIso string
destPath string
}{
{"/boot/bzimage", "bzimage"},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On arm64, vfkit requires an uncompressed kernel, I don't know what format bzimage is in.
Also be aware that there were some issues with direct kernel boot both on amd64 and arm64 on macOS 12 crc-org/vfkit#11

If you can require macOS 13+, I'd recommend using uefi boot if possible, no need to extract kernel/initrd/...

Copy link
Collaborator Author

@afbjorklund afbjorklund Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason it worked fine with boot2docker.iso, but failed to boot with minikube.iso

It might be the extra copy of the kernel, so might require some ISO cleanup before it works?

i.e. there is a BR2_LINUX_KERNEL_INSTALL_TARGET=y that was copied from the BIOS support

Dropping support for macOS 12 is not so much of an issue, I think? Had to upgrade anyway

Copy link
Collaborator Author

@afbjorklund afbjorklund Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kernel was supposed to be compressed with lz4 (at least so I thought), but seems uncompressed?

BR2_LINUX_KERNEL_LZ4=y

Could be some old bug with the aarch64 iso build perhaps, when it is copying the wrong file or something

Not sure what compression formats that Apple's EFI supports? Probably not lz4, but maybe zstd ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also be aware that there were some issues with direct kernel boot both on amd64 and arm64 on macOS 12 crc-org/vfkit#11

Minikube still uses kernel 5.10, so that should be OK. Perhaps going to upgrade to 5.15, but still (< 5.18)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for new code we can assume current macOS version as requirement. The only reason to run older macOS is old hardware that cannot be upgraded (6+ years old), and such hardware is typically not usable for running minikube with virtual machines.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The technical requirement is only macOS 11, but there's still the older drivers if you can't use macOS 13

pid := cmd.Process.Pid
if err := os.WriteFile(d.pidfilePath(), []byte(fmt.Sprintf("%v", pid)), 0600); err != nil {
return err
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another race which can happen is that vfkit can exit after cmd.Start() succeeds, for example if Apple's virtualization framework fails to start the VM and returns an error. If this happens, you'd have a pid file but no corresponding process.
I added this code in vfkit's test suite to catch this crc-org/vfkit@a38d84c
It probably would be useful to have a way to tell vfkit "do not exit by yourself, I'll explicitly stop/kill/.. you when I no longer need your process to be around"


// Make a boot2docker VM disk image.
func (d *Driver) generateDiskImage(size int) error {
log.Debugf("Creating %d MB hard disk image...", size)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the generated image will be size MiB, not MB.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't so important back then (but it was always MiB)

Hopefully this can be decoupled at some future point...

https://github.com/minikube-machine/machine/blob/main/libmachine/mcnutils/b2d.go#L492

I think it's only doing some qemu-img convert / truncate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g.

// ConvertMBToBytes converts MB to bytes
func ConvertMBToBytes(mbSize int) int64 {
        return int64(mbSize) * units.MiB
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would also be nice to avoid github.com/docker/go-units

@afbjorklund
Copy link
Collaborator Author

afbjorklund commented Aug 19, 2024

Would be great to add functional and integration tests for this in a follow up PR so we can find any bugs and accelerate this out of experimental

Added the standard "hack" integration script, not sure if there is anything more that needs to be done for testing?

@spowelljr

maybe hack/jenkins/minikube_set_pending.sh

@minikube-pr-bot

This comment has been minimized.

@minikube-pr-bot

This comment has been minimized.

@minikube-pr-bot
Copy link

Here are the number of top 10 failed tests in each environments with lowest flake rate.

Environment Test Name Flake Rate
Docker_Linux_containerd_arm64 (2 failed) TestStartStop/group/old-k8s-version/serial/SecondStart(gopogh) 46.55% (chart)
Docker_Linux_crio_arm64 (3 failed) TestMultiControlPlane/serial/RestartCluster(gopogh) 15.52% (chart)

Besides the following environments also have failed tests:

To see the flake rates of all tests by environment, click here.

@medyagh
Copy link
Member

medyagh commented Aug 20, 2024

@afbjorklund #19468 is merged and could be pull into this PR

@minikube-pr-bot

This comment has been minimized.

## Overview

[VFKit](https://github.com/crc-org/vfkit) is an open-source program for macOS virtualization, optimized for lightweight virtual machines and container deployment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To stay in line with the rest of the driver pages would be good to have a Usage section. I tried to do a suggestion comment but the closing backticks prevent it.

### Usage

```shell
minikube start --driver qemu --network socket_vmnet

site/content/en/docs/drivers/vfkit.md Outdated Show resolved Hide resolved
@spowelljr
Copy link
Member

Would be great to add functional and integration tests for this in a follow up PR so we can find any bugs and accelerate this out of experimental

Added the standard "hack" integration script, not sure if there is anything more that needs to be done for testing?

@spowelljr

maybe hack/jenkins/minikube_set_pending.sh

Yeah, what you have should be good for integration, might be good to add functional tests as well, but could be done in a follow up PR.

Co-authored-by: Steven Powell <44844360+spowelljr@users.noreply.github.com>
Copy link
Member

@medyagh medyagh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me ! this is gonna be exciting new feature for upcoming release, thank you for this contribution.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: afbjorklund, medyagh

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 27, 2024
@minikube-pr-bot
Copy link

kvm2 driver with docker runtime

+----------------+----------+---------------------+
|    COMMAND     | MINIKUBE | MINIKUBE (PR 19423) |
+----------------+----------+---------------------+
| minikube start | 52.0s    | 51.8s               |
| enable ingress | 16.2s    | 15.7s               |
+----------------+----------+---------------------+

Times for minikube (PR 19423) start: 51.6s 53.9s 49.8s 51.7s 52.1s
Times for minikube start: 50.7s 50.8s 55.0s 53.7s 49.9s

Times for minikube ingress: 16.1s 15.5s 16.0s 15.0s 18.5s
Times for minikube (PR 19423) ingress: 15.5s 15.5s 16.1s 16.5s 15.1s

docker driver with docker runtime

+----------------+----------+---------------------+
|    COMMAND     | MINIKUBE | MINIKUBE (PR 19423) |
+----------------+----------+---------------------+
| minikube start | 22.3s    | 22.8s               |
| enable ingress | 12.3s    | 12.0s               |
+----------------+----------+---------------------+

Times for minikube (PR 19423) start: 20.7s 24.1s 24.2s 24.0s 20.9s
Times for minikube start: 21.7s 20.6s 23.9s 24.4s 21.2s

Times for minikube (PR 19423) ingress: 12.8s 10.3s 13.3s 12.8s 10.8s
Times for minikube ingress: 12.8s 12.8s 10.8s 12.8s 12.3s

docker driver with containerd runtime

+----------------+----------+---------------------+
|    COMMAND     | MINIKUBE | MINIKUBE (PR 19423) |
+----------------+----------+---------------------+
| minikube start | 21.8s    | 21.1s               |
| enable ingress | 39.0s    | 39.1s               |
+----------------+----------+---------------------+

Times for minikube start: 20.7s 20.6s 22.3s 22.8s 22.5s
Times for minikube (PR 19423) start: 19.7s 22.7s 20.1s 22.7s 20.0s

Times for minikube ingress: 38.8s 39.8s 38.8s 38.8s 38.9s
Times for minikube (PR 19423) ingress: 39.3s 38.8s 39.8s 38.8s 38.8s

@medyagh medyagh merged commit 5295883 into kubernetes:master Sep 3, 2024
28 of 41 checks passed
@nirs
Copy link
Contributor

nirs commented Sep 3, 2024

This driver works beautifully for running disconnected clusters. The problem is how to make it work with shared network like socket_vmnet, or maybe getting minikube or vfkit a apple.netwroking entitlement, like UTM has, so it can use bridged network.

I'm not sure if UTM built locally can use bridged network, or only UTM from Apple app store. But it would be awesome if we can get minikube or vfkit in the app store so it can use good networking - without adding any code.

@afbjorklund afbjorklund added the co/vfkit VFkit related issues label Sep 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. co/vfkit VFkit related issues ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Minikube with driver "new Virtualization Framework" on Apple M1
7 participants