Building a Kubernetes Cluster in VirtualBox with Ubuntu

Building a Kubernetes Cluster in VirtualBox

As there is lot of possible ways to launch a kubernetes like cloud, minikube or kubeadm in local machine, here we have picked kubeadm in VirtualBox and created a new VM with 2 CPUs and 2GB RAM. (2 CPUs for the master is important!). Before I turned on the machine, I created a host-only network called vboxnet0 with an IP address of

VirtualBox network configuration

Once you have launch the VM in virtualbox, you have to change the network setting from default NAT to host-only. Now let’s configure our host-only network, which will be used inside of VirtualBox environment. Open VirtualBox, go to File -> Host Network Manager. If there is nothing configured yet, add new Host Only network (if you already have something configured, you need to either change IP as in this tutorial or make note what IPs to use later). You can now disable DHCP inside of the settings and also set IPv4 address to

Follow our Kubernetes Series On Kubernetes


I have created ubuntu 16.04 VM using vagrant, with this vagrantfile. Then on this machine I also disabled swap (you may not need to do this for your setup). To disable swap immediately you can use swapoff, but you’ll also need to edit your /etc/fstab file to remove or comment out any swap entries. This is required by kubeadm during its “pre-flight checks”.

Next, I installed docker and cloned the VM — I did not do a link clone, I had issues with the system’s product uuid not changing (this is also required for Kube). I cloned the machine until I had 3 freshly configured Ubuntu boxes. The kubemaster box has 2 CPUs and 2GB RAM, the workers worker1 and worker2 have 1 GB RAM and 1 CPU. During some of my initial failures, kube-dns would crash in a loop, and I eventually saw that there were insufficient CPU resources available to schedule it.

For each of these machines, I then:

  • Set the hostname accordingly
  • Configured the IP address of the host-only network as a static IP
  • Rebooted and ensured I could ssh to any machine in the group from any machine.

To configure the hostname I modified /etc/hostname, and to set the IP address of the host-only adapter, I added the following to the bottom of the file /etc/network/interfaces :

# Host-only network
auto eth0
iface eth0 inet static

Your interface name may be different, so check with ip addr or ifconfig -a to see what your interface names are. Compare the MAC address you see in the OS with the MAC assigned in your VirtualBox host-only network configuration to make sure you’ve got the right one. In my case, eth0 is my host-only network and enp0s3 is my regular adapter that can see my host machine’s network and is configured for DHCP.

I configured my IP addresses and hostnames as follows:

  • master — kubemaster —
  • worker 1 — worker1–
  • worker 2 — worker2–

After these were all set, I took a snapshot of the master (because I’m accident prone and always prefer having a backup) and then ssh into kubemaster from my workstation. My real terminal has better copy/paste support than inside VirtualBox’s quirky console. Because Ubuntu doesn’t have an active root account, you’ll need to sudo most of your kubeadm commands. You can follow the Kubernetes documentation for installing kubeadm on Ubuntu.

On the master, you need to run kubeadm init. Note that we absolutely have to specify the advertise address of the API server because we have multiple network adapters on the host and we need it to advertise on the host-only network IP. Also, you need to go look now at the apply commands for your CNI plugin of choice, as some of them require you to specify parameters to kubeadm, like the pod CIDR block:

# kubeadm init --apiserver-advertise-address= --pod-network-cidr=

I knew ahead of time that I was going to run Calico, so I knew that I needed to set the pod network CIDR. My lesson learned here was pick your network plugin before you run kubeadm init. Otherwise, you’ll have to do what I did and go back to a pre-kube snapshot and re-install.

Everything we’ve done up to this point means that my nodes are going to have IP addresses in the range–22, and the pods will be allocated IP addresses out of the CIDR Understanding the interplay between node IPs and pod IPs took me a while when first learning about Kubernetes.

After kubeadm finishes, it should tell you everything is good and then it’ll give you a command for kubeadm join with a token. DO NOT LOSE THIS COMMAND. I stored this in my user’s home directory on the master node as a text file. Since we’re not in production and we’re only building a lab system, this is okay.

Now ssh into worker1 and install kubeadm. Run the join command you were given as a sudo command. This command will be surprisingly fast. Within just a few seconds, you should be able to run kubectl get nodes on the master and see that you now have a master and a worker. You can refer following link for detailed steps.

How to setup Kubernetes on Centos & RedHat

Repeat the process on worker 2. At this point, you should notice that kube-dns is in a Pending state and hasn’t been scheduled (check this with kubectl get pods –all-namespaces). This is because we have no network plugin. How can we successfully discover and communicate with nodes if we have no network plugin? This is because the node network for the cluster is completely independent from the pod network. The node network is already up and running via our kubeadm commands. I chose Calico for my network plugin:

# kubectl apply -f

After a few seconds, you should start to see that kube-dns is being scheduled (it’ll be in ContainerScheduling state). A few more seconds and it’ll be running. Once it’s running, you should be able to see all your pods like this:

# kubectl get pods --all-namespaces
NAMESPACE     NAME                                       READY     STATUS    RESTARTS   AGE
kube-system   calico-etcd-c2m6m                          1/1       Running   1          3d
kube-system   calico-kube-controllers-685f8bc7fb-nbvbs   1/1       Running   1          3d
kube-system   calico-node-gdrnz                          2/2       Running   0          3d
kube-system   calico-node-s4x8z                          2/2       Running   1          3d
kube-system   calico-node-v7b9h                          2/2       Running   2          3d
kube-system   etcd-kubemaster                            1/1       Running   1          3d
kube-system   kube-apiserver-kubemaster                  1/1       Running   1          3d
kube-system   kube-controller-manager-kubemaster         1/1       Running   1          3d
kube-system   kube-dns-545bc4bfd4-cbxbw                  3/3       Running   0          3d
kube-system   kube-proxy-2nxvq                           1/1       Running   0          3d
kube-system   kube-proxy-8dmzc                           1/1       Running   0          3d
kube-system   kube-proxy-zz259                           1/1       Running   1          3d
kube-system   kube-scheduler-kubemaster                  1/1       Running   1          3d

And you should have a nice set of VMs running in Virtualbox