| |

LFCE 137 🐧 Kubernetes — Nodes and Control Plane

⏱️ Estimated read: 9 min | |

A Kubernetes cluster is a set of machines divided into two roles. The control plane makes global decisions about the cluster—scheduling Pods, detecting node failures, responding to events—and stores the desired state. The worker nodes run the application workloads. Every cluster needs at least one worker node to run Pods, and the control plane manages both the nodes and the Pods on them . In production, the control plane usually runs across multiple computers for fault tolerance, and the cluster usually runs multiple worker nodes for capacity and availability .

This chapter covers the components on each side of that division: the five control plane components and their individual responsibilities, the three components that run on every worker node, and the commands that verify each component is healthy. It also covers the scheduling boundary—what the control plane decides and what the node executes—and the failure modes that occur when one side is unhealthy.

Key point: The control plane does not run application containers. It runs the components that decide where containers should run. The worker nodes run the containers. A Pod is always tied to the node where it was scheduled, and remains there until termination or deletion .


Why the division exists

The global decision problem. Scheduling a Pod requires knowledge of every node’s available resources, the Pod’s requirements, and the cluster’s constraints. A single node cannot make that decision correctly because it does not see the other nodes. The control plane’s scheduler sees the entire cluster and assigns each Pod to a node that satisfies its requirements .

The execution problem. Once a Pod is assigned to a node, the node must start the containers, monitor their health, and report status back to the control plane. The control plane does not reach into the node to start processes; it sends the Pod specification to the node’s kubelet, and the kubelet carries out the instructions .

The failure isolation problem. If a worker node fails, the control plane notices and reschedules the Pods onto other available nodes . If a control plane component fails, the worker nodes continue running their existing Pods, but new scheduling decisions cannot be made until the control plane recovers. The two sides have different failure modes and different recovery paths.


a. The control plane components

The control plane components make global decisions about the cluster and detect and respond to cluster events. They can run on any machine in the cluster, but setup scripts typically start them on dedicated machines that do not run user containers .

The kube-apiserver is the front end of the control plane. It exposes the Kubernetes HTTP API, and every interaction with the cluster—kubectl, the scheduler, the controller manager, the kubelets—goes through it. It is designed to scale horizontally by deploying more instances and balancing traffic between them .

The etcd is a consistent and highly available key-value store used as the backing store for all cluster data. If the cluster uses etcd as its backing store, a backup plan for the data is mandatory .

The kube-scheduler watches for newly created Pods with no assigned node and selects a node for them to run on. The scheduling decision considers individual and collective resource requirements, hardware and software constraints, affinity and anti-affinity specifications, data locality, inter-workload interference, and deadlines .

The kube-controller-manager runs the controller processes. Logically each controller is a separate process, but they are compiled into a single binary and run in a single process to reduce complexity. Examples include the Node controller (notices when nodes go down), the Job controller (creates Pods for one-off tasks), the EndpointSlice controller (links Services to Pods), and the ServiceAccount controller (creates default ServiceAccounts for new namespaces) .

The cloud-controller-manager embeds cloud-specific control logic and links the cluster to the cloud provider’s API. It runs only the controllers that are specific to the cloud provider. A self-hosted cluster or a learning environment does not have one .


b. The node components

Node components run on every worker node, maintaining the running Pods and providing the Kubernetes runtime environment .

The kubelet is the primary node agent. It ensures that Pods and their containers are running. It receives Pod specifications from the API server and manages the containers on the machine .

The kube-proxy is optional. It maintains network rules on nodes to implement Services. Some network plugins provide their own third-party implementation of proxying, and when that kind of plugin is used, the node does not need to run kube-proxy .

The container runtime is the software responsible for running containers. It pulls the container image from a registry, unpacks the container, and runs the application .


Complete Example Session

# ============================================
# PART 1: LIST THE NODES
# ============================================
kubectl get nodes

# NAME       STATUS   ROLES           AGE   VERSION
# master     Ready    control-plane   10d   v1.34.0
# worker-1   Ready    <none>          10d   v1.34.0
# worker-2   Ready    <none>          10d   v1.34.0
# ============================================
# PART 2: CHECK CONTROL PLANE HEALTH
# ============================================
kubectl get componentstatuses

# NAME                 STATUS    MESSAGE   ERROR
# scheduler            Healthy   ok
# controller-manager   Healthy   ok
# etcd-0               Healthy   ok
# ============================================
# PART 3: CHECK CONTROL PLANE PODS
# ============================================
kubectl get pods -n kube-system

