Build Kubernetes Clusters with Kubeadm

Guide to Kubernetes Tools
Chapter 10 Kubeadm Tutorial

Kubeadm is a tool used to build Kubernetes (K8s) clusters. Kubeadm performs the actions necessary to get a minimum viable cluster up and running quickly. By design, it cares only about bootstrapping, not about provisioning machines (underlying worker and master nodes). Kubeadm also serves as a building block for higher-level and more tailored tooling.

Kubeadm’s Features

Common use cases for Kubeadm include testing, creating baselines for more advanced K8s deployments, and providing new K8s users a simple starting point for cluster configuration. The specific features that make kubeadm useful in those applications are:

Quick minimum viable cluster creation
Kubeadm is designed to have all the components you need in one place in one cluster regardless of where you are running them.
Portable
Kubeadm can be used to set up a cluster anywhere whether it's your laptop, a Raspberry Pi, or public cloud infrastructure.
Local development
As Kubeadm creates clusters with minimal dependencies and quickly, it's an ideal candidate for creating disposable clusters on local machines for development and testing needs.
Building block for other tools
Kubeadm is not just a K8s installer. It also serves as a building block for other tools like Kubespray.

Kubeadm vs kOps vs Kubespray

Of course, kubeadm isn’t the only tool available to deploy a K8s cluster. kOps and Kubespray are two popular tools for the same general use case. However, each tool offers different functionality that makes them ideal for different applications. Before we dive into how to create the Kubeadm cluster, let's take a closer look at how it stacks up to the alternatives.

Comparing Kubeadm, kOps, & Kubespray Functionality
Functionality Kubeadm Kops Kubespray
Infrastructure Does not create infrastructure Creates infrastructure Creates infrastructure
Creates “production-ready” clusters No Yes Yes
Lightweight Yes No No
Manages cluster lifecycle No Yes Yes

As we can see, Kubeadm is a more lightweight tool that doesn’t attempt to do everything kOps or Kubespray can. This is consistent with its focus on minimum viable clusters.

The Problems kubeadm Solves

With more robust tools available, why use kubeadm? In simple terms: because it reduces complexity and makes it easy to get a usable K8s cluster deployed.

Provisioning a Kubernetes cluster with other tools takes time, server resources, and expertise. Kubeadm is easy to get started with and lightweight enough to be used on local machines. As a result, many developers and testers prefer kubeadm for cases that require the fast deployment of a cluster with minimal resources.

How to Create a Kubernetes Cluster with kubeadm

Now that we know what kubeadm is, let’s walk through how to use it to create a Kubernetes cluster. In this example, we will create a 3 node cluster with 1 master node and 2 worker nodes.

1. Install Docker on All Three Nodes

Since kubeadm does not create infrastructure, as a prerequisite we need to provision 3 machines that will form the cluster.

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-get update
sudo apt-get install -y docker-ce=18.06.1~ce~3-0~ubuntu
sudo apt-mark hold docker-ce

Check if docker is installed:

sudo systemctl status docker

Need more help? Detailed instructions can be found in the official Docker docs.

2. Install kubeadm, kubelet, & kubectl on All Three Nodes

  1. curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
  2. cat << EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list\
    deb https://apt.kubernetes.io/ kubernetes-xenial main
    EOF
  3. sudo apt-get update
  4. sudo apt-get install -y kubelet=1.14.5-00 kubeadm=1.14.5-00 kubectl=1.14.5-00
  5. sudo apt-mark hold kubelet kubeadm kubectl

3. Initiate Cluster Setup on the Master Node

  1. First, we’ll initialize the control plane node and specify a network range for the pods using CIDR notation:
    sudo kubeadm init --pod-network-cidr=10.244.0.0/16
    Note: This command prints very important information which will be used later by worker nodes to join the master and form a cluster. The output should look something like this:
    'kubeadm join 10.0.1.101:6443 --token mgvt0h.3ui2w5lkjkcphc2x \    --discovery-token-ca-cert-hash sha256:4e6be4e531e704e7b919a97a3b3359896b00faf3853c6d4240bf46d3a1eb990d'
  2. Next, we’ll configure the kubeconfig file:
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
  3. Run the kubectl version command on the Kube master node to verify it is up and running:
    > kubectl version
    Client Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.5", GitCommit:"0e9fcb426b100a2aea5ed5c25b3d8cfbb01a8acf", GitTreeState:"clean", BuildDate:"2019-08-05T09:21:30Z", GoVersion:"go1.12.5", Compiler:"gc", Platform:"linux/amd64"}
    Server Version: version.Info{Major:"1", Minor:"14", GitVersion:"v1.14.10", GitCommit:"575467a0eaf3ca1f20eb86215b3bde40a5ae617a", GitTreeState:"clean", BuildDate:"2019-12-11T12:32:32Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}
  4. Next, we’ll check the nodes in the cluster with kubectl get nodes. At this point there should be only 1 node (the master node). Here’s an example of the expected output (don’t worry about the “NotReady” status, we’ll get to that soon!):
    > kubectl get nodes
    NAME            STATUS     ROLES    AGE   VERSION
    ip-10-0-1-101   NotReady   master   63s   v1.14.5

4. Add the Two Worker Nodes to the Cluster

With the master node created, we can add our worker nodes to the cluster.

  1. Use kubeadm join command on both worker nodes:
    kubeadm join 10.0.1.101:6443 --token mgvt0h.3ui2w5lkjkcphc2x \
        --discovery-token-ca-cert-hash sha256:4e6be4e531e704e7b919a97a3b3359896b00faf3853c6d4240bf46d3a1eb990d
  2. After running join command on both the worker nodes, go to master nodes and run the kubectl get nodes command to verify that worker nodes have joined the cluster:
    > kubectl get nodes
    NAME            STATUS     ROLES    AGE     VERSION
    ip-10-0-1-101   NotReady   master   2m41s   v1.14.5
    ip-10-0-1-102   NotReady      23s     v1.14.5
    ip-10-0-1-103   NotReady      7s      v1.14.5

We can see the nodes have joined the cluster. Now let's take care of that NotReady status...

5. Set up Networking for the Cluster

Once the worker nodes are in the cluster, we need to configure the network settings.

  1. Turn on iptables bridge calls on all three nodes:
    echo "net.bridge.bridge-nf-call-iptables=1" |
    sudo tee -a /etc/sysctl.conf
    sudo sysctl -p
  2. Next, run this command on only the Kube master node:
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
  3. Wait a few seconds run kubectl get nodes and all the nodes should have a “Ready” status:
    > kubectl get nodes
    NAME            STATUS   ROLES    AGE     VERSION
    ip-10-0-1-101   Ready    master   4m19s   v1.14.5
    ip-10-0-1-102   Ready       2m1s    v1.14.5
    ip-10-0-1-103   Ready       105s    v1.14.5

That’s it! We now have a working K8s cluster!

Kubeadm Best Practices

Kubeadm is a great tool when used for its intended applications. Here are three best practices to keep in mind to ensure you’re using the right tool for the job and getting the most out of kubeadm.

  1. Don’t use kubeadm for production clusters that require autoscaling: Generally, kubeadm should not be used for production clusters because it does not come with node autoscaling/cluster autoscaling functionality. This is because node autoscaling requires managing underlying infrastructure and hardware, which kubeadm leaves to other tools.
  2. Take frequent backups of etcd: By default, kubeadm does not have a multi-etcd cluster for storing cluster state. Be sure to take regular backups of etcd in case a failure occurs.
  3. Keep track of machines/nodes: Kubeadm can not turn machines off when they are not in use. As a result, you’ll need to use an external solution to track worker nodes and their resource utilization to cluster optimize cost and efficiency.

Continue Reading this Series