How To Setup Kubernetes Cluster Using Kubeadm on Ubuntu 18.04/16.04 LTS

In this article, We are going to perform, How To Setup Kubernetes Cluster Using Kubeadm on Ubuntu 18.04/16.04 LTS or any other cloud platform like Amazon Ec2, Azure VM, Google Cloud Compute,etc. with preinstalled Ubuntu 18.04/16.04 LTS.


Kubernetes is one of the Leading open source Container Orchestration Engine. It is used to automatic cluster deployment, scaling and manage containerized applications.

Kubeadm helps for installing and configuring Kubernetes cluster using command line. We are going to use below kubeadm commands while configuring Kubernetes cluster.

Kubeadm commands

kubeadm init(on master node) : It is used to initialize and configure any node as a master node.

kubeadm join(on worker node): It is used to initialize and configure any node as worker node.

kubeadm token: It is used to genrate token.

kubeadm version: It used to check kubeadm version.

To know more about kubeadm commands,visit official Kubernetes site.

Kubernetes Cluster Components

Genrally Kubernetes cluster includes one master node and many worker nodes also we can use more than one master node.

On Master node

Kubernetes master is responsible for managing entire cluster, it coordinates all the activities inside the cluster and communicates with worker node.There are four major components on master node.

API Server

It is used to exposing various API’s. It is used to create,delete and update any object inside the cluster using kubectl command. API objects can be pods,containers,deployments,services..etc.


Scheduler is responsible for physically scheduling pods across multiple nodes, depending upon when we submit requirement to API server, scheduler schedules pod accordingly.

Controller Manager

It is responsible overall health of entire cluster such as no of nodes insides the  cluster, up and running status as per specification.


etcd is light weight key-value database, it stores information like about current state of cluster,..etc.

On Worker Node

Worker node can be any Physical Server or Virtual Machine where containers are deployed , containers can be docker,rocket,.etc.


Kubelet is primary agent which runs on each worker node.It ensures containers are running in pod.


It is core Networking component of Kubernetes cluster, it is responsible for entire network configuration, it maintains distributed network across all containers, pods and nodes.


Pod is scheduling unit in Kubernetes, it consists of one or more container. With the help of pod we can deploy one or more container.


It provides runtime environment for application.


  • 2 or 3 Ubuntu 18.04/16.04 LTS System with Minimal Installation
  • Minimum 2 or more CPU, 3 GB RAM.
  • Disable SWAP on All node
  • SSH Access with sudo privileges

Firewall Ports/Inbound Traffic Ports for Kubernetes Cluster

Control-plane node(s)

Protocol Direction Port Range Purpose Used By
TCP Inbound 6443* Kubernetes API server All
TCP Inbound 2379-2380 etcd server client API kube-apiserver, etcd
TCP Inbound 10250 Kubelet API Self, Control plane
TCP Inbound 10251 kube-scheduler Self
TCP Inbound 10252 kube-controller-manager Self

Worker node(s)

Protocol Direction Port Range Purpose Used By
TCP Inbound 10250 Kubelet API Self, Control plane
TCP Inbound 30000-32767 NodePort Services† All

Disable swap

swapoff -a

Also comment out the reference to swap in /etc/fstab. Start by editing the below file:

sudo nano /etc/fstab

Reboot the system to take effect

sudo reboot

Update the system Packages

sudo apt-get update

Install Docker on All node

Install docker on both master and worker node

sudo apt-get install -y


You can install docker by script as shown below

curl -fsSL -o 

Check docker images

docker images


Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/json: dial unix /var/run/docker.sock: connect: permission denied


Add the docker user in group and give permission for docker.sock

sudo usermod -aG docker $USER

Change the docker.sock permission

sudo chmod 666 /var/run/docker.sock

Start the Docker service if not started

sudo systemctl enable docker.service

To check the docker service status

sudo systemctl status docker.service

Enable Docker service at startup

sudo systemctl enable docker.service

Install HTTPS Support on All node

Install HTTPS support package on all node

sudo apt-get install -y apt-transport-https

Install CURL on All node

Install curl on master node if not installed

sudo apt-get install curl

Add Kubernetes GPG Key on All node

Add Kubernetes GPG key in all node.

curl -s | sudo apt-key add -

Add Kubernetes APT Repository on All node

Add Kubernetes apt repository on all node for Ubuntu.

sudo apt-add-repository "deb kubernetes-xenial main"

Install Kubeadm,Kubelet and Kubectl on All Node

Install kubeadm,kubelet and kubectl using below command.

sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Configure cggroup driver

add the cggroup driver in kubelet

sudo sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

reload the daemon

sudo systemctl daemon-reload

Restart the kubelet service

sudo systemctl restart kubelet

Initialize the Master node using kubeadm (on Master Node)

Next initialize the master node using kubeadm.

sudo kubeadm init --pod-network-cidr=


Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube

  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.

Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join --token 2qmwga.qyejfbo9vouiowlt \

    --discovery-token-ca-cert-hash sha256:083a2a20c8de9254100f1b37b4be1999946aee6f34791985c80d9eced9618e94

As above output mentioned copy the token in your notepad, we will need to join worker/slave to master node

