Vagrant and MicroK8s: A Tested Linux Development VM
Posted on July 14, 2020
Updated
Vagrant and MicroK8s can provide a repeatable Linux development VM when the host, provider and guest are compatible. This walkthrough was tested on an amd64 Ubuntu 24.04 host with KVM/libvirt, Vagrant 2.4.9 and vagrant-libvirt 0.12.2. It replaces the original Ubuntu 20.04/VirtualBox assumptions.
Prepare a compatible Linux host
Install Vagrant from HashiCorp’s supported distribution, KVM/libvirt and the provider’s build dependencies. Confirm that hardware virtualization is available and libvirt works. The test used a disposable EC2 host with nested virtualization; a normal Linux workstation with KVM can provide the same provider boundary. macOS, Windows and VirtualBox were not validated by this run.
vagrant --version
vagrant plugin list
test -c /dev/kvm
virsh -c qemu:///system list --all
# Install the tested provider when it is not already present:
vagrant plugin install vagrant-libvirt --plugin-version 0.12.2Pin the guest and MicroK8s channel
Save this as Vagrantfile in an empty working directory. The Bento image is a third-party Ubuntu box, not a Canonical-published Vagrant image. Verify its publisher, provider, architecture and checksum through your normal image review. The tested box version contains a libvirt amd64 provider; a newer version may expose a different provider set.
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-24.04"
config.vm.box_version = "202508.03.0"
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.provider :libvirt do |vm|
vm.memory = 4096
vm.cpus = 2
vm.cpu_mode = "host-passthrough"
end
config.vm.provision "shell", inline: <<-SHELL
set -eux
systemctl start snapd
snap wait system seed.loaded
for attempt in 1 2 3; do
snap install microk8s --classic --channel=1.36/stable && break
sleep 10
done
snap list microk8s
timeout 600 microk8s status --wait-ready
microk8s kubectl get nodes
microk8s kubectl get namespaces
SHELL
endThe live run resolved the channel to MicroK8s v1.36.2. Do not assume upstream Kubernetes and MicroK8s tracks publish simultaneously: the proposed 1.37 stable track was unavailable. On the first boot Snap also needed initialization/retry handling. Review the actual Snap channels before an upgrade.
Boot and verify an actual workload
vagrant validate
vagrant up --provider=libvirt
vagrant ssh -c 'sudo microk8s kubectl create deployment sample --image=nginx:1.30-alpine'
vagrant ssh -c 'sudo microk8s kubectl rollout status deployment/sample --timeout=180s'
vagrant ssh -c 'sudo microk8s kubectl get nodes -o wide'Use explicit MicroK8s commands rather than assuming interactive aliases exist. The workload rollout passed in the tested guest. A single VM remains a development environment; it does not establish production availability, storage recovery or parity with a managed Kubernetes service.
Destroy the guest and verify removal
vagrant destroy -f
vagrant status
virsh -c qemu:///system list --allConfirm the VM is absent. Remove the project-specific box/cache if it was created only for the test. The live run destroyed the guest, then deleted its enclosing AWS host and disk. For a container-based local alternative, see the kind topology-spread lab.