A Comprehensive Guide to Kubernetes Pods
1. What is a Pod?
A Pod is the smallest building block in Kubernetes.
A Pod contains one or more running containers.
Pods are always created inside a namespace for logical separation.
Pods are the actual running instances of your application.
Each Pod has a unique IP address within the cluster.
Note : Normally, application pods do not run on the master (control plane) node.
They only run on worker nodes.
But some system pods (like DNS, networking, API server helpers, etc.) may run on the master node because Kubernetes itself needs them for management. These are part of the control plane or system namespaces (like kube-system).
Your app pods → run on worker nodes.
System/management pods → may run on master node (to keep the cluster working).
2. Where Pods Fit in the Kubernetes World
Master Node / Control Plane
The brain of Kubernetes – it has the scheduler, which plans and decides which worker node should run your pod.Worker Nodes
The machines (virtual or physical) that actually run the pods assigned by the master.Kubelet
A helper program on each worker node. It talks to the master, pulls the container images, starts the containers, and keeps checking that the pods are running properly.Container Runtime
Software like Docker or containerd that actually runs the containers inside each pod
3. Pod Characteristics
Smallest Unit
- A Pod is the smallest thing you can create and run in Kubernetes.
Contains Containers
A Pod can have one or more containers inside it.
Most of the time, it has only one container.
Unique IP Address
Each Pod gets its own IP address in the cluster.
All containers inside the pod share that IP.
Shared Network
- Containers inside the same Pod can talk to each other using
localhost.
- Containers inside the same Pod can talk to each other using
Shared Storage
- Containers inside a Pod can use the same storage volumes.
Ephemeral (Temporary)
Pods are not permanent.
If a pod dies, Kubernetes creates a new one, usually with a new IP.
Namespace Scoped
- Pods live inside a namespace (like
dev,test,prod) for logical separation.
- Pods live inside a namespace (like
4. Types of Pods
a) Single-Container Pod
Only one container inside.
Example: Running just a web server.
Understanding Kubernetes Pod YAML
YAML is the way we tell Kubernetes what we want. Kubernetes then takes this YAML and makes it real in the cluster.
Every Kubernetes YAML follows a similar structure:
apiVersion: v1 # Which version of Kubernetes API to use
kind: Pod # What we are creating (Pod, Deployment, Service, etc.)
metadata: # Basic information (name, namespace, labels)
name: my-first-pod
namespace: default
spec: # The "specification" of the Pod
containers: # List of containers inside this Pod
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
Key Sections Explained
apiVersion
Tells Kubernetes which version of the object definition to use.
For Pods → usually
v1.
kind
Defines what you’re creating.
Example:
Pod,Deployment,Service,ConfigMap.
metadata
Name, labels, and namespace.
Example:
name: my-first-pod→ this pod’s name in the cluster.namespace: default→ lives in the default namespace.
spec
The heart of the configuration.
Defines how the pod should run: containers, images, ports, volumes, etc.
A list because a Pod can have multiple containers.
Each container needs:
name→ a unique name inside the podimage→ the container image (from Docker Hub or registryports→ which port this container listens on
How Kubernetes Uses This YAML
- You apply the YAML:
kubectl apply -f pod.yaml
- Kubernetes reads it and asks:
What kind (
Pod)?What’s the name (
my-first-pod)?What container(s) should I run (
nginx:latest)?
The scheduler finds a worker node to host the pod.
The kubelet on that node pulls the image and starts the container.
You can check it with:
kubectl get pods
kubectl get pods -n [namespace name]
b) Multi-Container Pod
A multi-container pod is a pod that runs two or more containers together.
All containers in the pod share:
Network namespace → They can communicate via localhost and share the same IP/ports.
Storage volumes → They can read/write to the same mounted volumes.
Pod lifecycle → They start, stop, and restart together.
Common Use Case: Sidecar Pattern
The Sidecar Pattern pairs a main container with a helper container to add functionality without modifying the main app.

