I write what I learn here

Setting up Bare-metal Kubernetes From Scratch - Easy Way [Part 1]

Setting up Bare-metal Kubernetes From Scratch - Easy Way [Part 1]

With the rise of cloud native applications and adoption of agile software delivery methodology that require continued update of features, companies are faced with a challenging task or optimizing software delivery and management of processes. This is one of the core reasons for the growth of containerization technology. Containers help software run reliably when moved from one computing environment to another. This can be from the development environment to production without need for doing extra configurations. This has led to high adoption of Kubernetes, an open-source, production-grade solution for automation of container deployment, containerized app management and scaling. Some of the advantages of using kubernetes include;

  • It’s open-source and free
  • Fault tolerant, secure and highly scalable- Auto horizontal scaling in the number of Pods.
  • Efficient for micro services
  • Works well with CI/CD pipelines- Better version control and rolling updates 
  • Has a large community supporting it such as Google & Red Hat
  • More efficient with internal DNS and load-balancing out of the box
  • Eliminates infrastructure/vendor lock-ins, since it’s highly compatible without imposing too many restrictions

However, there is not so much support/ resources for Kubernetes cluster on bare-metal servers. Some of the reasons why you might need a bare-metal/VM cluster are;

  • To reduce latency of running applications
  • Store your data locally and adhere to regulations

In this blog series, I will help you set up your first bare-metal/ virtual machine cluster from scratch and deploy applications that run efficiently just like in the cloud (AWS,GCP, Azure).

What you need to know/have

  • Basic Linux skills
  • Understanding of Kubernetes terminologies
  • Two bare-metal or virtual machines running Ubuntu 16.04
  • Workstation (desktop/laptop)
  • Internet connection

Installing Docker

Install the latest version of Docker that is compatible with the version of Kubernetes you want to install. Add the GPG key for the official Docker repository to your system

curl -fsSL | sudo apt-key add -

Add the Docker repository to APT sources:

sudo add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable"

Update the package database with the Docker packages

sudo apt-get update

Install Docker

sudo apt-get install -y docker-ce

Check if docker is running successfully

sudo systemctl status docker

Disable the swap file

Kubernetes will not work if swap is enabled for Kubernetes 1.7+. You can check if you have swap enabled by typing:

cat /proc/swaps

Turn off swap by running:

sudo swapoff -a

This is a temporary solution and needs to be repeated if you restart the server.

Install Kubernetes packages

Start by Installing Kubernetes apt repositories followed by updating packages and finally Install kubelet,kubeadm and kubernetes-cni. This is done on both machines (Master Node & Worker Node)

sudo apt-get update \
  && sudo apt-get install -y apt-transport-https \
  && curl -s | sudo apt-key add -
echo "deb kubernetes-xenial main" \
  | sudo tee -a /etc/apt/sources.list.d/kubernetes.list \
  && sudo apt-get update
sudo apt-get update \
 && sudo apt-get install -y \
 kubelet \
 kubeadm \

The kubelet ensures that the containers described in the PodSpecs are running and are healthy. kubeadm helps you bootstrap a minimum viable Kubernetes cluster  and also supports other cluster life cycle functions, such as upgrades, downgrade, and managing bootstrap tokens.

Kubernetes-cni handles networking in kubernetes.

Initialize Kubernetes cluster

This step is only performed on the master node and will not work if you have missed any of the prior steps. Therefore you need to ensure the previous steps work fine.

sudo kubeadm init --pod-network-cidr= --apiserver-advertise-address= --kubernetes-version stable-1.13

--apiserver-advertise-address is the IP of the master node machine which will advertise the API server --kubernetes-version is the version of kubernetes you are targeting (1.13) and --pod-network-cidr specifies an address space/range for the containers you will deploy. The interesting thing about this setup is that you can use internal IP’s (like in this example) to create the cluster which improves on security and speeds communication between your nodes.

After the command runs successfully, note to copy the **kubeadmn join token **and save it separately. This token will be used to join worker nodes to the cluster. This should be something like

kubeadm join :6443 --token 1jixhu.dxhui0yrta4roi8x --discovery-token-ca-cert-hash sha256:abae1989dc2868v8s5dl8b52cf8914fc54epa67d3d68b8d98c3e43290b994hs51d9

Next we will create a new user and configure them to administer the cluster-administration. Note: Avoid administering the cluster as a root user. In this case I create a user called clusteradmin

Create user and add them to sudoers group

sudo useradd clusteradmin -G sudo -m -s /bin/bash

Set password for the user

sudo passwd clusteradmin <User Password>

Switch user to newly created user

sudo su clusteradmin

Confirm you are in the right user account

cd $HOME

Copy cluster kube config token (admin.conf) to your home directory and set is as the default cluster that will be used when you run kubectl commands.

sudo cp /etc/kubernetes/admin.conf $HOME/

sudo chown $(id -u):$(id -g) $HOME/admin.conf
export KUBECONFIG=$HOME/admin.conf
echo "export KUBECONFIG=$HOME/admin.conf" | tee -a ~/.bashrc

Install Networking

Kubernetes offer multiple networking providers as listed here and in this blog we will use Flannel which is simple to use and reliable as well. Apply the RBAC followed by the actual installation of the cluster.

kubectl apply -f

kubectl apply -f

By default, kubernetes does not allow containers to run on the master node and that’s why we are using two VM’s or physical servers. However this can be enabled by tainting the master by running the command below.

kubectl taint nodes --all

Check the status of all deployed pods by running

kubectl get all --namespace=kube-system

Joining Worker Nodes

From the worker node you want to join to the cluster, run the command that was generated when you initialized the cluster .

kubeadm join :6443 --token 1jixhu.dxhui0yrta4roi8x --discovery-token-ca-cert-hash sha256:abae1989dc2868v8s5dl8b52cf8914fc54epa67d3d68b8d98c3e43290b994hs51d9

In case you lost the auto generated join token, you can generate another join token by running this command on the master node.

kubeadm token create –print-join-command

To verify the node has joined successfully run the command below. If the status of all the nodes is ready then your cluster is set for deployment.

kubectl get nodes

Hope you found this blog helpful and you can successfully run your first cluster on physical machines. In the next blog, I will take you through deployment of applications on the** bare-metal cluster** we have just created.

As you might already know, bare-metal Kubernetes does not offer LoadBalancer for exposing services outside the cluster which gets very challenging and technical. I will guide you how to go around this challenge.


To make a comment you have to login