DEV Community

Cover image for eBPF on a Mac: A 5-Minute Linux VM with Multipass or Lima
Corey Lai
Corey Lai

Posted on

eBPF on a Mac: A 5-Minute Linux VM with Multipass or Lima

Foreword: this series started in a packed room at KubeSummit 2025

In October 2025 I gave a talk at KubeSummit 2025 (hosted by iThome) — "Exploring the Core of eBPF: Using eBPF and Kubernetes to Modernize Monitoring for Traditional-Industry ERP Systems." The room was full, and afterward the most common question wasn't about theory. It was some version of:

"This is great — but how do I actually run any of this myself?"

That question is what this series is for: turning that talk into small, runnable guides you can follow on your own machine. And it has to start with the wall every Mac developer hits first — eBPF doesn't run on macOS. So before the kernel tracing and the benchmarks, here's step zero: getting a Linux environment where eBPF actually works.

TL;DR: eBPF runs in the Linux kernel, so it can't run natively on macOS. Run a real Ubuntu VM with Multipass (simplest) or Lima (auto-mounts your code) — both give you the BTF that modern CO-RE eBPF needs. Don't use Docker Desktop for this: its LinuxKit kernel usually ships without BTF. A copy-paste setup script is at the end.

The problem: your Mac isn't Linux (and eBPF only speaks Linux)

eBPF is a Linux kernel technology. macOS runs the XNU kernel — there is no eBPF there. So every "I'll learn eBPF" attempt on a Mac hits the same wall on day one.

The good news: running Linux on a Mac for eBPF is a solved, 5-minute problem — if you pick the right tool. The trap is reaching for Docker Desktop (more on that below).

What you'll learn

  • Why you need a Linux VM (and why Docker Desktop is the wrong one for eBPF)
  • Multipass vs Lima — which to pick
  • A one-command script that gives you a working, verified eBPF dev VM

The one rule that saves you hours: you need BTF

Modern eBPF (CO-RE — compile once, run everywhere) reads the kernel's BTF (/sys/kernel/btf/vmlinux) to stay portable across kernel versions. If your VM's kernel was built without BTF, the very first step — generating vmlinux.h — fails.

  • Ubuntu 22.04 / 24.04 VMs ship with BTF enabled. ✅
  • Docker Desktop's LinuxKit kernel often does not. ❌ — this is why "I tried eBPF in a container and vmlinux.h failed" is so common.

So: a real Ubuntu VM, not a container.

Multipass vs Lima — pick one

Multipass Lima
Install brew install --cask multipass brew install lima
Vibe dead simple, "just give me a VM" lightweight, dev-friendly
Your code → VM multipass mount / transfer auto-mounts your home dir
Best for fastest start edit-on-Mac, build-in-VM loop

Both work great and both give you BTF. New to this? Use Multipass. Want your files to "just be there" in the VM? Use Lima.

Option A — Multipass (quickest)

brew install --cask multipass
multipass launch 24.04 --name ebpf-dev --cpus 2 --memory 4G --disk 20G
multipass shell ebpf-dev
Enter fullscreen mode Exit fullscreen mode

Inside the VM:

sudo apt update
sudo apt install -y clang llvm libbpf-dev libelf-dev zlib1g-dev \
                    make bpftrace git linux-tools-common linux-tools-$(uname -r)
Enter fullscreen mode Exit fullscreen mode

Share your project folder (edit on the Mac, build in the VM):

# back on the Mac:
multipass mount "$PWD" ebpf-dev:/home/ubuntu/work
Enter fullscreen mode Exit fullscreen mode

Option B — Lima (auto-mounts your code)

brew install lima
limactl start --name=ebpf-dev template://ubuntu-lts
limactl shell ebpf-dev
Enter fullscreen mode Exit fullscreen mode

Lima mounts your home directory at the same path inside the VM, so you can cd straight to your project — no copying. Install the same toolchain as above.

Or just run one script

Both options, wrapped up with a BTF check and an eBPF smoke test:

#!/usr/bin/env bash
# setup-ebpf-mac.sh — ./setup-ebpf-mac.sh [multipass|lima]   (default: multipass)
set -euo pipefail
PROVIDER="${1:-multipass}"; VM_NAME="ebpf-dev"

read -r -d '' VM_SETUP <<'EOF' || true
set -e
echo "[VM] kernel: $(uname -r)  arch: $(uname -m)"
[ -r /sys/kernel/btf/vmlinux ] && echo "[VM] BTF: OK" || { echo "[VM] BTF: MISSING"; exit 1; }
sudo apt-get update -y
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \
  clang llvm libbpf-dev libelf-dev zlib1g-dev make bpftrace git linux-tools-common
sudo apt-get install -y "linux-tools-$(uname -r)" || sudo apt-get install -y linux-tools-generic || true
echo "[VM] smoke test (3s): tracing execve()"
sudo timeout 3 bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%-6d %-16s %s\n", pid, comm, str(args->filename)); }' || true
echo "[VM] ✅ ready"
EOF

if [ "$PROVIDER" = multipass ]; then
  command -v multipass >/dev/null || brew install --cask multipass
  multipass info "$VM_NAME" >/dev/null 2>&1 || \
    multipass launch 24.04 --name "$VM_NAME" --cpus 2 --memory 4G --disk 20G
  multipass exec "$VM_NAME" -- bash -c "$VM_SETUP"
  echo "Enter: multipass shell $VM_NAME   |   Share code: multipass mount \"$PWD\" $VM_NAME:/home/ubuntu/work"
elif [ "$PROVIDER" = lima ]; then
  command -v limactl >/dev/null || brew install lima
  limactl list --format '{{.Name}}' 2>/dev/null | grep -qx "$VM_NAME" || \
    limactl start --name="$VM_NAME" --tty=false template://ubuntu-lts
  limactl shell "$VM_NAME" bash -c "$VM_SETUP"
  echo "Enter: limactl shell $VM_NAME   (Lima auto-mounts your home dir)"
else
  echo "use: multipass | lima"; exit 1
fi
Enter fullscreen mode Exit fullscreen mode

Run it:

chmod +x setup-ebpf-mac.sh
./setup-ebpf-mac.sh            # or: ./setup-ebpf-mac.sh lima
Enter fullscreen mode Exit fullscreen mode

(The full version, with fallbacks and friendlier output, is in the repo linked below.)

Verify it actually works

Inside the VM:

# 1) BTF present? (CO-RE needs this)
ls -l /sys/kernel/btf/vmlinux

# 2) eBPF works? trace every program launch, live:
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve {
    printf("%-6d %-16s %s\n", pid, comm, str(args->filename)); }'
Enter fullscreen mode Exit fullscreen mode

Open another shell, run ls — it shows up instantly. That's eBPF running in your VM's kernel.

bpftrace tracing execve() live inside the Lima VM — running  raw `ls` endraw  in another shell shows up instantly
Real output: bpftrace attached to the execve tracepoint; ls from another shell appears immediately.

Then build the real C + libbpf example from this series:

cd hello-ebpf
make
sudo ./hello
Enter fullscreen mode Exit fullscreen mode

Takeaways

  • eBPF is Linux-only — on a Mac you run it in a Linux VM, not a container.
  • You need BTF. Ubuntu 22.04/24.04 VMs have it; Docker Desktop usually doesn't.
  • Multipass = fastest, Lima = best dev loop. Either gets you running in ~5 minutes; one script does it all.

Resources


Part of a series on eBPF for traditional-industry / cloud-native systems. With the VM ready, the next post traces real syscalls with C + libbpf.

On a Mac and stuck setting up eBPF? Tell me where it broke — I'll help.

Top comments (0)