What is a K8s Cluster?
A Kubernetes (K8s) cluster is not a homogeneous collection of machines. Instead, it consists of a control plane and multiple worker nodes that function as a unified system. This architecture is why we call it a "cluster" - it's a collection of connected computing resources working together.
Important distinctions:
It's not a "cluster of containers" - containers are what run on the cluster
It is a "cluster of machines/VPS/VMs" - these form the physical/virtual infrastructure
Cluster Components
Control Plane
The control plane is the brain of the Kubernetes cluster, responsible for maintaining the desired state of the cluster. It includes:
API Server: The frontend of the control plane
etcd: The cluster's database and source of truth
Scheduler: Assigns pods to nodes
Controller Manager: Manages various controllers
Worker Nodes
Worker nodes are the machines where your containers actually run. Each worker node includes:
Kubelet: Ensures containers are running in pods
Kube-proxy: Maintains network rules
Container Runtime: Software for running containers (Docker, containerd, etc.)
Pod Architecture
In Kubernetes, the pod is the smallest deployable unit (SDU). A pod represents one or more containers that:
Share the same network namespace (IP address and port space)
Share the same storage/volumes
Are scheduled together on the same node
Container Relationship
One pod can contain one or multiple containers
Most commonly, a pod contains just a single container
Containers within a pod are always co-located and co-scheduled
Deployment Patterns
Example Scenario
Let's consider a scenario with Traefik as an ingress controller, a Python ML service, and a Node.js web service.
Option 1: Multi-container Pod Approach
You could put Traefik, the Python ML service, and the Node.js web service all in a single pod. This makes sense if:
These services always need to be deployed together
They need to communicate via localhost
They share a lifecycle (start/stop together)
Option 2: Typical Kubernetes Approach
More commonly, you'd structure this as:
A Traefik pod (as a DaemonSet or Deployment)
A Python ML service pod (as a Deployment)
A Node.js web service pod (as a Deployment)
This separation provides flexibility to:
Scale each component independently
Update each component separately
Have different resource allocations for each service
The Sidecar Pattern
A common multi-container pod use case is the sidecar pattern:
Main container: Your primary application (e.g., Python ML service)
Sidecar container: A helper container (e.g., logging or monitoring)
DaemonSets vs Deployments
DaemonSet
Ensures a copy of a pod runs on every node in the cluster
Exactly one pod per node
Automatically adds pods to new nodes
Used for cluster-wide services like:
Node monitoring agents
Log collectors
Network plugins
Storage daemons
Deployment
Manages a set of identical pods (replicas)
Pods are distributed across nodes based on available resources
You specify the desired replica count
Handles rolling updates and rollbacks
Used for stateless applications that can be scaled horizontally
When to Use Which
Ask yourself: "Do I need exactly one instance of this service on every node in my cluster?"
If yes, use a DaemonSet
If no, use a Deployment
Mental Model Summary
The cluster consists of physical/virtual machines (nodes)
Nodes run pods
Pods contain Docker/OCI containers
This hierarchical structure allows Kubernetes to efficiently manage containerized applications at scale while providing flexibility in deployment strategies.