Example:
Main App Container → Runs your primary application (e.g., web server, API).
Helper/Sidecar Container → Performs supporting tasks such as:
Log collection and shipping (e.g., Fluent Bit)
Service proxy (e.g., Envoy, Istio sidecar)
Data synchronization or backup tasks
Multiple containers that must be together.
Often used in the Sidecar Pattern:
Main app container (your application)
Helper container (e.g., log collector, proxy)
apiVersion: v1
kind: Pod
metadata:
name: my-multi-container-pod
spec:
containers:
- name: app-container
image: myapp:latest
ports:
- containerPort: 8080 # App listens on 8080
- name: log-collector
image: fluentd:latest
5. Pod-to-Pod Communication
Same Node:
Pods talk directly via their IPs no extra steps.Different Nodes:
Kubernetes uses a Cluster Network (e.g., Calico, Flannel, Cilium) to make sure pods can talk to each other even if they’re far apart in different machines.
6. Pod Storage
Containers are ephemeral if they restart, data inside disappears.
Solution: Use Volumes.
Common Volume Types:
emptyDir– Temporary storage; gone when the pod stops.hostPath– Uses a folder from the host machine.Persistent Volume (PV) – Storage that stays even if the pod is deleted.
Tip: For databases or apps that store important data, always use Persistent Volumes.
7. Pod Lifecycle
1. Pending
Pod is created but not yet scheduled or started.
Possible scenarios:
No node has enough CPU or memory to host the pod.
Required Persistent Volume (PV) is not yet bound.
Container image is still downloading from the registry.
Scheduling constraints (e.g., nodeSelector, taints/tolerations) prevent placement.
2. Running
Pod has been scheduled to a node, and at least one container is running without issues.
Possible scenarios:
Application is healthy and serving traffic normally.
Containers have passed readiness/liveness probes.
3. Succeeded
All containers in the pod have completed successfully and will not restart.
Possible scenarios:
Batch job finished processing data with no errors.
One-off scripts executed to completion.
4. Failed
All containers have stopped, and at least one exited with a non-zero status.
Possible scenarios:
Wrong command or arguments in the container entrypoint.
Application crashed due to missing files or misconfiguration.
Required services or dependencies were unavailable.
5. CrashLoopBackOff
Pod repeatedly fails, Kubernetes restarts it, but it keeps crashing.
Possible scenarios:
Invalid credentials (e.g., DB connection fails due to wrong username/password).
Missing configMap or secret.
Port conflict (port already in use).
Application bug causing repeated crashes.
Out of Memory (OOMKilled) due to insufficient resources.
6. Unknown
Pod state can’t be determined because the Kubernetes API server has lost communication with the node where the pod was running.
Possible scenarios:
Node is unreachable (network failure or shutdown).
Kubelet crash or kubelet is heavily overloaded and not reporting status.
Cloud node deleted/stopped (e.g., in AWS, GCP, or Azure).
8. Deploying Pods
You can create a pod directly, but in real-world projects, you usually use controllers:
Deployment – For apps that can have many copies (stateless).
StatefulSet – For apps that need a fixed identity (databases).
DaemonSet – Runs one copy of a pod on every node.
Example Pod:
9. Best Practices
Don’t run pods manually in production use Deployments/StatefulSets.
Add liveness and readiness probes to check health.
Keep pods small only related containers inside.
Set resource limits (CPU, memory).
Design apps to handle restarts.
10. Summary
Pods = smallest deployable units in Kubernetes.
They wrap one or more containers with shared networking/storage.
Communication is handled by Kubernetes networking.
Volumes keep data safe beyond container restarts.
11. Kubernetes Pod Commands with Explanation
1. Create Pod
kubectl apply -f pod.yaml
This creates a Pod using the YAML configuration file (
pod.yaml).The YAML file defines what container image, ports, and volumes the Pod should use.
If the Pod already exists, this command will update it.
2. Get Pods
kubectl get pods
kubectl get pods -o wide
Shows all Pods in the current namespace.
kubectl get pods→ Basic info (Pod name, status, age, restarts).kubectl get pods -o wide→ Extra details like Node name, Pod IP, container image etc.
3. Describe Pod
kubectl describe pod <pod-name>
Gives detailed information about a Pod:
Which node it is running on.
What containers are inside.
Events (like scheduling, pulling image, errors).
Resource requests & limits :useful for debugging why a Pod is failing or stuck in Pending/CrashLoopBackOff.
4. Check Logs
kubectl logs <pod-name>
kubectl logs <pod-name> -c <container-name>
Shows logs generated by containers inside the Pod.
For single-container Pods, just use Pod name.
For multi-container Pods, add
-c <container-name>to specify which container’s logs you want. Useful for checking application errors or runtime issues.
5. Enter into Pod (exec)
kubectl exec -it <pod-name> -- /bin/bash
kubectl exec -it <pod-name> -c <container-name> -- /bin/bash
Opens an interactive shell inside a Pod’s container.
-it→ interactive mode (so you can type commands)./bin/bash(or/bin/sh) → type of shell.
Useful for debugging inside the container (checking files, logs, configs).
6. Delete Pod
kubectl delete pod <pod-name>
kubectl delete -f pod.yaml
kubectl delete pod <pod-name>→ remove Pod directly.kubectl delete -f pod.yaml→ remove Pod defined in YAML file.Note: If the Pod was created by a Deployment/ReplicaSet, Kubernetes will automatically recreate it.