TL;DR (Quick Summary)#
- Control Plane vs Worker Node: The Control Plane makes cluster decisions, tracks state in
etcd, and schedules workloads. Worker Nodes execute containers via container runtimes (containerd/Docker) andkubelet. - Kind (Kubernetes in Docker): Runs Kubernetes nodes as Docker containers on your local laptop, enabling production-like multi-node topology without cloud VM costs.
- The API Server: Port
6443on the Control Plane node receives allkubectlrequests via REST endpoints. - Multi-Node Setup: Use a
kind-config.yamlmanifest to define 1 Control Plane and 2 Worker Nodes in under 2 minutes.
1. Understanding Basic Kubernetes Architecture#
Before typing your first command, you must understand the core architecture of a Kubernetes cluster.
A production Kubernetes cluster is split into two distinct planes:
graph TD
Client["kubectl CLI"] -->|HTTPS REST API :6443| APIServer["kube-apiserver"]
subgraph ControlPlane ["Control Plane"]
APIServer <--> ETCD["(etcd Database)"]
APIServer <--> Scheduler["kube-scheduler"]
APIServer <--> Controller["kube-controller-manager"]
end
subgraph WorkerNode1 ["Worker Node 1"]
Kubelet1["kubelet"] <--> APIServer
Kubelet1 <--> Containerd1["containerd / CRI"]
KubeProxy1["kube-proxy"]
end
subgraph WorkerNode2 ["Worker Node 2"]
Kubelet2["kubelet"] <--> APIServer
Kubelet2 <--> Containerd2["containerd / CRI"]
KubeProxy2["kube-proxy"]
end
Control Plane Components (The Brain)#
kube-apiserver: The central communication hub. Exposes the Kubernetes REST API (default port6443). Every tool (includingkubectl) interacts directly withkube-apiserver.etcd: A highly available, consistent key-value store used as Kubernetes’ backing store for all cluster data (state, secrets, configs).kube-scheduler: Watches for newly created Pods with no assigned node, and selects a node for them to run on based on resource requirements.kube-controller-manager: Runs controller processes in the background (Node Controller, ReplicaSet Controller, EndpointSlice Controller) to maintain the desired state of the cluster.
Worker Node Components (The Execution Engine)#
kubelet: An agent that runs on each node in the cluster. It makes sure that containers described in PodSpecs are running and healthy.kube-proxy: A network proxy that runs on each node, maintaining network rules (usingiptablesorIPVS) to allow network communication to your Pods from inside or outside of your cluster.- Container Runtime (
containerd/CRI-O): The software responsible for running containers.
2. Comparison: Control Plane vs Worker Node#
| Feature | Control Plane | Worker Node |
|---|---|---|
| Primary Goal | Cluster management & state tracking. | Application workload execution. |
| Key Services | kube-apiserver, etcd, kube-scheduler, kube-controller-manager. | kubelet, kube-proxy, containerd. |
| User Access | Receives REST API calls on port 6443. | Usually isolated behind Ingress or Load Balancers. |
| Failure Impact | Cluster management freezes (existing workloads continue running). | Workloads on the failed node are rescheduled to healthy nodes. |
3. System Prerequisites#
To follow along with this tutorial, ensure your system (Linux, macOS, or Windows WSL2) has the following software installed:
Step 1: Installing Docker#
Kind requires the Docker engine to run Kubernetes “nodes”.
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io -y
sudo systemctl enable --now docker
sudo usermod -aG docker $USER(Note: Log out and log back in to activate the Docker group).
Step 2: Installing kubectl#
kubectl is the primary CLI tool you will use to issue commands to the Kubernetes Control Plane.
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/Verify the installation:
kubectl version --clientStep 3: Installing Kind (Kubernetes in Docker)#
# Download Kind binary
[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind4. Building Your First Multi-Node Cluster#
By default, the kind create cluster command will only provision 1 node (acting as both the Control Plane and Worker simultaneously).
However, since we want to simulate a production-grade environment, we will provision a cluster with 1 Control Plane and 2 Worker Nodes.
Step 4.1: Creating the Kind Configuration File#
Create a file named kind-config.yaml and populate it with the following configuration:
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: workerTip: The configuration above instructs Kind to pull a specialized Docker image containing the complete Kubernetes components, and then boot up 3 isolated containers.
Step 4.2: Executing Cluster Creation#
Run this command in the same directory as your configuration file:
kind create cluster --name k8s-lab --config kind-config.yamlExpected Terminal Output:
Creating cluster "k8s-lab" ...
β Ensuring node image (kindest/node:v1.27.3) πΌ
β Preparing nodes π¦ π¦ π¦
β Writing configuration π
β Starting control-plane πΉοΈ
β Installing CNI π
β Installing StorageClass πΎ
β Joining worker nodes π
Set kubectl context to "kind-k8s-lab"
You can now use your cluster with:
kubectl cluster-info --context kind-k8s-lab5. Verification and Cluster Testing#
You now have a living, breathing Kubernetes cluster inside your laptop. Let’s ensure everything is running nominally.
Checking Node Status#
This command asks the Control Plane: “List all connected nodes and their current status.”
kubectl get nodes -o wideExpected Terminal Output:
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-lab-control-plane Ready control-plane 2m45s v1.27.3 172.18.0.4 Ubuntu 22.04 5.15.0-88-generic containerd://1.7.1
k8s-lab-worker Ready <none> 2m21s v1.27.3 172.18.0.3 Ubuntu 22.04 5.15.0-88-generic containerd://1.7.1
k8s-lab-worker2 Ready <none> 2m21s v1.27.3 172.18.0.2 Ubuntu 22.04 5.15.0-88-generic containerd://1.7.1Notice that the status is Ready. This implies the Control Plane has successfully established communication with both Worker Nodes.
Peeking Behind the Curtain (Docker)#
Because we are utilizing Kind, every “Node” is actually just a Docker container. Let’s prove it:
docker psExpected Terminal Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4e5f6g7h8i9 kindest/node:v1.27.3 "/usr/local/bin/entrβ¦" 3 minutes ago Up 3 minutes k8s-lab-worker
a1b2c3d4e5f6 kindest/node:v1.27.3 "/usr/local/bin/entrβ¦" 3 minutes ago Up 3 minutes k8s-lab-worker2
9z8y7x6w5v4u kindest/node:v1.27.3 "/usr/local/bin/entrβ¦" 3 minutes ago Up 3 minutes 127.0.0.1:45678->6443/tcp k8s-lab-control-planeDo you see port 6443 on the control-plane container? That is the Kubernetes API Server port. The kubectl commands you type from your terminal are actually sending HTTP Requests to that exact port!
6. Troubleshooting & Common Errors#
Error 1: docker: permission denied while trying to connect to the Docker daemon socket#
The Cause: Your current Linux user is not in the docker group.
The Fix:
sudo usermod -aG docker $USER
newgrp dockerError 2: kind create cluster hangs or times out#
The Cause: Insufficient memory or disk space allocated to Docker daemon. Kind requires at least 4GB of RAM allocated to Docker. The Fix: Increase Docker RAM allocation in Docker Desktop settings, or clean up unused Docker containers and images:
docker system prune -a --volumes7. Tearing Down the Cluster (Optional)#
If you wish to power down this lab and reclaim your RAM, you can destroy it just as easily as you created it:
kind delete cluster --name k8s-labThis command will permanently delete all configurations, state, and applications running inside the cluster.
Summary & Next Steps#
In this episode:
- We dissected the Kubernetes architecture into Control Plane and Worker Node components.
- We built a 3-node local Kubernetes cluster using Kind and Docker.
- We verified node connectivity via
kubectl get nodes -o wide. - We traced
kubectlcalls directly to port 6443 of the API Server.
In Episode 2: Pods and Deployments, we will deploy our first application, inspect container lifecycles, and explore self-healing deployment logic!

