The Ultimate Kubernetes Cluster Setup Guide: A Comprehensive, Step-by-Step Production Deployment Tutorial
Introduction to Kubernetes and Cluster Architecture
In the era of modern cloud-native software development, containerization has completely transformed how applications are built, packaged, and deployed. While containers solve the "it works on my machine" problem, managing hundreds or thousands of containers across multiple servers introduces complex challenges like scaling, network routing, high availability, and self-healing.
This is where Kubernetes (K8s) comes into play. Originally designed by Google and now maintained by the Cloud Native Computing Foundation (CNCF), Kubernetes is an open-source container orchestration engine that automates the deployment, scaling, management, and networking of containerized applications.
To successfully build a Kubernetes cluster, it is crucial to first understand its architecture, which relies on a master-worker topology.
![]() |
| The Ultimate Kubernetes Cluster Setup Guide: A Comprehensive, Step-by-Step Production Deployment Tutorial |
+-------------------------------------------------------+
| Control Plane (Master) |
| |
| +---------------+ +---------------------------+ |
| | kube-apiserver | | kube-scheduler | |
| +-------+-------+ +-------------+-------------+ |
| | | |
| v v |
| +-------+-------+ +-------------+-------------+ |
| | etcd | | kube-controller-manager | |
| +---------------+ +---------------------------+ |
+-----------------------------------+-------------------+
|
+------------------------+------------------------+
| |
v v
+-----------------------------------+ +-----------------------------------+
| Worker Node 1 | | Worker Node 2 |
| | | |
| +---------+ +---------+ +-----+ | | +---------+ +---------+ +-----+ |
| | kubelet | | k-proxy | | CRI | | | | kubelet | | k-proxy | | CRI | |
| +---------+ +---------+ +-----+ | | +---------+ +---------+ +-----+ |
| | | |
| +-------+ +-------+ | | +-------+ +-------+ |
| | Pod A | | Pod B | | | | Pod C | | Pod D | |
| +-------+ +-------+ | | +-------+ +-------+ |
+-----------------------------------+ +-----------------------------------+
1. The Control Plane (Master Node)
The control plane is the brains of the cluster. It makes global decisions about the cluster (such as scheduling applications), detects cluster events, and responds to them. Its core components include:
kube-apiserver: The exposure point for the Kubernetes API. It acts as the front end for the control plane, handling all internal and external REST requests.
etcd: A highly available, distributed key-value store used to hold all cluster data, state configuration, and secrets.
kube-scheduler: The component that watches for newly created Pods with no assigned node, and selects a healthy worker node for them to run on based on resource requirements.
kube-controller-manager: A daemon that runs distinct controller processes to regulate the state of the cluster (e.g., Node Controller, Replication Controller, EndpointSlice Controller).
2. The Worker Nodes
Worker nodes host the actual applications running inside container slots called Pods. Every worker node must run specific services to communicate with the control plane:
kubelet: An agent running on each node that ensures containers are running inside their designated Pods according to the specifications provided by the control plane.
kube-proxy: A network proxy running on each node that maintains network rules, allowing network communication to Pods from inside or outside the cluster.
Container Runtime Interface (CRI): The software responsible for running containers. While Docker was historically used, modern Kubernetes clusters utilize lightweight, dedicated CRIs like containerd or CRI-O.
Section 1: Environment Planning and System Prerequisites
Before executing commands, you must plan your infrastructure carefully to prevent system resource bottlenecks, network conflicts, or authentication failures during setup.
1. Hardware Resource Requirements
For a standard production-ready or evaluation cluster running via kubeadm, ensure your virtual or physical servers meet these minimum specifications:
| Node Type | Minimum vCPUs | Minimum RAM | Storage Space | Operating System |
|---|---|---|---|---|
| (Control Plane (Master) | 2 Cores | 2 GB (4 GB Recommended) | 20 GB+ SSD | Ubuntu 22.04 / 24.04 LTS) |
| (Worker Node(s) | 2 Cores | 2 GB (4 GB+ Recommended) | 20 GB+ SSD | Ubuntu 22.04 / 24.04 LTS) |
2. Network Infrastructure and IP Allocation
For this guide, we will configure a three-node cluster architecture using static IP addresses. You must ensure that none of the host subnets overlap with the internal Kubernetes Pod network or Service network subnets.
Master Node IP: 192.168.10.10 (Hostname: k8s-master)
Worker Node 1 IP: 192.168.10.11 (Hostname: k8s-worker1)
Worker Node 2 IP: 192.168.10.12 (Hostname: k8s-worker2)
Pod Network CIDR Block: 10.244.0.0/16 (Used by the Flannel/Calico network overlay)
Section 2: Step-by-Step OS Preparation (All Nodes)
These steps must be rigorously executed on all server-both the master and worker nodes-prior to initializing Kubernetes.
Step 1: Update the OS Packages
Log into your servers via SSH and synchronize your package indices to update the OS to its latest patch levels.
bash
sudo apt-get update && sudo apt-get upgrade -y
Step 2: Set Uniform Hostnames
Set individual hostnames on each respective machine so they can cleanly identify each other within the cluster logs.
On the Master Node:
bash
sudo hostnamectl set-hostname k8s-master
On Worker Node 1:
bash
sudo hostnamectl set-hostname k8s-worker1
On Worker Node 2:
bash
sudo hostnamectl set-hostname k8s-worker2
Step 3: Configure Local DNS Entries (/etc/hosts)
Edit the hosts file on every node to enable local name resolution independent of an external DNS server.
bash
sudo nano /etc/hosts
Add the following text block at the bottom of the file:
text
192.168.10.10 k8s-master
192.168.10.11 k8s-worker1
192.168.10.12 k8s-worker2
Step 4: Disable Swap Space Permanently
Kubernetes requires that swap memory be completely disabled. The kubelet's memory eviction logic relies on strict memory accounting; if memory swaps to disk, the scheduler cannot accurately track resource allocations, leading to instability.
bash
# Disable swap for the current session
sudo swapoff -a
# Prevent swap from re-enabling on system reboot
sudo sed -i '/swap/d' /etc/fstab
To verify that swap is fully disabled, run free -m. The entry for "Swap" should read all zeros:
text
total used free shared buff/cache available
Mem: 3932 840 1200 12 1892 2810
Swap: 0 0 0
Step 5: Load Mandatory Kernel Modules
Kubernetes network overlays require specific Linux kernel subsystems to handle bridge traffic and network address translation (NAT).
bash
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# Manually trigger module loading for the active session
sudo modprobe overlay
sudo modprobe br_netfilter
Step 6: Configure Sysctl Networking Parameters
We must ensure that network traffic traversing network bridges is passed systematically to iptables for filtering and routing.
bash
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# Apply the parameters instantly without system reboot
sudo sysctl --system
Section 3: Container Runtime Installation (containerd)
Since Kubernetes deprecated native Docker support via the dockershim, containerd has emerged as an industry-standard, lightweight, secure, and fully compliant container runtime.
Step 1: Install Dependencies and GPG Keys
bash
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
### Step 2: Configure the Containerd Repository
bash
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y containerd.io
Step 3: Configure the Systemd cgroup Driver
By default, containerd generates standard configuration settings that do not use systemd as the cgroup driver. For production stability, both the container runtime and the Kubernetes kubelet must use the same control group (cgroup) driver engine (systemd).
```bash
# Generate default configuration directory and file
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/etc/containerd/config.toml >/dev/null
# Modify the configuration file to explicitly set SystemdCgroup to true
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
Step 4: Restart and Enable the Containerd Service
bash
sudo systemctl restart containerd
sudo systemctl enable containerd
## Section 4: Installing Kubernetes CLI Tools (kubeadm, kubelet, kubectl)
You need to install three essential command-line packages across all nodes:
kubeadm: The bootstrapping tool used to initialize clusters and join nodes.
kubelet:** The primary worker component that manages container execution.
kubectl:** The command-line client used to send REST requests to the cluster.
Step 1: Download the Public GPG Signing Key
bash
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
(Note: Replace v1.30 in the URL with your desired target version if upgrading to a newer stable version release).
Step 2: Add the Kubernetes Repository to Apt
bash
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
Step 3: Install the Packages
bash
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
Step 4: Pin Package Versions
To prevent accidental, uncoordinated cluster updates during standard system maintenance (apt upgrade), you must pin the Kubernetes software packages to their current versions:
bash
sudo apt-mark hold kubelet kubeadm kubectl
Section 5: Initializing the Control Plane (Master Node Only)
This step must be run exclusively on the machine designated as the cluster master (k8s-master).
Step 1: Pre-Pull Container Images
Before initializing, force kubeadm to download all necessary system components (like kube-apiserver, etcd, and coredns) from the registry:
bash
sudo kubeadm config images pull
Step 2: Run Kubeadm Init
Initialize the cluster by specifying the master API server IP address and matching the target network CIDR block that your internal pod network plugin expects.
bash
sudo kubeadm init \
--apiserver-advertise-address=192.168.10.10 \
--pod-network-cidr=10.244.0.0/16
Understanding the Output
Once initialization completes successfully, you will see a detailed confirmation message containing critical instructions. Do not close your terminal windows yet.
text
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.10.10:6443 --token abcdef.1234567890abcdef \
--discovery-token-ca-cert-hash sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Step 3: Configure Non-Root Cluster Management Access
To allow your normal user account to execute administrative operations via kubectl, copy the security access configuration profiles into your user home directory:
bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Section 6: Deploying the Cluster Networking Overlay (CNI)
At this point, the master node is online, but all cluster services will remain in a NotReady status. This occurs because the cluster has no unified physical or virtual data plane established to link containers on different nodes.
We will install Flannel, a highly stable, lightweight Virtual Extensible LAN (VXLAN) network layer configuration.
Step 1: Apply the Network Overlay Configuration
On the master node, execute kubectl to pull and run the Flannel deployment manifests directly from its official repository:
bash
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Step 2: Verify Control Plane Initialization
Wait approximately 60 seconds, then check the structural readiness of your master node components:
bash
kubectl get nodes
Expected Output:
text
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 3m v1.30.0
Verify that all critical internal system pods are functioning correctly:
bash
kubectl get pods -n kube-system
Ensure that status variables for coredns, kube-apiserver, etcd, and kube-proxy display Running.
Section 7: Joining Worker Nodes to the Cluster
With the master control plane fully operational, you can now attach your worker nodes to expand your compute capacity.
Step 1: Execute the Join Command
Log into k8s-worker1 and k8s-worker2 via SSH. Paste the custom kubeadm join string generated at the end of your master initialization step:
bash
sudo kubeadm join 192.168.10.10:6443 --token abcdef.1234567890abcdef \
--discovery-token-ca-cert-hash sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Step 2: Troubleshooting Token Expiration (Optional)
If you join worker nodes at a later date, the default bootstrap tokens may have expired (they are valid for 24 hours). You can generate a fresh join token directly from the master node using:
bash
kubeadm token create --print-join-command
Step 3: Final Verification of Cluster Status
Return to the terminal on your Master Node and check the overall structural layout of the nodes:
bash
kubectl get nodes -o wide
Expected Output:
text
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE KERNEL-VERSION
k8s-master Ready control-plane 15m v1.30.0 192.168.10.10 Ubuntu 22.04.2 LTS 5.15.0-72-generic
k8s-worker1 Ready <none> 2m v1.30.0 192.168.10.11 Ubuntu 22.04.2 LTS 5.15.0-72-generic
k8s-worker2 Ready <none> 95s v1.30.0 192.168.10.12 Ubuntu 22.04.2 LTS 5.15.0-72-generic
Section 8: Testing and Validating the Cluster Deployment
To confirm your new Kubernetes cluster can successfully pull images, manage network traffic, and handle failures, you should run a test application deployment.
1. Create a Sample Nginx Deployment
We will deploy an Nginx web server deployment containing three replica pods distributed across our worker nodes.
bash
kubectl create deployment nginx-test-server --image=nginx --replicas=3
2. Verify Pod Distribution
Monitor the creation phase of the pods to see which worker nodes they are assigned to:
bash
kubectl get pods -o wide
Expected Output:
text
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
nginx-test-server-587cdc6865-2bcms 1/1 Running 0 45s 10.244.1.2 k8s-worker1 <none>
nginx-test-server-587cdc6865-7nmlq 1/1 Running 0 45s 10.244.2.2 k8s-worker2 <none>
nginx-test-server-587cdc6865-z8v9p 1/1 Running 0 45s 10.244.1.3 k8s-worker1 <none>
3. Expose the Application via a NodePort Service
To access these pods from outside the internal network, create a Kubernetes service tracking asset that maps a host-level port across all cluster nodes to the web server's internal port 80.
bash
kubectl expose deployment nginx-test-server --type=NodePort --port=80
4. Locate the Assigned External Port
Query your services to find the randomly assigned port within the standard Kubernetes NodePort range (30000–32767):
bash
kubectl get service nginx-test-server
Expected Output:
text
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-test-server NodePort 10.105.21.155 <none> 80:31245/TCP 12s
In this example, the assigned external port is 31245.
5. Access the Web Server External Endpoint
Open a web browser or run curl from any device capable of routing to your cluster nodes. Use any of your nodes' IP addresses along with the NodePort:
bash
curl http://192.168.10.11:31245
bash
curl http://192.168.10.12:31245
If you see the HTML output containing the "Welcome to nginx!" landing screen, your Kubernetes cluster networking, routing, pod scheduling, and runtimes are fully functional and production-ready.
Section 9: Advanced Cluster Production Configuration
For production environments, the basic setup should be extended with additional layers for storage management, external routing, and security boundaries.
1. Dynamic Storage Allocation (StorageClasses)
Out of the box, Kubernetes pods are ephemeral; any data written to a pod's local disk is lost if the pod restarts. For persistent workloads like databases (PostgreSQL, MySQL), you must configure a StorageClass tied to external persistent storage solutions such as NFS, Ceph, AWS EBS, or OpenEBS.
Example layout to deploy a simple Local Path Provisioner storage solution:
bash
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
Once installed, check your available storage classes:
bash
kubectl get sc
2. Ingress Controllers (Nginx Ingress)
While a NodePort service works well for testing, it is impractical for managing hundreds of production web APIs on arbitrary port ranges (e.g., :31245).
An Ingress Controller acts as an intelligent, high-performance reverse proxy that routes external traffic (on standard ports 80 and 443) to internal services based on the request's HTTP host header or URL path (e.g., api.example.com or [example.com/shop](https://example.com/shop)).
You can install the official Nginx Ingress Controller using the following command:
bash
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.0/deploy/static/provider/cloud/deploy.yaml
3. Cluster Security: Network Policies
By default, Kubernetes uses a flat network structure where every pod can communicate freely with every other pod across the entire cluster. In a production environment, this poses a security risk.
You can enforce network isolation using NetworkPolicies to restrict traffic between namespaces or specific application tiers.
Here is an example YAML policy configuration (network-policy.yaml) that blocks all incoming traffic to a database backend except from pods carrying the specific frontend application label:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: backend-security-policy
namespace: default
spec:
podSelector:
matchLabels:
app: database-backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend-webapp
ports:
- protocol: TCP
port: 5432
Apply this policy to your cluster using:
bash
kubectl apply -f network-policy.yaml
Section 10: Common Troubleshooting Frameworks
Even when following instructions closely, complex network configurations or hardware discrepancies can cause issues. Here are the standard procedures for identifying and fixing common errors.
1. Pods Stuck in Pending State
If you deploy an application and its pods remain in a Pending state, the scheduler cannot find a suitable node to run them on.
Root Cause: Often caused by insufficient CPU or memory resources across worker nodes, or master isolation controls preventing scheduling on the control plane.
Resolution Run: Inspect the scheduling lifecycle logs by running:
bash
kubectl describe pod <pod-name>
Look at the "Events" section at the bottom of the output to see the exact reason (e.g., `0/3 nodes are available: 3 Insufficient cpu`).
2. Pods Stuck in `CrashLoopBackOff`
This status indicates that a pod was successfully scheduled to a worker node, but its internal application container keeps crashing immediately after starting.
Root Cause: Incorrect application environment variables, broken container entrypoints, misconfigured internal file permissions, or database connection failures.
Resolution Run: Fetch the internal standard error stream from the crashing container:
bash
kubectl logs <pod-name> --previous
3. Worker Node Dropouts (NotReady Status)
If a worker node suddenly switches from a Ready to a NotReady state, it means the master control plane has lost contact with that node's local agent.
Root Cause: The kubelet daemon on the worker node has crashed, the server ran completely out of memory/disk space (DiskPressure/MemoryPressure), or a firewall is blocking the connection.
Resolution Run: SSH directly into the failing worker node and examine the operational state of the kubelet service:
bash
sudo systemctl status kubelet
To view active runtime errors, pull the system logs for the kubelet:
bash
sudo journalctl -u kubelet -f -n 100
Conclusion and Summary Checklist
Setting up a production-ready Kubernetes cluster from scratch using kubeadm provides deep visibility into how container workloads interact with networking components, operating system kernels, and compute resources. By standardizing your container runtimes on containerd and configuring uniform systemd cgroup management, you establish a highly stable foundation for running cloud-native applications.
As a final reference, here is a quick summary checklist of the deployment process:
1. Hardware & OS: Clear swap memory, configure your hosts file, and enable kernel modules (br_netfilter).
2. Container Runtime: Install containerd and explicitly set SystemdCgroup = true.
3. Kubernetes Tools: Install and pin identical versions of kubeadm, kubelet, and kubectl.
4. Initialization: Run kubeadm init with a dedicated network CIDR block on your master node.
5. Networking Overlay: Deploy a CNI plugin like Flannel or Calico to establish the pod network fabric.
6. Expansion: Run the generated kubeadm join tokens across your worker nodes.
7. Validation: Test your deployment with an Nginx application deployment and expose it via a NodePort service.
Hello If you love online shopping you can use the platforms listed below. All you need to do is click the blue (Click Here) button under each platform to open it. Please choose and use the shopping platform that interests you and that you trust or feel comfortable with.
1) Flipkart Online Shopping
2)Ajio Online Shopping
3) Myntra Online Shopping
4)Shopclues Online Shopping
5)Nykaa Online Shopping
6)Shopsy Online Shopping
best technical & earn money tips & cashback earning tips & mobile easy features website & apps using tips & helpful tips provider website.
Website Name = Areefulla The Technical Men
Website Url = https://www.areefulla.in
Share website link your friends or family members.
.jpg)

0 Comments