A pod has one or more containers on the same node sharing a network namespace (one IP) and volumes. A bare pod is not recreated when deleted or when its node dies; workloads such as Deployments do that.
apiVersion: v1
kind: Pod
metadata:
name: web
namespace: dev
spec:
containers:
- name: app
image: nginx:1.27
ports:
- containerPort: 80
readinessProbe:
httpGet: { path: /, port: 80 }
periodSeconds: 10
livenessProbe:
httpGet: { path: /, port: 80 }
initialDelaySeconds: 30
periodSeconds: 60
commandreplaces the image ENTRYPOINT,argsreplaces CMD.- readinessProbe failing: the pod is removed from the Service endpoints (no traffic); the container is not restarted.
- livenessProbe failing: the kubelet restarts the container.
flowchart LR
R{"readiness fails"} --> E["Removed from Service endpoints"]
L{"liveness fails"} --> X["Container restarted"]
Debugging
| Command | Use it when |
|---|---|
kubectl run web --image=nginx:1.27 -n dev |
Quickly create a pod (imperative) |
kubectl describe pod web -n dev |
Read the Events: image pull errors, Pending, probe failures |
kubectl logs web -n dev / --previous |
Current logs / logs of the run before the crash |
kubectl exec -it web -n dev -- sh |
Open a shell in the container; -- separates the command from kubectl flags |
kubectl port-forward pod/web 8080:80 -n dev |
Reach localhost:8080 from your machine |
kubectl delete -f web.yaml |
Delete using the manifest |
Pod phases and container states
| Phase | Meaning |
|---|---|
Pending |
Accepted but not running yet: waiting for scheduling or image pull |
Running |
Bound to a node, at least one container running |
Succeeded |
All containers exited with 0 and will not restart |
Failed |
All containers stopped and at least one failed |
Unknown |
The node cannot be contacted |
Inside kubectl get pods, the STATUS column often shows a container's waiting reason instead: ContainerCreating, ImagePullBackOff (wrong image name, tag, or registry credentials), or CrashLoopBackOff (the container keeps exiting; read kubectl logs --previous).
More probe options
A startupProbe protects slow-starting apps: liveness and readiness checks wait until it succeeds. Probes can be httpGet, tcpSocket, exec (run a command), or grpc. Keep liveness probes simple and independent of other services; a liveness probe that checks the database can restart every pod during a database outage.
Graceful shutdown
When a pod is deleted, Kubernetes removes it from Service endpoints, runs any preStop hook, sends SIGTERM, waits terminationGracePeriodSeconds (30 by default), and then sends SIGKILL. Apps should finish in-flight requests on SIGTERM. A short preStop sleep gives load balancers time to stop sending traffic.
Restart policy and security
restartPolicy is Always for long-running pods, OnFailure or Never for Jobs. A securityContext such as runAsNonRoot: true, readOnlyRootFilesystem: true, and allowPrivilegeEscalation: false hardens a pod in a few lines.
Multi-container patterns and debugging
Sidecar containers, such as a log shipper or proxy, run next to the main container; Kubernetes now supports native sidecars as init containers with restartPolicy: Always, so they start first and stop last. For images without a shell, an ephemeral debug container attaches tools to a running pod:
kubectl debug -it web -n dev --image=busybox:1.36 --target=app