How to Install a Kubernetes cluster on Linux

This post summarize all steps required to get a Kubernetes cluster installed correctly and get it running on a Linux machine. Whilst there are many guides available in the internet, this is concise steps that I have tried and will serve as a guide for future use.

For this guide, I will go with 2 virtual servers ( could be cloud servers), one master node and one worker node.

Prerequisites on Master and Worker Nodes

Kubernetes has minimum requirements for the virtual servers as outlined here. After provisioning the virtual servers, the following will have to done before proceeding with Kubernetes install

  • Update distro to make sure the servers are up to date
  • Disable swap memory on all servers
  • Disable SELINUX
  • Transparent masquerading and facilitate network bridges between pods across the cluster
  • Enable IP masquerade on the firewall and allow bridge packets to traverse iptables rules
  • Install docker and containerd tools
$ sudo yum update && sudo yum upgrade 
(or)
$ sudo apt-get update ; sudo apt-get upgrade

$ sudo swapoff -a 
$ sudo setenforce 0 
$ sudo sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=disabled/g' > /etc/sysconfig/selinux
$ modprobe br_netfilter
$ firewall-cmd --add-masquerade --permanent firewall-cmd --reload
$ sudo tee /etc/sysctl.d/k8s.conf<<EOF 
> net.bridge.bridge-nf-call-ip6tables = 1 
> net.bridge.bridge-nf-call-iptables = 1 
> EOF
$ sudo sysctl --system 

$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg2 
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 
$ sudo apt update sudo apt install -y containerd.io docker-ce docker-ce-cli 
$ sudo mkdir -p /etc/systemd/system/docker.service.d 
$ sudo tee /etc/docker/daemon.json <<EOF 
> {   
> "exec-opts": ["native.cgroupdriver=systemd"],   
> "log-driver": "json-file",   
> "log-opts": {
>      "max-size": "100m"   
> },   
> "storage-driver": "overlay2" 
> } 
EOF 

Installing Kubernetes on Master and Slave nodes

Follow the steps given below to install Kubernetes on Master and Slave nodes.

Step 1: Setup Kubernetes Repo

Create a file Kubernetes.repo in /etc/yum.repos.d with following

[kubernetes]
name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 
gpgcheck=1 
repo_gpgcheck=1 
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg 

Add Kubernetes repo in apt

$ sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

$ echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

Step 2: Install Kubernetes Tools

Kubernetes is made of three main packages which can be installed with following command

$ sudo yum upgrade 
$ sudo yum install kubeadm kubectl kubelet
or
$ sudo apt-get upgrade
$ sudo apt -y install kubelet kubeadm kubectl 
$ sudo apt-mark hold kubelet kubeadm kubectl

Step 3: Confirm Version

tux-networks@kmaster:~$ kubectl version --client && kubeadm version
Client Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.1", GitCommit:"5e58841cce77d4bc13713ad2b91fa0d961e69192", GitTreeState:"clean", BuildDate:"2021-05-12T14:18:45Z", GoVersion:"go1.16.4", Compiler:"gc", Platform:"linux/amd64"}
kubeadm version: &version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.1", GitCommit:"5e58841cce77d4bc13713ad2b91fa0d961e69192", GitTreeState:"clean", BuildDate:"2021-05-12T14:17:27Z", GoVersion:"go1.16.4", Compiler:"gc", Platform:"linux/amd64"}

Step 4: Enable Kubelet

Enable the services to run at startup and start kubelet service

$ sudo systemctl enable kubelet
$ sudo systemctl start kubelet

Step 5: Check Kubelet service

Confirm Kubernetes services are started successfully 
$ sudo systemctl status kubelet

Configure Master Node

After successful installation of Kubernetes, the nodes will have to configured to form a cluster

Step 1: Configure Kubeadm

tux-networks@kmaster:~$ sudo kubeadm config images pull
 [config/images] Pulled k8s.gcr.io/kube-apiserver:v1.21.1
 [config/images] Pulled k8s.gcr.io/kube-controller-manager:v1.21.1
 [config/images] Pulled k8s.gcr.io/kube-scheduler:v1.21.1
 [config/images] Pulled k8s.gcr.io/kube-proxy:v1.21.1
 [config/images] Pulled k8s.gcr.io/pause:3.4.1
 [config/images] Pulled k8s.gcr.io/etcd:3.4.13-0
 [config/images] Pulled k8s.gcr.io/coredns/coredns:v1.8.0

