BLOG02: Usage and Difference

BLOG01: Usage and difference between Kubeadm, Kubectl, Kubelet

Here’s a clear and concise explanation of kubeadm, kubectl, and kubelet — how they differ, how they work, and whether Kubernetes components run as containers.


Are all Kubernetes services containers?

Yes — in a kubeadm-based cluster, most control-plane components run as containers, such as:

  • kube-apiserver

  • kube-controller-manager

  • kube-scheduler

  • etcd (if local)

These run as static pods managed by kubelet. You can see them in:

kubectl get pods -n kube-system

Worker-node components like kubelet, container runtime (containerd, cri-o) run as systemd services (not containers).


The difference between kubeadm, kubectl, and kubelet

kubeadm

“The Kubernetes cluster installer”

  • A bootstrap tool to create and join Kubernetes clusters.

  • It does NOT run the cluster.

  • It only prepares and sets up the control plane + worker nodes.

kubeadm does things like:

  • kubeadm init – initialize the cluster

  • kubeadm join – join worker nodes

  • Configure certificates

  • Create static pod manifests for API server, scheduler, controller-manager

  • Configure kubelet bootstrap

Think of kubeadm as:

  • installer

  • initializer

  • not a long-running service

  • not responsible for cluster management


kubectl

“The Kubernetes command-line client”

Used to interact with the Kubernetes API server.

Examples:

kubectl does not manage nodes or start Kubernetes. It only sends requests to the API server.


kubelet

“The node agent — runs on every node”

kubelet is a long-running systemd service that:

  • Talks to the Kubernetes API

  • Ensures containers/pods are running

  • Runs static pod manifests

  • Manages health checks (liveness/readiness)

  • Talks to container runtime (containerd/cri-o)

Without kubelet, a node is NOT part of the cluster.

kubelet responsibilities:

  • Start/stop pods

  • Report node health

  • Run control plane components (kubeadm static pods)

  • Manage CRI runtime

kubelet ≠ kubeadm

kubeadm installs/kicks things off. kubelet actually runs/maintains everything.


Quick Comparison Table

Component
Type
Purpose
Runs as

kubeadm

Bootstrap tool

Create/Join cluster

CLI command

kubectl

Client tool

Talk to API server

CLI command

kubelet

Node agent

Runs pods, manages node

systemd service

kube-apiserver

Control-plane service

Accepts API requests

Container (static pod)

scheduler

Control-plane service

Assign pods to nodes

Container (static pod)

controller-manager

Control-plane service

Reconciliation loops

Container (static pod)

etcd

Database

Cluster state

Container (static pod)


Summary

  • kubeadm → installs and bootstraps Kubernetes

  • kubectl → interacts with the Kubernetes API

  • kubelet → runs on every node and manages pods

  • Control-plane services run as containers, managed by kubelet


Question: How do kubeadm, kubelet, kubectl, and all Kubernetes components interact in the cluster?

Great — here is a simple, clean, visual explanation of how kubeadm, kubelet, kubectl, and all Kubernetes components work together. This will make the whole architecture crystal clear.


How kubeadm, kubelet, kubectl, API server connect (Simple Diagram)


How kubeadm fits into this

kubeadm is NOT a service. It simply creates everything needed.

When you run:

kubeadm does these things:

Generates control-plane certificates

  • apiserver certs

  • etcd certs

  • kubelet client certs

Writes static pod manifests

kubeadm creates YAML files in:

These YAML files define:

  • kube-apiserver

  • kube-scheduler

  • kube-controller-manager

  • etcd (if local)

kubelet automatically sees these files

kubelet detects static pod manifests and runs them as containers.

So kubeadm → writes manifests kubelet → runs the containers


kubeadm vs kubelet vs kubectl — Simple Summary

kubeadm = Installer / Bootstrapper

  • creates cluster

  • generates certificates

  • installs control plane

  • creates static pod configs

kubelet = Node Agent (runs 24/7)

  • runs pods

  • pulls images via containerd

  • ensures health

  • keeps node in sync with API server

kubectl = Client tool

  • sends commands to API server

  • never interacts with kubelet directly


How kubeadm-created nodes run the control plane

Control-plane node example:

You will see kubelet running as a systemd service, and the API server, scheduler, and controller-manager running as containers, e.g.:

Because they are static pods pulled by kubelet.


Difference Between K8s Distributions

Here is how K8s installers differ:

Tool / Distro
Control-plane runs as
Purpose

kubeadm

containers (static pods)

Production cluster bootstrap

minikube

VM or Docker env

Local testing

k3s

