The pod is the smallest thing Kubernetes runs. Create one, read its logs, get a shell inside it, understand multi-container pods, and see why you rarely manage pods directly.
Why: a pod is the smallest unit Kubernetes deploys — a wrapper around one (occasionally a few) containers that share a network address and storage. A pod always runs on a single node, and every pod gets its own cluster-internal IP. Note: you usually do NOT create pods directly; a Deployment makes them for you. But to understand everything else, you start here.
# pod.yaml — a single-container pod
apiVersion: v1
kind: Pod
metadata:
name: hello
labels:
app: hello
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80Apply the file, then list pods with extra columns: -o wide adds the node and pod IP. STATUS tells you the lifecycle phase (Pending, Running, CrashLoopBackOff…) and READY shows how many of its containers are up. When something is wrong, describe shows why in its Events.
kubectl apply -f pod.yamlWide listing shows the node and the pod's IP
kubectl get pod hello -o wideWhy is it Pending / crashing? The Events explain
kubectl describe pod hellologs prints whatever the container wrote to stdout/stderr — your number-one debugging tool. -f follows live, like tail -f. exec runs a command inside the running container; with -it you get an interactive shell to poke around from the inside.
Show the container's logs (-f to follow live)
kubectl logs helloOpen a shell INSIDE the container
kubectl exec -it hello -- shRun a one-off command without a shell
kubectl exec hello -- ls /usr/share/nginx/htmlA pod's IP is only reachable from inside the cluster. To hit it from your laptop while developing, port-forward tunnels a local port to the pod. This is for debugging only — real external access uses Services and Ingress, covered in later lessons.
Forward localhost:8080 to the pod's port 80
kubectl port-forward pod/hello 8080:80Now in another terminal:
curl http://localhost:8080Why: sometimes a helper container belongs right next to your app — shipping its logs, refreshing a cache, or proxying traffic. Containers in the same pod share a network (they reach each other on localhost) and can share files through a volume. This "sidecar" pattern is how you add capability without changing the main app.
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
- name: app
image: nginx:1.27
- name: log-shipper # sidecar: runs alongside "app"
image: busybox:1.36
command: ['sh', '-c', 'tail -F /var/log/app.log']