# kube-apiserver-master          1/1   Running
# kube-controller-manager-master 1/1   Running
# kube-scheduler-master          1/1   Running
# etcd-master                    1/1   Running
# coredns-...                    1/1   Running
# kube-proxy-...                 1/1   Running
# ============================================
# PART 4: CHECK THE API SERVER
# ============================================
kubectl cluster-info

# Kubernetes control plane is running at https://10.0.0.1:6443
# ============================================
# PART 5: CHECK THE SCHEDULER
# ============================================
kubectl get pods -n kube-system -l component=kube-scheduler

# kube-scheduler-master   1/1   Running
# ============================================
# PART 6: CHECK THE CONTROLLER MANAGER
# ============================================
kubectl get pods -n kube-system -l component=kube-controller-manager

# kube-controller-manager-master   1/1   Running
# ============================================
# PART 7: CHECK ETCD
# ============================================
kubectl get pods -n kube-system -l component=etcd

# etcd-master   1/1   Running
# ============================================
# PART 8: CHECK THE KUBELET ON A NODE
# ============================================
# On the node itself:
systemctl status kubelet

# Active: active (running)
# ============================================
# PART 9: CHECK KUBE-PROXY
# ============================================
kubectl get pods -n kube-system -l k8s-app=kube-proxy

# kube-proxy-xxxxx   1/1   Running
# ============================================
# PART 10: CHECK THE CONTAINER RUNTIME
# ============================================
# On the node itself:
crictl info | grep -i runtimeType

# "runtimeType": "containerd"

The ten parts covered node listing, component statuses, control plane Pods, the API server, the scheduler, the controller manager, etcd, the kubelet, kube-proxy, and the container runtime.


Quick Reference

Control plane components

ComponentResponsibility
kube-apiserverExposes the Kubernetes API, front end
etcdBacking store for all cluster data
kube-schedulerAssigns Pods to nodes
kube-controller-managerRuns controller loops
cloud-controller-managerCloud provider integration (optional)

Node components

ComponentResponsibilityOptional
kubeletEnsures Pods and containers runNo
kube-proxyNetwork rules for ServicesYes (with some CNIs)
Container runtimeRuns containersNo

Verification commands

CommandChecks
kubectl get nodesNode status
kubectl get componentstatusesControl plane health
kubectl get pods -n kube-systemControl plane Pods
kubectl cluster-infoAPI server endpoint
systemctl status kubeletKubelet on a node
crictl infoContainer runtime on a node

Best Practices

✅ Do This:

# Back up etcd regularly
etcdctl snapshot save backup.db                             # ✅
# Run the control plane on dedicated machines
# Do not schedule user workloads there                     # ✅
# Check componentstatuses after cluster changes
kubectl get componentstatuses                               # ✅
# Verify the kubelet on each node after maintenance
systemctl status kubelet                                    # ✅

❌ Don’t Do This:

# Assume the control plane is healthy because nodes are Ready
# Check componentstatuses separately                          # ❌
# Run user workloads on control plane nodes
# Without taints and tolerations, they compete for resources # ❌
# Skip etcd backups
# Losing etcd loses the cluster state                        # ❌

Common Pitfalls

PitfallWhy It HappensFix
Pods stay PendingNo worker nodes or insufficient resourcesCheck kubectl get nodes and resource requests
kubectl commands failAPI server downCheck kubectl cluster-info and API server Pod
Node shows NotReadyKubelet or container runtime downCheck systemctl status kubelet and crictl info
Service name does not resolveCoreDNS not runningCheck kube-system for CoreDNS Pods
Scheduling stopsScheduler downCheck kube-scheduler Pod and componentstatuses

Real-World Examples

1. List nodes

kubectl get nodes

2. Check control plane health

kubectl get componentstatuses

3. Check control plane Pods

kubectl get pods -n kube-system

4. Check API server

kubectl cluster-info

5. Check scheduler

kubectl get pods -n kube-system -l component=kube-scheduler

6. Check controller manager

kubectl get pods -n kube-system -l component=kube-controller-manager

7. Check etcd

kubectl get pods -n kube-system -l component=etcd

8. Check kubelet

systemctl status kubelet

9. Check kube-proxy

kubectl get pods -n kube-system -l k8s-app=kube-proxy

10. Check container runtime

crictl info

Visual

The cluster architecture

