Kubernetes Basics
This page walks through the pieces every Kubernetes cluster is built from - the control plane, the worker nodes, and the core objects you deploy onto them. Each example is small and runnable so you can build a mental map before diving deeper.
Prerequisites
kubectlmatching your cluster (skew of one minor version is supported).- A cluster: kind or minikube locally, or a managed cluster (EKS/GKE/AKS) on Kubernetes 1.36.2.
- Docker Engine 29.6.1 locally if you want to build your own images (nodes run containerd).
Quick local cluster with kind:
kind create cluster --name demo
kubectl cluster-infoBasic Examples
1. See the control-plane and node layout
The control plane makes decisions; worker nodes run your Pods.
kubectl get nodes -o wide
kubectl get pods -n kube-system- The control plane hosts the API server, scheduler, controller manager, and etcd.
- Worker nodes run a kubelet and a container runtime (containerd).
kube-systemholds cluster components like CoreDNS and the kube-proxy.- On managed clusters the control plane is hidden; you only see and pay for nodes.
2. Talk to the API server
Every command you run is an HTTP call to the API server.
kubectl api-resources | head
kubectl get --raw /healthz- The API server is the single front door to the cluster.
- It validates requests, enforces RBAC, and persists objects to etcd.
api-resourceslists every object kind the server understands.- Controllers and the scheduler are also just API-server clients.
3. Create your first Pod
A Pod is the smallest schedulable unit and wraps one or more containers.
apiVersion: v1
kind: Pod
metadata:
name: hello
spec:
containers:
- name: hello
image: nginx:1.27
ports:
- containerPort: 80- Apply it with
kubectl apply -f hello.yaml. - The scheduler picks a node; the kubelet starts the container via containerd.
- Containers in one Pod share a network namespace and can reach each other on
localhost. - Bare Pods are not self-healing - prefer a Deployment for real workloads.
4. Run a self-healing Deployment
A Deployment keeps a desired number of Pod replicas alive.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27- The Deployment controller creates and replaces Pods to match
replicas. - Delete a Pod and watch a new one appear:
kubectl delete pod -l app=web. - The
selectormust match thetemplatelabels or the object is rejected. - This is desired-state reconciliation doing the work for you.
5. Expose Pods with a Service
A Service gives a stable virtual IP and DNS name in front of changing Pods.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80- The Service selects Pods by label, not by name or IP.
- kube-proxy programs the node so traffic to the Service IP is load-balanced across Pods.
- Inside the cluster, other Pods reach it as
webvia CoreDNS. - Pod IPs are ephemeral; the Service IP is stable.
6. Organize with namespaces
Namespaces partition a cluster into logical groups.
kubectl create namespace staging
kubectl get pods -n staging- Namespaces scope names, quotas, and RBAC rules.
- Use them to separate teams or environments inside one cluster.
- Cluster-wide objects like nodes are not namespaced.
kubectl config set-context --current --namespace=stagingsets a default.
7. Inspect and debug
describe and logs are your first two debugging tools.
kubectl describe pod hello
kubectl logs deploy/webdescribeshows events like scheduling failures and image pull errors.logsstreams container stdout/stderr; add-fto follow.kubectl get events --sort-by=.lastTimestampgives a cluster timeline.- Most first-day problems are visible in these two commands.
Intermediate Examples
8. Give Pods resource requests and limits
Requests drive scheduling; limits cap consumption.
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"- The scheduler uses
requeststo find a node with room. - Exceeding a memory
limitgets the container OOM-killed and restarted. - CPU over the limit is throttled, not killed.
- Setting these is a baseline production requirement, not an optimization.
9. Add liveness and readiness probes
Probes let the kubelet and Services know a container's health.
readinessProbe:
httpGet:
path: /healthz
port: 80
periodSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 10- A failing readiness probe removes the Pod from Service endpoints without restarting it.
- A failing liveness probe restarts the container.
- Wrong probes cause rollout hangs and restart loops, so tune them carefully.
- Keep probe endpoints cheap and dependency-free.
10. Roll out an update safely
Changing the image triggers a controlled rolling update.
kubectl set image deploy/web web=nginx:1.27.1
kubectl rollout status deploy/web
kubectl rollout undo deploy/web- The Deployment replaces Pods gradually so the Service stays available.
rollout statusblocks until the new version is healthy.rollout undoreverts to the previous ReplicaSet if something breaks.- Readiness probes gate each new Pod before old ones are removed.
11. Inject configuration and secrets
Keep config out of the image and mount it at runtime.
apiVersion: v1
kind: ConfigMap
metadata:
name: web-config
data:
LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
name: web-secret
type: Opaque
stringData:
API_TOKEN: "changeme"- Reference these from a Pod with
envFromorvalueFromto set environment variables. - ConfigMaps hold non-sensitive settings; Secrets hold credentials and are base64-encoded at rest.
- Enable encryption-at-rest and RBAC so Secrets are not readable by everyone.
- Changing config without rebuilding the image is a core benefit of this split.
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).