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.hfailed" 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
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)
Share your project folder (edit on the Mac, build in the VM):
# back on the Mac:
multipass mount "$PWD" ebpf-dev:/home/ubuntu/work
Option B — Lima (auto-mounts your code)
brew install lima
limactl start --name=ebpf-dev template://ubuntu-lts
limactl shell ebpf-dev
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
Run it:
chmod +x setup-ebpf-mac.sh
./setup-ebpf-mac.sh # or: ./setup-ebpf-mac.sh lima
(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)); }'
Open another shell, run ls — it shows up instantly. That's eBPF running in your VM's kernel.

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
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
- The setup script +
hello-ebpfexample: github.com/hyperredstart/hello-ebpf - Multipass docs: multipass.run
- Lima: lima-vm.io
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)