┌─────────────────────────────────────────────────────────────┐
│  CONTROL PLANE                                               │
│                                                              │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │ kube-        │  │   etcd       │  │ kube-        │      │
│  │ apiserver    │  │              │  │ scheduler    │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ kube-controller-manager                              │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                              │
│  ─────────────────────────────────────────────────────────  │
│                                                              │
│  WORKER NODE 1              WORKER NODE 2                    │
│  ┌──────────────┐           ┌──────────────┐                │
│  │ kubelet      │           │ kubelet      │                │
│  │ kube-proxy   │           │ kube-proxy   │                │
│  │ runtime      │           │ runtime      │                │
│  │ ┌──────────┐ │           │ ┌──────────┐ │                │
│  │ │ Pod      │ │           │ │ Pod      │ │                │
│  │ └──────────┘ │           │ └──────────┘ │                │
│  └──────────────┘           └──────────────┘                │
└─────────────────────────────────────────────────────────────┘

The scheduling boundary

┌─────────────────────────────────────────────────────────────┐
│  CONTROL PLANE DECIDES          NODE EXECUTES                │
│                                                              │
│  Scheduler selects a node       Kubelet receives the Pod     │
│  for a new Pod                  specification                │
│       │                              │                       │
│       ▼                              ▼                       │
│  Node is assigned               Kubelet starts the containers│
│                                      │                       │
│                                      ▼                       │
│                                 Container runtime pulls image│
│                                 and runs the container       │
└─────────────────────────────────────────────────────────────┘

Pod scheduling and failure

┌─────────────────────────────────────────────────────────────┐
│  POD LIFECYCLE                                               │
│                                                              │
│  Pod created ──► Scheduler assigns node                     │
│       │                                                      │
│       ▼                                                      │
│  Pod runs on that node                                       │
│       │                                                      │
│       ├── Node fails ──► Control plane reschedules          │
│       │                    identical Pod on another node     │
│       │                                                      │
│       └── Pod terminated ──► according to restart policy     │
└─────────────────────────────────────────────────────────────┘

Verification flow

┌─────────────────────────────────────────────────────────────┐
│  HEALTH CHECK                                                │
│                                                              │
│  kubectl get nodes                                           │
│    └── Are worker nodes Ready?                               │
│                                                              │
│  kubectl get componentstatuses                               │
│    └── Is the control plane healthy?                         │
│                                                              │
│  kubectl get pods -n kube-system                             │
│    └── Are the control plane Pods running?                   │
│                                                              │
│  systemctl status kubelet (on each node)                     │
│    └── Is the node agent running?                            │
└─────────────────────────────────────────────────────────────┘

Summary

ItemValue
Control planeMakes global decisions
Worker nodesRun application Pods
API serverFront end, exposes the Kubernetes API
etcdBacking store for all cluster data
SchedulerAssigns Pods to nodes
Controller managerRuns reconciliation loops
KubeletNode agent, ensures Pods run
kube-proxyNetwork rules for Services (optional with some CNIs)
Container runtimeRuns containers
Pod placementTied to the scheduled node until termination

Key takeaways:

  • The control plane decides, and the worker nodes execute. The scheduler selects a node for each Pod, and the kubelet on that node ensures the containers are running. The control plane does not run application containers .
  • The kube-apiserver is the front door. Every interaction with the cluster goes through it. It is stateless and can be scaled horizontally for high availability .
  • etcd is the source of truth. Every object in the cluster is stored there. A backup plan is mandatory, because losing etcd means losing the cluster’s state .
  • The kubelet is the node agent. It receives Pod specifications from the API server and ensures the containers are running. The container runtime does the actual running .
  • kube-proxy is optional with some CNI plugins. It maintains the network rules for Services, but a plugin that provides its own proxying can replace it .
  • A Pod is tied to its node. It remains on the node where it was scheduled until termination or deletion. If the node fails, the control plane schedules an identical Pod on another available node .

Remember: The Kubernetes cluster is a separation of concerns. The control plane makes the global decisions—scheduling, reconciliation, API access—and the worker nodes execute the local work—running containers, reporting status, routing traffic. The kube-apiserver is the interface, etcd is the memory, the scheduler is the placement decision, and the controller manager is the reconciliation loop. The kubelet on each node is the agent that carries out the instructions. When a Pod stays Pending, the scheduler cannot find a node that satisfies its requirements. When a node goes NotReady, the kubelet or the container runtime has failed. When kubectl stops responding, the API server is down. Knowing which component is responsible for which decision is what makes cluster debugging tractable.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!