Create new ‘.kube’ configuration directory and copy the configuration ‘admin.conf’ from ‘/etc/kubernetes’ directory.

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

To check kubeadm version.

kubeadm version

To check master node status

kubectl get nodes

Configure Pod Network and Verify Pod namespaces

Install the Weave network plugin to communicate master and worker nodes.

kubectl apply -f "$(kubectl version | base64 | tr -d '\n')"


serviceaccount/weave-net created created created created created

daemonset.apps/weave-net created

Check node status

Join Worker Node to the Cluster

Next Join two worker nodes to master.

sudo kubeadm join --token 2qmwga.qyejfbo9vouiowlt \     --discovery-token-ca-cert-hash             sha256:083a2a20c8de9254100f1b37b4be1999946aee6f34791985c80d9eced9618e94


[preflight] Reading configuration from the cluster...

[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

[kubelet-start] Downloading configuration for the kubelet from the "kubelet-config-1.17" ConfigMap in the kube-system namespace

[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

Check the All node status

sudo kubectl get nodes



NAME               STATUS   ROLES    AGE     VERSION

ip-172-31-16-180   Ready    master   3m19s   v1.20.5

ip-172-31-16-86    Ready    worker1   6m15s   v1.20.5

ip-172-31-21-34    Ready    worker2   3m23s   v1.20.5

To Verify Pod namespaces

sudo kubectl get pods --all-namespaces


NAMESPACE     NAME                                      READY   STATUS    RESTARTS   AGE

kube-system   coredns-6955765f44-7sw4r                  1/1     Running   0          6m46s

kube-system   coredns-6955765f44-nwwx5                  1/1     Running   0          6m46s

kube-system   etcd-ip-172-31-16-86                      1/1     Running   0          6m53s

kube-system   kube-apiserver-ip-172-31-16-86            1/1     Running   0          6m53s

kube-system   kube-controller-manager-ip-172-31-16-86   1/1     Running   0          6m53s

kube-system   kube-proxy-b5vht                          1/1     Running   0          4m5s

kube-system   kube-proxy-cm6r4                          1/1     Running   0          4m1s

kube-system   kube-proxy-jxr9z                          1/1     Running   0          6m45s

kube-system   kube-scheduler-ip-172-31-16-86            1/1     Running   0          6m53s

kube-system   weave-net-99tsd                           2/2     Running   0          93s

kube-system   weave-net-bwshk                           2/2     Running   0          93s

kube-system   weave-net-g8rg8                           2/2     Running   0          93s

We have covered Setup Kubernetes Cluster Using Kubeadm.

Create a Deployment using YAML in Kubernetes

Lets create a deployment on master node named “nginx-deploy” using YAML.

sudo nano nginx-deploy.yaml

Deployment YAML file should like below

apiVersion: apps/v1
kind: Deployment
  name: nginx-deployment
    app: nginx-app
  replicas: 1
      app: nginx-app
        app: nginx-app
      - name: nginx-container
        image: nginx:latest
        - containerPort: 80

Lets create a pod using kubectl command

kubectl apply -f nginx-deploy.yaml


deployment.apps/nginx-deployment created

Lets check Pod status

kubectl get pods

To check Pods all information

kubectl describe pods

To check pods IP address and its states

kubectl get pods -o wide

To delete pod

kubectl delete pod fosstechnix-web-pod(pod name)


kubectl delete -f fosstechnix-web-pod.yml


In this article, We have covered, How To Setup Kubernetes Cluster Using Kubeadm on Ubuntu 18.04/16.04 LTS, Initializing master node, creating pod network,join worker/slave node to master, creating pod using YAML , checking the status of node,pod,namespace and deleting pod.


[preflight] Running pre-flight checks
[WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at
error execution phase preflight: [preflight] Some fatal errors occurred:
[ERROR DirAvailable--etc-kubernetes-manifests]: /etc/kubernetes/manifests is not empty
[ERROR FileAvailable--etc-kubernetes-kubelet.conf]: /etc/kubernetes/kubelet.conf already exists
[ERROR Port-10250]: Port 10250 is in use
[ERROR FileAvailable--etc-kubernetes-pki-ca.crt]: /etc/kubernetes/pki/ca.crt already exists
[preflight] If you know what you are doing, you can make a check non-fatal with `--ignore-preflight-errors=...`
To see the stack trace of this error execute with --v=5 or higher


Reset the kubeadm and join again

sudo kubeadm reset

Related Articles:


Rushikesh Neerukondi

I am Rushikesh Neerukondi working as DevOps Engineer and Cloud Solution Architect.Likes to Share Knowledge.

9 thoughts on “How To Setup Kubernetes Cluster Using Kubeadm on Ubuntu 18.04/16.04 LTS”

  1. when i have excute sudo kubeadm init
    i am facing below issue
    [wait-control-plane] Waiting for the kubelet to boot up the control plane as sta tic Pods from directory “/etc/kubernetes/manifests”. This can take up to 4m0s
    [kubelet-check] Initial timeout of 40s passed.
    [kubelet-check] It seems like the kubelet isn’t running or healthy.
    [kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz ‘ failed with error: Get “http://localhost:10248/healthz”: dial tcp 248: connect: connection refused.


Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap