In Docker you run a container. In Kubernetes the smallest unit is a Pod. It is not simply a wrapper around a container — it is a fundamentally different abstraction.
What Is a Pod
A Pod is a group of one or more containers that:
- Start together on the same node
- Share a single network (one IP address,
localhostbetween themselves) - Share the same volumes (a common filesystem)
- Have a shared lifecycle — they start and die together
Most of the time a Pod contains a single container. Multiple containers are used when you need the sidecar pattern: the main application plus a logger, proxy, or agent.
Analogy: a Pod is an apartment. Several tenants (containers) can live there; they share a mailbox (IP address) and a storage room (volume). Tenants communicate freely via localhost.
Creating a Pod Imperatively
# Run a Pod with nginx
kubectl run nginx --image=nginx:1.25
# Run a Pod and get a shell immediately
kubectl run -it busybox --image=busybox --restart=Never -- sh
# Delete a Pod
kubectl delete pod nginx
Creating a Pod Declaratively (YAML)
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
env: production
spec:
containers:
- name: app
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
# Apply the manifest
kubectl apply -f pod.yaml
# Delete via manifest
kubectl delete -f pod.yaml
Multi-Container Pod (Sidecar)
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
containers:
- name: app
image: my-app:1.0
ports:
- containerPort: 8000
- name: log-shipper
image: fluentd:v1.16
volumeMounts:
- name: logs
mountPath: /var/log/app
volumes:
- name: logs
emptyDir: {}
Both containers see the same volume at /var/log/app. The application writes logs; Fluentd collects them.
Pod Lifecycle
Pending → Running → Succeeded
↘ Failed
↘ Unknown
- Pending — the Pod has been accepted by the cluster but is not yet running. The Scheduler is finding a suitable node or the image is being pulled.
- Running — the Pod is placed on a node and at least one container is running.
- Succeeded — all containers exited successfully (exit code 0). Typical for Jobs.
- Failed — at least one container exited with an error.
- Unknown — state cannot be determined (node communication problem).
Individual container statuses within a Pod: Waiting, Running, Terminated.
kubectl Commands for Working with Pods
# List all pods in the default namespace
kubectl get pods
# List with extra info (IP, Node)
kubectl get pods -o wide
# Detailed pod information (events, state)
kubectl describe pod my-app
# Container logs
kubectl logs my-app
# Logs from a specific container in a multi-container Pod
kubectl logs my-app -c log-shipper
# Stream logs in real time
kubectl logs -f my-app
# Execute a command inside the container
kubectl exec -it my-app -- bash
# Forward a pod port to localhost
kubectl port-forward pod/my-app 8080:80
# Example kubectl get pods output
NAME READY STATUS RESTARTS AGE
my-app 1/1 Running 0 5m
busybox 0/1 Completed 0 2m
Why You Should Not Use Pods Directly in Production
A Pod is a mortal unit. If the node goes down or the Pod exits with an error, nothing restarts it — the Pod simply disappears forever.
In production you need to guarantee that the required number of pods is always running. For that you use a Deployment → which creates a ReplicaSet → which manages pods.
The only time you create a Pod directly is for debugging and one-off tasks (kubectl run for diagnostics).
Rule: in production always create a Deployment, never create a Pod directly.
💬 Comments (0)
No comments yet
Be the first to share your opinion about this article!