This artice describes how you can create a kubernetes custer using Vagrant, Hyper-V and Packer.

Update (11-05-2020)

I have updated the scripts to use contianerd in favor of docker. Don’t worry using docker is still possible. In /packer/ubuntu-18.04-amd64.json replace woth


I found myself in the need of having a kubernetes test cluster. Instead of using minikube or enabling Kubernetes on Docker Desktop. I thought I could learn from setting up a cluster from scratch. This also allows me to easiliy simulate network failures or have nodes go down.


The only reason I choose Hyper-V is that my machine runs Windows 10 Pro, which includes Hyper-V. Please note that both Packer an Vagrant support many other platforms.

Please make sure all prerequisites are installed.

Prepare a Virtual Machine image

First we are going to use packer to create a Hyper-V base image. The image will be used to build the cluster. For this I took the Ubuntu packer file from bento as an example. On top of that I’ve added docker installation and installation of kubernetes tools.

Please download or clone and navigate to the packer directory in an elevated command promt. The current user needs to be in “Hyper-V Administrators” or “Administrators” to communicate to Hyper-V.

Optionally start the Hyper-V Manager to see what packer does. Now run packer build ubuntu-18.04-amd64.json

This will take some while and packer might ask for permission to run a http server to serve the pre-seed config file.

What will happen is the following:

  1. Ubuntu iso is downloaded
  2. VM is created
  3. Ubuntu installation starts (using a preseed config)
  4. When installation is complete Ubuntu will reboot with ssh enabled
  5. Installation continues using ssh
  6. VM shuts down
  7. Imagefile is built

Here’s a video as reference:

When the image is completed, add it to vagrant using: vagrant box add builds\ --name ubuntu-k8s-docker

One time preparations

  • Install vagrant-reload: vagrant plugin install vagrant-reload

  • Creat a new network swith in Hyper-V for cluster to run on. Please see my previous blog for that. The ip ranges match with the ip addresses in Vagrantfile.

Spin up a cluster

Navigate to the directory in which was cloned.

In Vagrantfile change the number of worker nodes to the desired amount. Look for NodeCount. The default is 2.

Then, using elevated command promt, execute vagrant up

Unfortunately Vagrant will ask to which swwtch a machine must be connected initially. Please be sure to select the Default Switch! The Vagrant script will reconnect to the static ip switch after netwroking is properly configured.

Apart from the need to select a switch for each machine no further actions are required.

After the process is complete you can use ssh (username: vagrant, password: vagrant) to login to the master node on Type kubectl get nodes to see if all nodes are ready.

vagrant@k8smaster:~$ kubectl get nodes
k8smaster   Ready      master   11m     v1.18.0
kworker1    Ready      <none>   6m59s   v1.18.0
kworker2    Ready      <none>   3m56s   v1.18.0

Delete the cluster

Deleting is easy. Just type vagrant destroy

C:\src\vagrant-kubernetes>vagrant destroy
    kworker2: Are you sure you want to destroy the 'kworker2' VM? [y/N] y
==> kworker2: Running cleanup tasks for 'reload' provisioner...
==> kworker2: Stopping the machine...
==> kworker2: Deleting the machine...
    kworker1: Are you sure you want to destroy the 'kworker1' VM? [y/N] y
==> kworker1: Running cleanup tasks for 'reload' provisioner...
==> kworker1: Stopping the machine...
==> kworker1: Deleting the machine...
    k8smaster: Are you sure you want to destroy the 'k8smaster' VM? [y/N] y
==> k8smaster: Running cleanup tasks for 'reload' provisioner...
==> k8smaster: Stopping the machine...
==> k8smaster: Deleting the machine...


Final thoughts

I can now easily setup a multi node kubernetes cluster for some proper testing. Additionally, setting this up really helped me learn more about kubernetes.

There is some improvements to be made though:

  • Setup of the masternode takes quite some time because kubernetes images are downloaded. There is possibly some speed to gain to download these already when building the Hyper-V image
  • Maybe replace docker by containerd Done, see update at the start of this article!
  • Adding an Ingress Controller or some other usefull stuff to the initial cluster

Stuff to ponder about for the next blog…