Kubernetes Single Master Node

A single master cluster has one master node and can easily fail, while a multi-master cluster uses multiple master nodes, any of them has access to all worker nodes in the cluster.

If a single-master node fails you can not create more pods, services etc.

In this lab there will be one master and two worker nodes. Multi master cluster and high-availability (HA) will be detailed on further sections. The commands shown in this section are for the ubuntu/xenial64 (16.04.6 LTS), weblinks for the other OSs are added in steps.

Single Master Topology

Initialize the current directory to be a Vagrant environment by creating an initial Vagrantfile. Vagrantfile will be created in the folder.

C:\Vagrant-Lab\Master-1>vagrant init
A Vagrantfile has been placed in this directory. You are now
ready to vagrant up your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on vagrantup.com for more information on using Vagrant.

Configure the Vagrantfile with the required settings as below.

  • config.vm.box is the different operating systems. More OS can be found here.
  • config.vm.box_version is the OS version. Versions for the OS we use are here.
  • config.vm.hostname changes the hostname when you ssh to VM.
  • config.vm.network “private_network” creates a second interface and assigns the IP address to the node.
  • config.vm.network “forwarded_port” sets a different port for the SSH. By default it assigns a random value.
  • config.vm.define changes the machine name from default to any value.
  • config.vm.provider shows that will be done on virtualbox.
  • vb.name changes the VM name on VirtualBox from a random value to any.
  • vb.memory updates the memory assigned to the node.
  • vb.cpus updates the cpu assigned to the node

config.vm.box = “ubuntu/xenial64”
config.vm.box_version = “20200407.0.0”
config.vm.hostname = “k8-master1”
config.vm.network “private_network”, ip: “”
config.vm.network “forwarded_port”, guest: 22, host: 2250, host_ip: “”, id: “ssh”
config.vm.define “k8-master1”
config.vm.provider “virtualbox” do |vb|
vb.name = “vagrant_k8-master1”
vb.memory = “2048”
vb.cpus = 2

Step 1 : Install Containerd
You can find the details on the Kubernetes site.

## necessary steps to use containerd as CRI runtime ##
$ cat > /etc/modules-load.d/containerd.conf <<EOF
$ modprobe overlay
$ modprobe br_netfilter
$ cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
$ sysctl –system

## Install containerd on Ubuntu ##
$ apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add –
add-apt-repository \
“deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
$ apt-get update && apt-get install -y containerd.io
$ mkdir -p /etc/containerd
$ containerd config default > /etc/containerd/config.toml
$ systemctl restart containerd

Step 2: Install Docker
You can find the details on Dockers site

## Set Up the Repository ##
$ sudo apt-get update
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add –
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
“deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable” \

## Install Docker Engine ##
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo docker run hello-world

Step 3: Allow regular user to run docker commands
You can add the regular user (vagrant) to the docker user group so that you can run docker commands as vagrant user without sudo privileges.

usermod -aG docker vagrant

Step-4: Install Kubeadm, Kubelet and Kubctl
You can find the details on Kubernetes site

$ sudo apt-get update && sudo apt-get install -y apt-transport-https curl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add –
$ cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl

Step-5: Kubelet requires swap to be disabled
Some Kubelet/Kubernet versions do not work with Swap enabled on Linux Machines.

swapoff -a
## disable swap permanently ##
sudo sed -i ‘/ swap / s/^\(.*\)$/#\1/g’ /etc/fstab

Step-6: Initialize API-Server
Initialise the API Server with a new POD subnet ( API server IP address will be same with the enp0s8 interface.
You can add “–dry-run” to simulate the command and observe the errors before the production.

# IP Adress of the enp0s interface ##
IP_ADDR=`ifconfig enp0s8 | grep Mask | awk ‘{print $2}’| cut -f2 -d:`

# Activates the API Server #
HOST_NAME=$(hostname -s)
kubeadm init –apiserver-advertise-address=$IP_ADDR –apiserver-cert-extra-sans=$IP_ADDR, –node-name $HOST_NAME –pod-network-cidr=

Kubelet is ready on the master node with the minimum configurations. Additional Plugins can be added like Callico, Flannel for the advanced network configurations, or Dashboard for the web based GUI.

[email protected]:~$ kubectl get nodes -o wide // shows node status
[email protected]:~$ kubeadm config view // shows the API-server parameters
[email protected]:~$ ps aux | grep apiserver // shows the API-server service

## The units’ status below must be active “(running)” ##
systemctl status kubernetes
systemctl status docker
systemctl status containerd

You can use the vagrant commands to ssh, reload, backup, destoy the node.

C:\Vagrant-Lab\Master-1> vagrant global-status // Shows the global status of all nodes in cluster.
C:\Vagrant-Lab\Master-1> vagrant ssh-config // Shows the ssh config, port
C:\Vagrant-Lab\Master-1> vagrant snapshot save <node-name> <snapshot-name> // Takes snapshot
C:\Vagrant-Lab\Master-1> vagrant reload <node-name> // Reloads the running node
C:\Vagrant-Lab\Master-1> vagrant halt <node-name> // Stops the node
C:\Vagrant-Lab\Master-1> vagrant up <node-name> –provision // Starts the node
C:\Vagrant-Lab\Master-1> vagrant destroy <node-name> // Destroys the node permanently

Step 7: Create kubeadm Token
When the worker nodes are ready bootstrap token must be created to establish bidirectional trust between worker nodes joining the cluster and a control-plane node.
–print-join-command shows the join command that will be used on worker node to join to that msater node.
–dry-run can be used to simulate the command.

[email protected]:~$ kubeadm token create –print-join-command

## Sample Output – This join command will be run on worker node ##
kubeadm join –token rehg1k.jo045reyosvrpq6n –discovery-token-ca-cert-hash sha256:9382a71afad8373226258cf0b715d09f2b15b6d24b5b77734457c97194c6fdce

Step 8: You can set the role for worker node
When the worker node joined to the master, the role will be shown <NONE> by default. This can be changed to “worker” for the administrating purposes.

[email protected]:~$ kubectl label node k8-worker1 node-role.kubernetes.io/worker=worker
node/k8-worker1 labeled
[email protected]:~$ kubectl get node -o wider
k8-master1 Ready master 4h18m v1.18.1 Ubuntu 16.04.6 LTS 4.4.0-177-generic docker://19.3.8
k8-worker1 Ready worker 7m16s v1.18.2 Ubuntu 16.04.6 LTS 4.4.0-177-generic docker://19.3.8

Series Navigation<< Kubernetes ComponentsKubernetes Worker Node >>