topics: k8s (post)

M1 K8s The Hard Way

What

Lima provides a ‘sort of unofficial “macOS subsystem for Linux”’ which is designed to provide CLI access to (Contai)nerdctl on a Mac. It does this by leveraging QEMU with HVF accelerator enabling running Arm on Intel and Intel on Arm. The tool has a shorthand that references a ‘default’ vm where:

lima nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine

translates into something like

limactl shell default nerdctl run -d --name nginx -p 127.0.0.1:8080:80 nginx:alpine

Having spent a little time evaluating Lima as a replacement for my own container usage on Mac I starting looking into running multiple VMs and customising the network configurations. It turns out that with autoconf and automake installed on a vanilla M1 Monterey Mac, vde_vmnet can be installed providing “vmnet.framework support for rootless QEMU”. This translates into (a slightly manual) ability to bring VMs up with specific network interfaces and specific DHCP issued static IP addresses.

The instructions at the vde_vmnet repository describe how to build the two required components, vde_vmnet and vde_switch.

Install vde_switch:

git clone https://github.com/virtualsquare/vde-2.git
cd vde-2
autoreconf -fis
./configure --prefix=/opt/vde
make
sudo make install

Install vde_vmnet:

git clone https://github.com/lima-vm/vde_vmnet
cd vde_vmnet
make PREFIX=/opt/vde
sudo make PREFIX=/opt/vde install

The configuration for the networks can be found in e.g. ~/.lima/_config/networks.yaml

Support for managing network daemons automatically is backed in to Lima as of v0.7.0. To do this a networks configuration is added to the VM lima.yaml configuration file:

networks:
  # Lima can manage daemons for networks defined in $LIMA_HOME/_config/networks.yaml
  # automatically. Both vde_switch and vde_vmnet binaries must be installed into
  # secure locations only alterable by the "root" user.
  - lima: shared

Static IP address can be configured by specifying a MAC address for each VM and configuring /etc/bootptab with Host / MAC / IP mappings, for example:

# bootptab
%%
# hostname      hwtype  hwaddr              ipaddr          bootfile
tmp-vm01        1       de:ad:be:ef:00:01   192.168.105.100

And in a VMs configuration:

networks:
  - lima: shared
    macAddress: "de:ad:be:ef:00:01"

With a change to bootptab the DHCP deamon needs to be reloaded:

sudo /bin/launchctl unload -w /System/Library/LaunchDaemons/bootps.plist
sudo /bin/launchctl load -w /System/Library/LaunchDaemons/bootps.plist

For Lima to be able to control the networking daemons it (currently) requires sudo access. This can be added via:

limactl sudoers | sudo tee /etc/sudoers.d/lima

Why

With an ability to spin up small VMs with custom network configuration running almost seamlessly on an M1 macbook, I reached for a problem to match the solution. Having not run through Kubernetes The Hard Way for quite some time it seemed I had found the problem.

Can I run an ARM based multi-VM hand-crafted Kubernetes cluster on an M1 powered macbook - easily ?

There are multiple ways to get Kubernetes up and running on an M1 Macbook with substantially less effort required than the approach taken in this blog post. Lima itself provides a config file, Minikube is still winning and some new entries to the scene look interesting like Rancher Desktop, which uses Lima under the hood.

How

To set up the VMs for an Arm based Kubernetes cluster on an M1 Mac I used the following network configuration:

paths:
  vdeSwitch: /opt/vde/bin/vde_switch
  vdeVMNet: /opt/vde/bin/vde_vmnet
  varRun: /private/var/run/lima
  sudoers: /private/etc/sudoers.d/lima

group: staff

networks:
  shared:
    mode: shared
    gateway: 10.1.0.1
    dhcpEnd: 10.1.254.254
    netmask: 255.255.0.0

Lima configuration allows specifying a remote iso (which it can cache locally), for example: https://github.com/lima-vm/alpine-lima/releases/download/v0.2.2/alpine-lima-std-3.14.3-aarch64.iso

With the ability to orchestrate VMs and network configuration locally with Lima, we can run through installing a setting up a cluster using resources such as Kubernetes The Hard Way.