A step-by-step guide to setup Kubernetes cluster in VirtualBox Ubuntu 20.04 image

Just for learning to set up Kubernetes

Tan Chun Wei
Level Up Coding

--

1) Ubuntu image preparation

Download the image from Ubuntu
In this example, I am using ubuntu-20.04.4-live-server-amd64.iso

1.1) Setup Ubuntu image in Oracle VirtualBox
Requirement used in this example:
- RAM: 8Gb
- CPU: 2
- The rest as default

Network settings:
Adapter 1: Create a NAT Network, so that the k8s nodes are able to communicate within the virtual machine (VM) through this network.

  • To create a NAT Network, go to File -> Preferences -> Network
  • To select the network, right-click VM-> Settings -> Network

1.2) Installing Ubuntu Image

First choosing the iso image downloaded previously.
To select the disk, right-click -> Settings -> Storage -> Optical Disk Selection

Follow through the installation steps (stick with default settings) until the Profile Setup steps.
For your first k8s node, it should be the control plane node, so name it as follows:
- Your name: k8scp
- Your server’s name: k8scp
- Pick a username: k8s
- Choose a password: <your own password>
- Confirm your password: <your own password>

Next, until SSH Setup steps, choose Install OpenSSH server if you need to access your node via SSH.

Voila, the Ubuntu installation is complete.

2) Install Kubernetes in Ubuntu

2.1) Tools installation

We will install tools such as Vim, which we will use later when setting up the Kubernetes.

sudo -i
apt-get update && apt-get upgrade -y
apt-get install -y vim

2.2) Container runtime interface installation

Kubernetes is a platform for container orchestration and CRI is a Kubernetes API that interacts with different container runtimes. So, we will need to install a container runtime before installing Kubernetes.

This example uses CRI-O however we can also install other container runtimes such as Docker that uses containerd.

modprobe overlay
modprobe br_netfilter
vim /etc/sysctl.d/k8s.conf
-> Add the following content into k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
sysctl --system
export OS=xUbuntu_20.04
export VER=1.22
export WEBSITE=http://download.opensuse.org
echo "deb $WEBSITE/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VER/$OS/ /" | tee -a /etc/apt/sources.list.d/cri-0.listcurl -L $WEBSITE/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VER/$OS/Release.key | apt-key add -echo "deb $WEBSITE/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" | tee -a /etc/apt/sources.list.d/libcontainers.listcurl -L $WEBSITE/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -apt-get update
apt-get install -y cri-o cri-o-runc
systemctl daemon-reload
systemctl enable crio
systemctl start crio
systemctl status crio

2.3) Kubernetes installation

You will require kubeadm, kubeletand kubectl when installing Kubernetes cluster nodes. kubeadm is a tool that we will be using to init control plane node and join worker node. kubelet is a primary node agent that runs each node. kubectl is a command line tool that runs commands against the clusters.

vim /etc/apt/sources.list.d/kubernetes.list
-> Add the following content into kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -apt-get updateapt-get install -y kubeadm=1.22.1-00 kubelet=1.22.1-00 kubectl=1.22.1-00apt-mark hold kubelet kubeadm kubectl

2.4) Setup network

Setup the network so it will be easier to use the hostname rather than the IP address later.

ip addr show
-> You will see output with 10.130.0.x
that will be the NAT Network IpAddress
vim /etc/hosts
-> Add the following content
10.130.0.5 k8scp

2.5) Create control plane node

Running kubeadm init will create a control plane node

kubeadm init --upload-certs | tee kubeadm-init.out

2.6) Setup Kubernetes config

We are required to set up a Kube config to access the Kubernetes cluster. For this example, we are setting up Kube config with cluster-admin privileges.

# Exit from the root account
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

2.7) Setup Container Network Interface

CNI plugin is required to implement the Kubernetes network model. For this example, we are using Calico.

wget https://docs.projectcalico.org/manifests/calico.yaml
kubectl apply -f calico.yaml

2.8) Utilizing control plane node

This is an optional step. For practicing purposes in this example, we will utilize the control plane by removing the taint NoSchedule.

kubectl describe node | grep -i taint
-> Default control plane will be set as NoSchedule
To utilize it we have to remove the taint(For practice purpose)
kubectl taint nodes --all node-role.kubernetes.io/master-

3) Add Worker Node

3.1) Repeat the whole of step 1 (Ubuntu image preparation)
For your second k8s node, it should be the worker node, so name it as follows:
- Your name: k8swoker01
- Your server’s name: k8swoker01
- Pick a username: k8s
- Choose a password: <your own password>
- Confirm your password: <your own password>

3.2) Repeat part of step 2 (Install Kubernetes in Ubuntu)
- Tools installation
- Container runtime interface installation
- Kubernetes installation
- Setup network (Note: To set IP address and hostname based on control plane node)

3.3) Create worker node

To join worker node with control plane node. We will have to create a token with kubeadm join and generate a secure key from the control plane node (Note: not the current work node). Then join the cluster with kubeadm join with the token and key in the worker node.

# Go to CP node, it will output the token
sudo kubeadm token create
-> output
gexp9v.w1oe77h0yyuls5nh
# Still at CP node, it will output a secure key
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/ˆ.* //'
-> output
6e7f23199360bba5fb80a98992913b417310b97718bb2fbf9ab99bd00b00e9b0
# Go to Worker node
kubeadm join --token gexp9v.w1oe77h0yyuls5nh k8scp:6443 --discovery-token-ca-cert-hash sha256:6e7f23199360bba5fb80a98992913b417310b97718bb2fbf9ab99bd00b00e9b0

And voila, you have configured a Kubernetes cluster.

Thank you for reading!!

Optional tools to access the cluster

The optional tool that I have used often to the access server is MobaXterm. So here are some of the additional tips to help access the cluster easily.

In order to SSH into your Ubuntu server, we have to install OpenSSH and set up Host-Adapter.

To install OpenSSH if we have not installed it during the setup. We can log into the VM to execute apt install openssh-server .

sudo -i
apt-get update && apt-get upgrade -y
apt install openssh-server

To make it accessible from the host machine we can follow the setup. We can go to the VirtualBox, right-click on VM -> Settings -> Network

Adapter 2: Use Host-only Adapter, so that the host machine is able to access the virtual machine.

In Oracle VirtualBox, start the server in detachable mode
To start in detachable mode, right-click VM-> Settings -> Start-> Detachable Start.

We will get the IP address assigned by the Host-only Adapter using the following command below. For this example, my IP address is 192.168.56.105, so I will use this to SSH with MobaXterm.

ip addr show

We can close the virtual box window once the server is started and continue to run in the background.

To set up the MobaXterm session, we will provide the IP address in the Remote host and the Username previously used to set up the Ubuntu server.

After the session setting, we can now connect to the server via MobaXterm.

Level Up Coding

Thanks for being a part of our community! Before you go:

🚀👉 Top jobs for software engineers

--

--