Kubernetes is a powerful container management system that can be used to manage multiple containers on a single machine. It’s easy to set up a Kubernetes cluster from scratch, but there are some important steps you need to take in order to get started. In this article, we’ll walk you through setting up a Kubernetes cluster from scratch with Kubeadm and Kubectl. We’ll use an Ubuntu 14.04 LTS server as our example, but the process should work equally well with other Linux distributions.

  1. Install Kubeadm and Kubectl on your Ubuntu 14.04 LTS server Kubernetes is built on the open-source container management system Kubeadm. You can install Kubeadm using the following command: sudo apt-get install kubeadm-tools kubeconfig Kubeconfig is a configuration file that contains information about your Kubernetes cluster. You can find it in the /etc/kubernetes/kubeconfig directory. To create a new Kubernetes cluster, you first need to create an empty directory and then copy the contents of kubeconfig into it: mkdir -p /etc/kubernetes/clusters && cp -r /etc/kubernetes/clusters/defaults/* /etc/kubernetes/clusters/new_cluster_name

Kubernetes has a reputation for complexity but modern releases are relatively straightforward to set up. The official cluster administration tool Kubeadm provides an automated experience for booting your control plane and registering worker nodes.

This article will walk you through setting up a simple Kubernetes cluster using the default configuration. This is a “from scratch” guide which should work on a freshly provisioned host. A Debian-based system is assumed but you can adjust most of the commands to match your operating system’s package manager. These steps have been tested using Ubuntu 22.04 and Kubernetes v1.25.

Installing a Container Runtime

Kubernetes needs a CRI-compatible container runtime to start and run your containers. The standard Kubernetes distribution doesn’t come with a runtime so you should install one before you continue. containerd is the most popular choice. It’s the runtime included with modern Docker releases.

You can install containerd using Docker’s Apt repository. First add some dependencies that’ll be used during the installation procedure:

Next add the repository’s GPG key to Apt’s keyrings directory:

Now you can add the correct repository for your system by running this command:

Update your package list to include the contents of the Docker repository:

Finally install containerd:

Check the containerd service has started up:

A few tweaks to the containerd config file are required to get it working properly with Kubernetes. First replace the file’s content with containerd’s default configuration:

This populates all the available config fields and sorts out some issues, such as CRI support being disabled on fresh installs.

Next open /etc/containerd/config.toml and find the following line:

Change the value to true:

This modification is required to enable full support for systemd cgroup management. Without this option, Kubernetes system containers will periodically restart themselves.

Restart containerd to apply your changes:

Installing Kubeadm, Kubectl, and Kubelet

The second phase in the process is to install Kubernetes tools. These three utilities provide the following capabilities:

Kubeadm – An administration tool that operates at the cluster level. You’ll use this to create your cluster and add additional nodes. Kubectl – Kubectl is the CLI you use to interact with your Kubernetes cluster once it’s running. Kubelet – This is the Kubernetes process that runs on your cluster’s worker nodes. It’s responsible for maintaining contact with the control plane and starting new containers when requested.

The three binaries are available in an Apt repository hosted by Google Cloud. First register the repository’s GPG keyring:

Next add the repository to your sources…

…and update your package list:

Now install the packages:

It’s best practice to “hold” these packages so Apt doesn’t automatically update them when you run apt upgrade. Kubernetes cluster upgrades should be initiated manually to prevent downtime and avoid unwanted breaking changes.

Disabling Swap

Kubernetes does not work when swap is enabled. You must turn swap off before you create your cluster. Otherwise you’ll find the provisioning process hangs while waiting for Kubelet to start.

Run this command to disable swap:

Next edit your /etc/fstab file and disable any swap mounts:

This file shows a mount with the swap type as the last line. It should be removed or commented out so that swap remains disabled after system reboots.

Loading the br_netfilter Module

The br_netfilter kernel module is required to enable iptables to see bridged traffic. Kubeadm won’t let you create your cluster when this module’s missing.

You can enable it with the following command:

Make it persist after a reboot by including it in your system’s modules list:

Creating Your Cluster

You’re ready to create your Kubernetes cluster. Run kubeadm init on the machine you want to host your control plane:

The –pod-network-cidr flag is included so that a correct CIDR allocation is available to the Pod networking addon that will be installed later on. The default value of 10.244.0.0/16 works in most cases but you might have to change the range if you’re using a heavily customized networking environment.

Cluster creation can take several minutes to complete. Progress information will be displayed in your terminal. You should see this message upon success:

The output also includes information on how to start using your cluster.

Preparing Your Kubeconfig File

Begin by copying the auto-generated Kubeconfig file into your own .kube/config directory. Adjust the file’s ownership to yourself so that Kubectl can read its contents correctly.

Installing a Pod Networking Addon

Kubernetes requires a Pod networking addon to exist in your cluster before worker nodes begin operating normally. You must manually install a compatible addon to complete your installation.

Calico and Flannel are the two most popular choices. This guide uses Flannel because of it’s simple installation experience.

Use Kubectl to add Flannel to your cluster:

Wait a few moments and then run kubectl get nodes in your terminal. You should see your Node shows as Ready and you can begin interacting with your cluster.

If you run kubectl get pods –all-namespaces, you should see that the control plane components, CoreDNS, and Flannel are all up and running:

Interacting With Your Cluster

Now you can start using Kubectl to interact with your cluster. Before you continue, remove the default taint on your control plane node to allow Pods to schedule onto it. Kubernetes prevents Pods from running on the control plane node to avoid resource contention but this restriction is unnecessary for local use.

Replace ubuntu22 in the command above with the name assigned to your own node.

Now try starting a simple NGINX Pod:

Expose it with a NodePort service:

Find the host port that was allocated to the service:

The port is 30647. HTTP requests to this endpoint should now issue the default NGINX landing page in response:

Your Kubernetes cluster is working!

Adding Another Node

To configure additional worker nodes, first repeat all the steps in the sections up to “Creating Your Cluster” on each machine you want to use. Every Node will need containerd, Kubeadm and Kubelet installed. You should also check your node has full network connectivity to the machine that’s running your control plane.

Next run the following command on your new worker node:

Replace the IP address with that of your control plane node. The values of and will have been displayed when you ran kubeadm init to create your control plane. You can retrieve them using the following steps.

Token

Run kubeadm token list on the control plane node. The token value will be shown in the TOKEN column.

Token CA Cert Hash

Run this command and use its output as the value:

Joining the Cluster

The kubeadm join command should produce this output upon success:

Verify the node’s joined the cluster and is ready to receive Pods by running the kubectl get nodes command:

The node shows up in the list and has Ready as its status. This means it’s operational and Kubernetes can schedule Pods to it.

Summary

Setting up Kubernetes can seem daunting but Kubeadm automates most of the hard bits for you. Although there’s still several steps to work through, you shouldn’t run into issues if you make sure the prerequisites are satisfied before you begin.

Most problems occur because there’s no container runtime available, the br_netfilter kernel module is missing, swap is enabled, or the need to provide a Pod networking addon has been overlooked. Troubleshooting should begin by checking these common mistakes.

Kubeadm gives you the latest version of Kubernetes straight from the project itself. Alternative distributions are available that let you start a single-node cluster with a single command. Minikube, MicroK8s, and K3s are three popular options. Although these are usually easier to set up and upgrade, they all have slight differences compared to upstream Kubernetes. Using Kubeadm gets you closer to Kubernetes’ internal workings and is applicable to many different environments.