Skip to content

Kubernetes homelab — beginner's guide

All concepts below appeared in your homelab conversation. Read them in order — each one builds on the previous.


1. What is Kubernetes?

Kubernetes (also called k8s) is a system that manages containerised applications across a group of computers. Think of it as an orchestra conductor — it decides where to run each part of your app, restarts things that crash, and keeps everything coordinated.

Analogy: If Docker is like shipping containers, Kubernetes is the port that decides which ship carries which container and where it goes.

In your homelab, you have a small cluster: one control-plane machine (k8s-cp-01) and two worker machines (k8s-worker-01, k8s-worker-02). That's a real, functional Kubernetes setup.


2. Nodes — the machines in your cluster

A node is just a computer (physical or virtual) that Kubernetes manages. There are two kinds:

Type Your machine Role
Control plane k8s-cp-01 The brain — manages the cluster, schedules work, stores config
Worker k8s-worker-01 The muscle — actually runs your app containers
Worker k8s-worker-02 Second worker — adds capacity and redundancy

In your terminal output, both showed NotReady. This means the nodes are online but can't yet communicate with each other — they're waiting for a CNI (covered next).

Once Flannel is installed, they'll flip to Ready.


3. Pods — the smallest unit of work

A pod is the smallest thing Kubernetes can run. It wraps one (or sometimes a few) containers and gives them a shared network and storage.

Analogy: If a container is a single app process, a pod is the little apartment it lives in — with its own address and shared utilities.

This command from your conversation creates a bare pod running nginx:

# Creates a single pod called "test-nginx"
kubectl run test-nginx --image=nginx --restart=Never
  • --image=nginx tells k8s to pull the nginx container image.
  • --restart=Never means "just run it once, don't keep restarting" — useful for quick tests.

4. CNI & Flannel — the cluster's network layer

A CNI (Container Network Interface) is a plugin that gives every pod its own IP address and lets pods talk to each other across nodes. Without one, your nodes stay NotReady and nothing can be scheduled.

Pod A (worker-01)  →  Flannel (overlay network)  →  Pod B (worker-01)

Flannel is one of the simplest CNI plugins. It creates a virtual network overlay so every pod gets an IP — even when they're on different physical machines. It's a great choice for homelabs because it's lightweight (important with your 8 GB RAM constraint).

You install it with one command:

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

The kubectl apply -f pattern means "apply this configuration file to my cluster." You'll use it constantly in Kubernetes.

The CRI-to-CNI Handoff

While CNI stands for Container Network Interface, it is not merely a theoretical API — it consists of physical, executable binary files (like flannel, bridge, portmap).

When a pod is scheduled to a node, the Container Runtime Interface (CRI) (like containerd) creates the initial Linux network namespace. However, the runtime does not know how to assign IPs or route traffic. Instead, the runtime executes the CNI binary on the host OS and hands off the networking responsibilities.

Because of this direct execution model, the CRI is hardcoded to look for these CNI binaries in a specific directory (usually /opt/cni/bin/). If the OS package manager compiled the CRI to look in /usr/lib/cni/ instead, the handoff fails, and the pod will be permanently stuck in ContainerCreating.


5. Pod CIDR — giving pods their IP addresses

A CIDR (Classless Inter-Domain Routing) block is a range of IP addresses written in compact notation. 10.244.0.0/16 means "all addresses from 10.244.0.0 to 10.244.255.255" — that's 65,536 possible IPs.

10.244.0.0 / 16
│            │
│            └─ First 16 bits are fixed (the "network" part)
└─ Network address

Kubernetes assigns each pod a unique IP from this range so they can communicate. 10.244.0.0/16 is Flannel's default range — which is exactly why it works out of the box with your cluster config.

These are private IPs (invisible to the internet), used only internally inside your cluster.


6. kubectl — your command line for Kubernetes

kubectl (pronounced "kube control" or "kube cuttle") is the CLI tool you use to interact with your cluster. Every command in the conversation used it.

Almost every kubectl command follows this pattern:

kubectl [action] [resource type] [name]

Essential commands

# List all nodes and their status
kubectl get nodes

# Create or update resources from a YAML config file
kubectl apply -f file.yml

# Quickly launch a pod from a container image
kubectl run test-nginx --image=nginx --restart=Never

# List all pods and their current state
kubectl get pods

# Get detailed info about a specific pod
kubectl describe pod test-nginx

# Stream logs from a pod
kubectl logs test-nginx

Node maintenance commands

# Mark a node as unschedulable (no new pods will be placed on it)
kubectl cordon k8s-worker-01

# Evict all pods from a node (also cordons it automatically)
kubectl drain k8s-worker-01 --ignore-daemonsets --delete-emptydir-data

# Mark a node as schedulable again (allow new pods after maintenance)
kubectl uncordon k8s-worker-01 k8s-worker-02
  • cordon = "put up the tape" — the node stays running, but the scheduler won't place new pods on it.
  • drain = cordon + evict all existing pods. Used before maintenance or shutdown.
  • uncordon = "take the tape down" — the node is open for business again. You can uncordon multiple nodes at once.

Quick reference — concepts at a glance

Term What it is Your example
k8s Short for Kubernetes Your whole homelab cluster
Node A machine in the cluster k8s-cp-01, k8s-worker-01, k8s-worker-02
Control plane The node that manages everything k8s-cp-01
Worker The node that runs workloads k8s-worker-01, k8s-worker-02
Pod Smallest runnable unit (wraps containers) test-nginx
CNI Network plugin — gives pods IPs Flannel
CIDR A range of IP addresses 10.244.0.0/16
kubectl CLI tool to control the cluster All commands above
NotReady Node online but no CNI yet Your initial state
Ready Node fully operational After Flannel installs
Cordon Mark a node as unschedulable kubectl cordon k8s-worker-01
Uncordon Mark a node as schedulable again kubectl uncordon k8s-worker-01
Drain Evict all pods from a node (+ cordon) kubectl drain k8s-worker-01