Step 2: Open ports used by Kubernetes

$ firewall-cmd --zone=public --permanent --add-port={6443,2379,2380,10250,10251,10252}/tcp

Step 3: Allow docker access from another node

$ firewall-cmd --zone=public --permanent --add-rich-rule 'rule family=ipv4 source address=<worker-ip>/32 accept'

Step 4: Allow access to localhost from the docker container

$ firewall-cmd --zone=public --permanent --add-rich-rule 'rule family=ipv4 source address=127.0.0.0/16 accept'

Step 5: Refresh firewall changes

$ sudo firewall-cmd --reload

Install CNI (container network interface) plugin for Kubernetes.

For this setup, we’ll be using Calico: https://docs.projectcalico.org/getting-started/kubernetes/quickstart#overview

Issue the following command:

$ kubeadm init --pod-network-cidr 192.168.0.0/16

You should see something like the below.

Make note of the discovery token, it’s needed to join worker nodes to the cluster.

kubeadm join 172.22.223.90:6443 --token oaguax.tb7vrq9ec3lm9oho \
         --discovery-token-ca-cert-hash sha256:43e90d1949ba5b2cc3e5e453a023d1650bc3d0848745b0174854a46c4a5b9a4f

Make the following directory and configuration files.

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

sudo curl https://docs.projectcalico.org/manifests/canal.yaml -O 
kubectl apply -f canal.yaml

7. Enable pod to run on Master. This is only for demonstration purposes and is not recommended for production use.

kubectl taint nodes --all node-role.kubernetes.io/master-

8. Check that Master node has been enabled and is running.

tux-networks@kmaster:~$ kubectl get nodes
 NAME      STATUS   ROLES                  AGE   VERSION
 kmaster   Ready    control-plane,master   60m   v1.21.1

On successful execution, you should see a node with ready status. If not, wait for a while and repeat the command.

After the master node setup is completed and when the Master node confirmed to be running, continue with the next section to join the Worker node to the cluster.

Configuring Kubernetes on the Worker node only

Each Kubernetes installation needs to have one or more worker nodes that run the containerized applications. We’ll only configure one worker in this example but repeat these steps to join more nodes to your cluster.

1. Open ports used by Kubernetes.

firewall-cmd --zone=public --permanent --add-port={10250,30000-32767}/tcp

2. Make the changes permanent.

firewall-cmd --reload

3. Join the cluster with the previously noted token.

Note that the join token below is just an example.

tux-networks@knode01:~$ sudo kubeadm join 172.22.223.90:6443 --token oaguax.tb7vrq9ec3lm9oho \
      --discovery-token-ca-cert-hash sha256:43e90d1949ba5b2cc3e5e453a023d1650bc3d0848745b0174854a46c4a5b9a4f
   [preflight] Running pre-flight checks
   [preflight] Reading configuration from the cluster…
   [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
   [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
   [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
   [kubelet-start] Starting the kubelet
   [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap… 
 This node has joined the cluster:
 Certificate signing request was sent to apiserver and a response was received.
 The Kubelet was informed of the new secure connection details. 
 Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

4. See if the Worker node successfully joined.

Go back to the Master node and issue the following command.

tux-networks@kmaster:~$ kubectl get nodes
 NAME      STATUS   ROLES                  AGE   VERSION
 kmaster   Ready    control-plane,master   65m   v1.21.1
 knode01   Ready                           41s   v1.21.1

On success, you should see two nodes with ready status. If not, wait for a while and repeat the command.

Deploy an Application on Kubernetes Cluster

Test if we are able to deploy an application on our cluster

tux-networks@kmaster:~$ kubectl apply -f https://k8s.io/examples/pods/commands.yaml
pod/command-demo created
tux-networks@kmaster:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
command-demo 0/1 ContainerCreating 0 6s
tux-networks@kmaster:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
command-demo 0/1 Completed 0 19s
tux-networks@knode01:~$ kubectl logs command-demo
command-demo
tcp://10.96.0.1:443

0 Comments on How to Install a Kubernetes cluster on Linux

Leave a Comment

Your email address will not be published. Required fields are marked *

You Might Be Interested In