Introduction

This guide provides instructions for setting up a Kubernetes cluster on Ubuntu using $kubeadm$.

Prerequisites

One or more machines running Ubuntu 18.04 or later
Each machine has at least:
2 CPUs
2GB RAM
Network connectivity between machines
Root privileges on each machine

Comprehensive Guide to Setting Up a Kubernetes Cluster Using Kubeadm

Step 1: Install Docker

Kubernetes requires a container runtime, and Docker is a popular choice. Install Docker on each node:

sudo apt-get update
sudo apt-get install -y docker.io

Step 2: Install Kubeadm, Kubelet, and Kubectl

You will install these packages on all of your machines:

sudo apt-get update
sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

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

Step 3: Initialize Your Cluster

On the master node, initialize the cluster:

sudo kubeadm init

Kubernetes control-plane has initialized successfully:

......
[kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

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

kubeadm join 192.168.218.12:6443 --token 81n1ak.ozgrdyuuk1oa7b99 \
	--discovery-token-ca-cert-hash sha256:b08f7cdd57b3f40c456c293f6479b5523801f2632d95c2729d476e54e6f17790 

Note: If you are using a single-node cluster, after initializing the cluster, you need to allow workloads to be scheduled on the master node:

kubectl taint nodes --all node-role.kubernetes.io/master-

Step 4: Set Up kubectl for the Root User

To start using your cluster as root:

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

Step 5: Install a Pod Network

A pod network is necessary for pods to communicate with each other. Apply a CNI (Container Network Interface) plugin:

kubectl apply -f [pod network add-on yaml]

Replace $[pod network add-on yaml]$ with the network manifest for your chosen network solution.

Step 6: Join Worker Nodes

To join your worker nodes to the cluster, use the token generated by $kubeadm init$. On each worker node:

sudo kubeadm join [your-master-ip]:6443 --token [your-token] --discovery-token-ca-cert-hash sha256:[your-hash]

Replace $[your-master-ip]$, $[your-token]$, and $[your-hash]$ with the values provided by the $kubeadm init$ output on your master node.

Conclusion

After completing these steps, you should have a functioning Kubernetes cluster. Use $kubectl get nodes$ on the master node to see the status of your nodes.

Note: The installation process may vary based on Kubernetes and Ubuntu versions. Always refer to the official Kubernetes documentation for the most up-to-date instructions.

Troubleshooting

During the Kubernetes setup process, you might encounter various issues that prevent the initialization of the cluster. This section covers some common issues and their solutions.

Issue 1: Error [ERROR FileAvailable--etc-kubernetes-manifests-etcd.yaml]

Solution:
Remove existing manifest files:

sudo rm /etc/kubernetes/manifests/*.yaml

Issue 2: Error [kubelet-check] The HTTP call equal to 'curl -sSL http://localhost:10248/healthz' failed with error

Solution:
Restart the kubelet service:

sudo systemctl restart kubelet

Issue 3: Error [ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables] and [ERROR FileContent--proc-sys-net-ipv4-ip_forward]

Solution:
Load the br_netfilter module and configure sysctl:

sudo modprobe br_netfilter
echo "net.bridge.bridge-nf-call-iptables = 1" | sudo tee /etc/sysctl.d/k8s-network.conf
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.d/k8s-network.conf
sudo sysctl --system
cat /proc/sys/net/bridge/bridge-nf-call-iptables
cat /proc/sys/net/ipv4/ip_forward

Persist the br_netfilter module across reboots:

echo "br_netfilter" | sudo tee /etc/modules-load.d/br_netfilter.conf

Issue 4: Error failed to run Kubelet: running with swap on is not supported

Solution:
The command sudo swapoff -a is used to disable swap immediately, but this change will not persist across reboots.

sudo swapoff -a

To ensure that swap remains off after a reboot, you need to create a systemd service file disable-swap.service. This file specifies that the swapoff command should be run at boot time.

cat <<EOF | sudo tee /etc/systemd/system/disable-swap.service
[Unit]
Description=Disable swap

[Service]
ExecStart=/sbin/swapoff -a
RemainAfterExit=true
Type=oneshot

[Install]
WantedBy=multi-user.target
EOF

After creating the service file, you need to enable the service so that it starts on boot, and then start the service immediately.

sudo systemctl enable disable-swap.service
sudo systemctl start disable-swap.service

Issue 5: Error [ERROR Port-10250]: Port 10250 is in use

Solution:
Restart the kubelet service:

sudo systemctl restart kubelet

Issue 6: Error [ERROR DirAvailable--var-lib-etcd]: /var/lib/etcd is not empty

Solution:
Remove existing files under /var/lib/etcd:

sudo rm -rf /var/lib/etcd/*

Issue 7: –ignore-preflight-errors

If you are sure about what you are doing, you can bypass certain preflight errors using the --ignore-preflight-errors flag with kubeadm init:

sudo kubeadm init --ignore-preflight-errors=DirAvailable--var-lib-etcd