Install Kubernetes cluster in Virtual Machines the easy way

Mohammed Hewedy
5 min readMay 26, 2020

--

In this post, we will see how to install a Kubernetes v1.18 cluster composed of 2 VMs running Ubuntu 20.04 in few minutes.

We will use provisioning scripts to install and configure the master and the worker nodes.

The provision script changes hostname to the IP of the machine (to make sure it is unique to match k8s requirements) and set the swap off then fix the IP address of the machine.

Then it installs the correct version of docker that matches Kubernetes 1.18 and install it as a service, then install version 1.18 fromkubeadmin, kubectl and kubelet.

And in case of the master node, it initializes the kubeadm and installs flannel network.

We will go install Kubernetes cluster in 4 steps:

  1. Create the provision script for the master node
  2. Create and Provision the master node
  3. Create the Provision script for the worker node
  4. Create and Provision the worker node
  5. Testing the cluster

We will use vermin so we can complete the cluster installation in minutes.

Vermin is a smart, simple and powerful command line tool for Linux, Windows and macOS. It’s designed for developers who want a fresh VM environment with a single command. It uses VirtualBox to run the VM. Vermin will fetch images in your behave.

To follow this tutorial, you will have to install vermin.

First, you need to install Virtualbox, then for Linux and macOS, type in a terminal window:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/mhewedy/vermin/master/install.sh)"

And for Windows, Open a PowerShell terminal as an administrator then type:

iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/mhewedy/vermin/master/install.ps1'))

vermin is a single binary, you can still download it yourself and do a manual installation or even build it from source, see Github page for more information.

Step 1: Create the provision script for the master node

let’s create the provision script that will do the setup for the master node. Let’s name the file master.sh.

You can find the script on GitHub as well.

Step 2: Create and Provision the master node

Now open a new terminal and run the following command, note the Kubernetes master need 2 CPUs and 2048 MB memory to run correctly:

$ vermin create ubuntu/focal64 --cpus 2 --mem 2048 /path/to/master.sh✔ Creating vm_01 from image ubuntu/focal64
✔ Setting bridged network adapter
✔ Starting vm_01
✔ Establishing connection
Provisioning vm_01
++ docker_ubuntu_release=bionic
++ k8s_version=1.18.0
......
......
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.100.102:6443 --token <token...> \
--discovery-token-ca-cert-hash sha256:<hash....>
......

VM is ready, to connect to it use:
$ vermin ssh vm_01

Now the master is installed, configure, and ready. It took about 4 minutes in my case to finish the setup.

You need to copy the command printed from the output of the vermin create command above (started by kubeadmin join) to use it from the worker nodes to join the cluster as shown below:

The kubeadm join command

We have the master node installed and ready, let create and provision the worker node.

Step 3: Create the Provision script for the worker node

let’s create the provision script that will do the setup for the worker node. Let’s name the file worker.sh.

You can find the script on GitHub as well.

Step 4: Create and Provision the worker node

Now open a new terminal and run the following command, note the Kubernetes worker need 1 CPUs and 2048 MB memory to run correctly:

$ vermin create ubuntu/focal64 --cpus 1 --mem 2048 /path/to/worker.sh✔ Creating vm_02 from image ubuntu/focal64
✔ Setting bridged network adapter
✔ Starting vm_02
✔ Establishing connection
Provisioning vm_02
++ docker_ubuntu_release=bionic
++ k8s_version=1.18.0
......
......

VM is ready, to connect to it use:
$ vermin ssh vm_02

Now the worker is installed, configured, and ready. It took about 3 minutes in my case to finish the setup.

Now let’s make the worker join the cluster. (note vm_01 is the master and vm_02 is the worker)

Let's execute the join command against the worker node:

$ vermin exec vm_02 -- sudo  kubeadm join 192.168.100.102:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

You can repeat steps 3 and 4 above as many times as you would to create worker nodes.

🚀🚀🚀

Testing the cluster

The cluster setup has been completed and ready to be used. let’s login to the master node and test the cluster:

$ vermin ssh vm_01

Now we inside the master node, let’s check the available nodes: (the role <none> means worker nodes)

vermin@192.168.100.102:~ $ kubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.100.102 Ready master 16m v1.18.0
192.168.100.103 Ready <none> 5m26s v1.18.0

Let’s create a pod and test it is working:

vermin@192.168.100.102:~ $ kubectl run nginx --image=nginx
pod/nginx created
vermin@192.168.100.102:~ $ kubectl expose pod nginx --port=80
service/nginx exposed

Let’s check it is running by creating another pod and try to curl the Nginx service.

vermin@192.168.100.102:~ $ kubectl run curlpod --image radial/busyboxplus:curl --restart=Never -it --rm -- curl nginx

This post installs flannel for Networking, which does not support Network Policies.
To work with Network Policies you need to install Calico along with flannel (a.ka. Canal ).
More information can be found here: https://docs.projectcalico.org/getting-started/kubernetes/flannel/flannel

Bouns

vermin allow you to tag VMs and filter by tag, name, and image when listing the VMs.

This will be useful when you have multiple VMs, so to list VMs we will get output similar to:

$ vermin ps
VM NAME IMAGE CPUS MEM DISK TAGS
vm_01 ubuntu/focal64 2 2048 5.7GB
vm_02 ubuntu/focal64 1 2048 3.8GB
vm_03 ubuntu/focal64 1 1024 5.2GB

Now vm_01 and vm_02 are the Kubernetes master and worker, and vm_03 for another purpose. Now we can tag vm_01 and vm_03 and list only such VMs:

$ vermin tag vm_01 k8s-master
$ vermin tag vm_02 k8s-worker

Then when listing, pass a filter where tags field contains k8s

$ vermin ps -f tags=k8s
VM NAME IMAGE CPUS MEM DISK TAGS
vm_01 ubuntu/focal64 2 2048 5.7GB k8s-master
vm_02 ubuntu/focal64 1 2048 3.8GB k8s-worker

The filter function follows docker filter in which you can filter with multiple fields and the filter will be matched contains , and the result should match all filters supplied.

--

--

Mohammed Hewedy
Mohammed Hewedy

Responses (1)