In this article, we will learn to create a single master Kubernetes (k8s) cluster using kubeadm.
What is kubeadm ?
Kubeadm is a tool that helps you bootstrap a simple Kubernetes cluster and simplifies the deployment process. It performs the actions necessary to get a minimum viable cluster up and running such that it passes Kubernetes Conformance tests.
A typical Kubernetes cluster set-up with kubeadm consists of a single Kubernetes master, which is the machine coordinating the cluster, and multiple Kubernetes nodes, which are the machines running the actual workload.
Setting up the machines
We will deploy our k8s cluster on Amazon EC2 instances.
While launching the
EC2 instance, select
Ubuntu Server 16.04 LTS as the Machine Image.
Select type of instance as
t2.medium because kubeadm needs 2 or more CPUs as well as minimum 2 GB RAM.
Enter the number of instances required.
Inbound rules to the instances respectively.
- TCP Inbound 6443
- TCP Inbound 2379–2380
- TCP Inbound 10250
- TCP Inbound 10251
- TCP Inbound 10252
- TCP Inbound -10250
- TCP Inbound 30000–32767
Install Docker on the instances
From Docker’s repositories for Ubuntu:
apt-get updateapt-get install -y apt-transport-https ca-certificates curl software-properties-commoncurl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -add-apt-repository “deb https://download.docker.com/linux/$(. /etc/os-release; echo “$ID”) $(lsb_release -cs) stable”apt-get update apt-get install -y docker-ce
Installing kubeadm, kubelet and kubectl on the instances
apt-get update && apt-get install -y apt-transport-https curlcurl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOFapt-get updateapt-get install -y kubelet kubeadm kubectlapt-mark hold kubelet kubeadm kubectl
Configure cgroup driver used by kubelet on Master Node
When using Docker, kubeadm will automatically detect the cgroup driver for the kubelet and set it in the
/var/lib/kubelet/kubeadm-flags.env file during runtime.
If you are using a different CRI, you have to modify the file
/etc/default/kubelet with your cgroup-driver value, like so:
KUBELET_KUBEADM_EXTRA_ARGS= — cgroup-driver=<value>
Restarting the kubelet is required:
systemctl daemon-reloadsystemctl restart kubelet
Please bear in mind, that you only have to do that if the cgroup driver of your CRI is not cgroupfs.
Initializing your master
The master is the machine where the control plane components run, including
etcd (the cluster database) and the
API server (which the kubectl CLI communicates with).
We have to install a pod network so that our pods can communicate with each other. Kubeadm only supports Container Network Interface (CNI) based networks.
We use Calico as our pod network add-on and install it using following commands
kubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/rbac-kdd.yamlkubectl apply -f https://docs.projectcalico.org/v3.1/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
kubeadm init — kubernetes-version=1.11.0 — apiserver-advertise-address=<master_ip-address> — pod-network-cidr=192.168.0.0/16
Installs specified version of k8s and uses the network interface to advertise the master’s IP.
kubeadm init first runs a series of prechecks to ensure that the machine is ready to run Kubernetes. These prechecks expose warnings and exit on errors. It then downloads and installs the cluster control plane components.
To make kubectl work for your non-root user, run these commands
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
Make a record of the
kubeadm init command’s output. You need this command to join the worker nodes to your cluster.
Joining worker nodes
Nodes are where your workloads (containers and pods, etc) run.
Run the following commands on each worker machine by first SSH-ing into it and become root
kubeadm join — token <token> <master-ip>:<master-port> — discovery-token-ca-cert-hash sha256:<hash>
(This command is the output of the
kubeadm init command run on the master node)
To undo what kubeadm did, you should first drain the node and make sure that the node is empty before shutting it down.
On the master run:
kubectl drain <node name> — delete-local-data — force — ignore-daemonsetskubectl delete node <node name>
Then, on the node being removed, reset all kubeadm installed state:
Now you can start over by simply running
kubeadm init again.
That’s it folks. You now have your first k8s cluster deployed using kubeadm :) In the next post, we will be creating Highly Available clusters with kubeadm.