Creating Kubernetes Clusters with Kubeadm
Introduction
This tutorial guides you through creating a Kubernetes cluster using kubeadm. kubeadm simplifies the process of bootstrapping a minimal viable Kubernetes cluster. This tutorial assumes you have a basic understanding of Kubernetes concepts and access to at least two virtual machines (VMs) or physical machines, one for the master node and one or more for worker nodes. You will need ssh access to all machines.
Prerequisites:
- At least two machines (VMs or physical). One will be the master, and the others will be worker nodes.
- Each machine should have at least 2 CPUs and 2 GB of RAM.
- A stable network connection between all machines.
- Internet access for downloading packages.
- Root privileges on all machines.
- Familiarity with basic Linux commands.
Task 1: Preparing the Hosts
On all machines (master and worker nodes), perform the following steps:
-
Install Container Runtime (Containerd):
NODE_TYPE // bashsudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install -y containerdThis tutorial uses containerd as the container runtime. Docker can also be used. Ensure the chosen runtime is configured before proceeding.The above example is based on ubuntu. If you are using Debian use the following command: “curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg –dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg” -
Configure containerd:
NODE_TYPE // bashsudo mkdir -p /etc/containerd sudo containerd config default | sudo tee /etc/containerd/config.toml sudo systemctl restart containerd -
Disable Swap: Kubernetes requires swap to be disabled.
NODE_TYPE // bashsudo swapoff -a sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstabDisabling swap may affect system performance in memory-constrained environments. Ensure your machines have sufficient memory. -
Install kubeadm, kubelet, and kubectl:
NODE_TYPE // bashsudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | 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 kubectlkubeletis the agent that runs on each node.kubeadmis the tool for cluster bootstrapping.kubectlis the command-line tool for interacting with the Kubernetes cluster.apt-mark holdprevents these packages from being automatically updated.
Task 2: Initializing the Kubernetes Master Node
Perform these steps only on the machine designated as the master node.
-
Initialize the Kubernetes cluster:
NODE_TYPE // bashsudo kubeadm init --pod-network-cidr=10.244.0.0/16The--pod-network-cidrflag specifies the IP address range for pods. Choose a CIDR that doesn’t conflict with your existing network.Keep track of the
kubeadm joincommand output, you’ll need this to join the worker nodes later. It should look similar to:NODE_TYPE // outputkubeadm join <master-ip>:<master-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash> -
Configure
kubectl:NODE_TYPE // bashmkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/configThis allows you to use
kubectlas a non-root user. -
Install a Pod Network Add-on (Calico):
NODE_TYPE // bashkubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yamlA pod network add-on is required for pods to communicate with each other. Calico is a popular option. Other options include Flannel, Weave Net, and Cilium.Wait for all pods to be in the
Runningstate. This may take a few minutes.NODE_TYPE // bashkubectl get pods --all-namespaces
Task 3: Joining Worker Nodes
Perform these steps on each machine designated as a worker node.
-
Join the cluster:
Use the
kubeadm joincommand that was output during thekubeadm initstep on the master node. Replace<master-ip>:<master-port>,<token>, and<hash>with the actual values.NODE_TYPE // bashsudo kubeadm join <master-ip>:<master-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>If you lost thekubeadm joincommand, you can regenerate the token on the master node usingkubeadm token create --print-join-command.
Task 4: Verifying the Cluster
Back on the master node, verify that the worker nodes have joined the cluster.
-
Check node status:
NODE_TYPE // bashkubectl get nodesYou should see all your nodes listed, with their status as
Ready.NODE_TYPE // outputNAME STATUS ROLES AGE VERSION master-node Ready control-plane,master 10m v1.27.2 worker-node1 Ready <none> 5m v1.27.2 worker-node2 Ready <none> 5m v1.27.2
Task 5: Deploying a Sample Application
-
Create a deployment:
NODE_TYPE // bashkubectl create deployment nginx --image=nginx -
Expose the deployment:
NODE_TYPE // bashkubectl expose deployment nginx --port=80 --type=NodePort -
Get the service information:
NODE_TYPE // bashkubectl get service nginxLook for the
NodePort.NODE_TYPE // outputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx NodePort 10.100.1.100 <none> 80:30000/TCP 1m -
Access the application:
Open a web browser and navigate to
http://<worker-node-ip>:<node-port>(replace<worker-node-ip>with the IP address of one of your worker nodes and<node-port>with the NodePort obtained in the previous step). You should see the default Nginx welcome page.
Conclusion
You have successfully created a Kubernetes cluster using kubeadm, joined worker nodes, and deployed a sample application. Key takeaways from this tutorial include:
kubeadmsimplifies Kubernetes cluster bootstrapping.- A container runtime (like containerd) is required.
- A pod network add-on (like Calico) is necessary for pod communication.
kubectlis the primary tool for interacting with the cluster.