single binary

Lightweight, CNCF-certified

EKS/GKE/AKS

Hidden (AWS manages)

Managed control plane

RKE/Rancher

containers

Cluster provisioning


Question: What actually happens inside Kubernetes when you run kubectl apply -f pod.yaml?

Let's step through and visualize how kubectl apply -f pod.yaml flows through Kubernetes, including how kubeadm, kubelet, and container runtimes fit into the picture. This breakdown will make the full lifecycle clear.


Step-by-Step Flow: kubectl apply -f pod.yaml

User runs kubectl

  • kubectl reads the YAML file (defines a Pod or Deployment).

  • Sends a REST API request to the kube-apiserver.


API server receives request

  • Validates YAML schema and authentication (RBAC).

  • Stores desired state in etcd (cluster database).

  • Updates spec in etcd: "I want Pod X running on Node Y".


Scheduler assigns Pod to a Node

  • kube-scheduler watches etcd for unassigned pods.

  • Decides which node will run the pod based on:

    • Resources (CPU, memory)

    • Taints/Tolerations

    • Node selectors/affinity


Controller-manager ensures desired state

  • kube-controller-manager ensures cluster matches desired state:

    • For Deployments, ReplicaSets → ensures the right number of pods exist

    • Updates API server status if pods need to be created


kubelet on the assigned node acts

  • kubelet sees new pod assigned to its node via the API server.

  • kubelet reads pod spec and instructs container runtime (containerd, CRI-O, Docker) to start containers.

  • kubelet monitors pod health and restarts containers if needed.


Pod runs

  • kubelet continuously reports status back to API server:

    • Pod running

    • Container started

    • Readiness / Liveness

  • kubectl can now show status:


Full Flow Diagram


Key Takeaways

  1. kubectl → talks to API server (CLI client).

  2. kube-apiserver → validates, stores desired state in etcd.

  3. scheduler → assigns pods to nodes.

  4. controller-manager → ensures desired number of replicas and state.

  5. kubelet → runs on node, ensures pod runs correctly.

  6. container runtime → actually runs containers.

Note: kubeadm is only used once to bootstrap the cluster. kubelet and container runtime run continuously to keep pods alive.


Question: What happens when you run kubeadm join on a new worker node? How does it connect and become part of the Kubernetes cluster?

Perfect — let’s break down what happens when you run kubeadm join on a new worker node and how it hooks into the cluster.


Step-by-Step Flow: kubeadm join

Assume you already have a control-plane node up with kubeadm.


Run kubeadm join on worker node

Example:

  • This tells the worker: “I want to join the cluster at this API server.”

  • kubeadm on the worker does not start the cluster, just sets up the node to join.


Bootstrap the kubelet

  • kubeadm creates the kubelet configuration on the worker node.

  • It writes a kubelet.conf pointing to the control-plane API server.

  • kubelet now knows how to authenticate with the API server using a bootstrap token.


Download cluster CA and configuration

  • kubeadm fetches cluster CA certificate to securely communicate with API server.

  • This ensures TLS communication with the control plane.


kubelet starts on the node

  • kubeadm ensures kubelet service is running (systemd).

  • kubelet registers the node with the API server:

  • Node status in API server initially shows NotReady.


Install networking plugin

  • Most clusters use CNI (like Calico, Flannel, Weave).

  • kubeadm doesn’t install CNI by default for worker nodes — you must deploy it.

  • Once CNI is applied, kubelet can start scheduling pods.


Node becomes Ready

  • kubelet continuously reports node health and capacity to the API server.

  • Control plane marks the node Ready.

  • Node can now run pods scheduled by kube-scheduler.


Flow Diagram: kubeadm join


Key Points

  1. kubeadm join only runs once per node to configure it.

  2. kubelet is the long-running agent that maintains the node.

  3. Token + CA hash ensures secure authentication with the cluster.

  4. After joining, the node becomes part of the cluster and can run workloads.


Check existing valid tokens

On your control-plane node, run:

Example output:

  • If a token exists and is not expired, you can use it.

  • If no token exists or it expired, create a new one.


Create a new token

  • This outputs a new token, e.g.:

  • If you want the join command ready with CA hash:

Example output:

  • Copy this — it’s your new join command for the worker node.


Run kubeadm join on the new node

On the new worker node, run:

  • kubeadm will bootstrap kubelet, fetch the cluster CA, and register the node.


Verify the node joined

Back on the control-plane node:

You should see the new node appear and eventually reach Ready status.


Tip: Always save tokens or use --print-join-command so you can join nodes later.

Last updated