reference · kubernetes 1.3x · kubectl
Architecture, workloads, and the commands you'll actually type
Kubernetes automates deploying, scaling, and healing containerized applications. This
guide covers how a cluster is put together, the objects you'll build things out of, the
controllers that keep them running, and a kubectl reference for daily
work.
01 Cluster architecture
A cluster is a set of machines running containerized workloads, coordinated through a declarative API.
You describe the state you want; a set of controllers continuously works to make the actual state match it. Nodes split into two roles: control plane nodes make global decisions about the cluster and store all its state, while worker nodes run the actual application workloads, inside Pods.
┌───────────────────────────────┐
│ Control Plane │
│ kube-apiserver etcd │
│ kube-scheduler controller- │
│ manager │
└────────────────┬──────────────────┘
│ HTTPS (API)
┌────────────────────────┼────────────────────────┐
│ │ │
┌───────┴────────┐ ┌────────┴───────┐ ┌────────┴───────┐
│ Worker Node 1 │ │ Worker Node 2 │ │ Worker Node N │
│ kubelet │ │ kubelet │ │ kubelet │
│ kube-proxy │ │ kube-proxy │ │ kube-proxy │
│ container │ │ container │ │ container │
│ runtime │ │ runtime │ │ runtime │
│ [Pod] [Pod] │ │ [Pod] [Pod] │ │ [Pod] │
└──────────────────┘ └──────────────────┘ └──────────────────┘
Every component talks to the API server; nothing talks to etcd directly
except the API server itself. That makes it the single front door for reading or
changing cluster state.
02 Control plane components
- kube-apiserver — the front door. Exposes the Kubernetes REST API, handles authentication/authorization and admission control, validates and persists objects. Everything else is a client of it.
- etcd — a distributed, consistent key-value store. The single source of truth for all cluster state.
- kube-scheduler — watches for Pods with no node assigned yet and picks one, based on resource requests, affinity/anti-affinity rules, taints/tolerations, and topology constraints.
- kube-controller-manager — runs the reconciliation loops (node controller, replication controller, endpoints controller, and more) that continuously watch actual state and drive it toward desired state.
- cloud-controller-manager — cloud-provider-specific logic (provisioning load balancers, labeling nodes with cloud metadata). Only present on managed clusters (EKS, GKE, AKS).
03 Worker node components
- kubelet — the agent on every node. Watches the API server for Pods assigned to its node and ensures the containers described in each Pod's spec are actually running and healthy.
- kube-proxy — maintains the network rules (iptables or IPVS) on each node that implement the Service abstraction, routing traffic sent to a Service's virtual IP to one of its backing Pods.
- Container runtime — the software that actually pulls images and runs containers (containerd, CRI-O), talked to by the kubelet through the Container Runtime Interface (CRI).
04 Cluster & kubeconfig
A cluster is one or more control plane nodes plus one or more worker
nodes, operating as a single unit behind one API server (or a load-balanced set of API
server replicas in production). Inside a cluster, namespaces let you
logically partition resources (e.g. dev, staging,
prod) without running separate clusters.
kubectl doesn't know which cluster to talk to on its own — it reads
a kubeconfig file (default ~/.kube/config) holding one or
more clusters, users (credentials), and contexts (a cluster + user + default namespace,
bundled together and given a name you can switch to).
05 Image
A container image is an immutable, layered filesystem plus metadata
(entrypoint/cmd, environment defaults, exposed ports), built once (typically from a
Dockerfile) and pushed to a registry (Docker Hub, ECR, GCR, GHCR). Kubernetes pulls
images by reference: registry/name:tag, optionally pinned to an exact
@sha256:digest for full immutability.
| imagePullPolicy | Behavior |
|---|---|
IfNotPresent | Pull only if the image isn't already cached on the node (default for explicit tags). |
Always | Always check the registry, re-pull if the tag now points to a different digest. Default when the tag is :latest. |
Never | Only use what's already on the node; fail if it's not there. |
06 Container
A container is a running instance of an image, isolated from the host and other containers via Linux namespaces (PID, network, mount, ...) and resource-limited via cgroups. In Kubernetes, containers never run standalone — they always run inside a Pod. A Pod can define:
- init containers — run to completion, in order, before any app container starts (common for setup/migrations).
- app containers — the long-running main process(es) of the Pod.
- sidecar containers — auxiliary containers that run alongside the app container for its whole lifetime (log shippers, proxies).
07 Pod
The Pod is the smallest deployable unit in Kubernetes: one or more
containers always scheduled together on the same node, sharing a network namespace (same
IP address, containers reach each other over localhost) and optionally
storage volumes. Pods are ephemeral and not self-healing on their own
— if a bare Pod's node fails or the Pod is deleted, nothing recreates it. That's
why Pods are almost always created indirectly, through a controller like a Deployment or
StatefulSet, rather than by hand.
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
08 ReplicaSet
A ReplicaSet ensures a specified number of identical Pod replicas are running at all times, using a label selector to identify which Pods it's responsible for. If a Pod it manages dies, it creates a replacement; if there are too many matching Pods, it deletes the excess. In practice you rarely create a ReplicaSet directly — a Deployment creates and manages one for you.
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-rs
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
09 Deployment
A Deployment is the standard way to run stateless applications. You
describe the desired Pod template and replica count declaratively; the Deployment
controller creates and owns a ReplicaSet, which in turn owns the Pods. Change the Pod
template (e.g. a new image tag) and the Deployment performs a controlled
rolling update — spinning up new Pods and retiring old ones
gradually, governed by maxSurge/maxUnavailable — and you
can roll it back with a single command if it goes wrong.
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
10 StatefulSet
A StatefulSet is for workloads that need stable, unique identity and stable storage per replica — databases, Kafka, ZooKeeper, anything where "replica 0" and "replica 1" aren't interchangeable. It differs from a Deployment in three ways:
- Pods get stable, predictable names —
<name>-0,<name>-1, ... — instead of a random hash suffix. - Pods are created and scaled in order by default (0, 1, 2, ... up; reverse order down), rather than all at once.
- Each replica gets its own PersistentVolumeClaim via
volumeClaimTemplates, which survives Pod rescheduling — Pod-0always reattaches to the same volume it had before.
A StatefulSet also needs a headless Service (clusterIP: None) so each Pod
gets a stable DNS name:
<pod-name>.<service-name>.<namespace>.svc.cluster.local.
apiVersion: v1
kind: Service
metadata:
name: postgres-headless
spec:
clusterIP: None
selector:
app: postgres
ports:
- port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres-headless
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
containers:
- name: postgres
image: postgres:16
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
11 Liveness & readiness probes
| Probe | Question it answers | On failure |
|---|---|---|
livenessProbe |
Is this container still alive/healthy? | kubelet kills and restarts the container (per its
restartPolicy) — recovers a deadlocked or stuck process. |
readinessProbe |
Is this container ready to receive traffic right now? | The Pod is pulled out of every Service's endpoint list — no restart, traffic just stops being routed to it until it passes again. |
startupProbe, delays liveness/readiness checks until a
slow-starting container has finished booting, so a long startup isn't mistaken for a
liveness failure and repeatedly restarted.
All three support the same check mechanisms — httpGet,
tcpSocket, or exec — and the same tuning fields:
initialDelaySeconds, periodSeconds, timeoutSeconds,
successThreshold, failureThreshold.
containers:
- name: web
image: myapp:1.4
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 2
12 kubectl cheat sheet
cluster & context
kubectl cluster-info | Show the API server and core service endpoints. |
kubectl get nodes -o wide | List nodes with IP/OS/kubelet version. |
kubectl config get-contexts | List available cluster/user/namespace contexts. |
kubectl config use-context <name> | Switch the active context. |
kubectl config set-context --current --namespace=<ns> | Set the default namespace for the current context. |
namespaces
kubectl get ns | List namespaces. |
kubectl create ns <name> | Create a namespace. |
pods
kubectl get pods -o wide -n <ns> | List Pods with node/IP. |
kubectl describe pod <name> | Full status, events, and probe/restart history — the first place to look when a Pod misbehaves. |
kubectl logs <pod> [-c <container>] [-f] | Stream container logs; -f follows. |
kubectl logs <pod> --previous | Logs from the previous (crashed) instance of the container. |
kubectl exec -it <pod> -- sh | Open a shell inside a running container. |
kubectl port-forward pod/<name> 8080:80 | Forward a local port to a port inside the Pod. |
kubectl delete pod <name> | Delete a Pod (its controller will usually recreate it). |
deployments
kubectl create deployment <name> --image=<img> | Quickly create a Deployment imperatively. |
kubectl get deployments | List Deployments and their ready/up-to-date/available counts. |
kubectl scale deployment <name> --replicas=5 | Change the replica count. |
kubectl set image deployment/<name> <container>=<image>:<tag> | Trigger a rolling update to a new image. |
kubectl rollout status deployment/<name> | Watch a rollout until it completes. |
kubectl rollout history deployment/<name> | List past revisions. |
kubectl rollout undo deployment/<name> [--to-revision=N] | Roll back to the previous (or a specific) revision. |
replicasets & statefulsets
kubectl get rs | List ReplicaSets (usually one per Deployment revision). |
kubectl get sts | List StatefulSets. |
kubectl scale statefulset <name> --replicas=3 | Scale a StatefulSet (respects ordered creation/deletion). |
kubectl rollout status statefulset/<name> | Watch a StatefulSet rollout. |
services
kubectl get svc | List Services and their cluster IPs/ports. |
kubectl expose deployment <name> --port=80 --target-port=8080 | Create a Service in front of a Deployment. |
manifests & labels
kubectl apply -f file.yaml | Create or update resources declaratively from a manifest. |
kubectl apply -f dir/ | Apply every manifest in a directory. |
kubectl delete -f file.yaml | Delete everything defined in a manifest. |
kubectl diff -f file.yaml | Preview what apply would change. |
kubectl get pods -l app=web | Filter by label selector. |
kubectl label pod <name> env=prod | Add/update a label on a live object. |
debugging & config objects
kubectl get events --sort-by=.lastTimestamp | Cluster-wide events, newest last — useful for scheduling/pull failures. |
kubectl top pods / kubectl top nodes | Live CPU/memory usage (requires metrics-server). |
kubectl create configmap <name> --from-literal=key=value | Create a ConfigMap for non-secret config. |
kubectl create secret generic <name> --from-literal=key=value | Create a Secret for sensitive config. |