Pods & YAML
Pods & YAML
TL;DR
- Pod is smallest deployable unit in Kubernetes—containers deployed to pods, not directly to nodes
- All containers in a pod share one network namespace (IP, ports), storage volumes, and IPC namespace
- YAML manifests require four keys:
apiVersion,kind,metadata,spec - Imperative commands (
kubectl run) are fast but not auditable; declarative YAML enables GitOps - Port binding within a pod is shared—two containers cannot bind the same port in same namespace
- Bare pods don’t reschedule on node failure; use Deployments/StatefulSets for high availability
Core Concepts
What Is a Pod?
Pod is a logical wrapper containing one or more containers that share runtime resources:
- Network namespace: Shared IP address, port space, network interface. Containers reach each other via
localhost - Storage volumes: Mount shared storage directories accessible by all containers
- IPC namespace: Inter-process communication via shared memory
Mental model: Pod = virtual machine; containers = processes running inside it.
YAML Manifest Structure
Every Kubernetes resource needs four root keys:
apiVersion: v1 # API schema (v1 for Pods/Services, apps/v1 for Deployments)
kind: Pod # Resource type
metadata: # Identification
name: web-server
namespace: default
labels:
app: frontend
spec: # Desired configuration
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
Imperative vs. Declarative
Imperative: Direct commands telling Kubernetes what to do. Quick for one-offs; not auditable or version-controlled.
kubectl run web --image=nginx:alpine --port=80
Declarative: Write YAML files defining desired state; apply with kubectl apply. Version-controllable (Git), repeatable, self-documenting; enables GitOps.
kubectl apply -f pod.yaml
Pod Lifecycle Phases
- Pending: API accepted pod; waiting for scheduling or image download
- Running: Scheduled to node; at least one container starting/running
- Succeeded: All containers exited with status 0; won’t restart (typical for Jobs)
- Failed: Containers exited; at least one failed with non-zero status
- Unknown: API lost contact with node’s kubelet
Comparison Table
| Aspect | Imperative Commands | Declarative YAML |
|---|---|---|
| Speed | Fast—immediate execution | Slower—write file, apply, reconcile |
| Auditability | Not stored; changes lost | Version-controlled in Git |
| Repeatability | Manual re-run needed | kubectl apply reapplies as-is |
| GitOps friendly | No | Yes |
| Best for | Diagnostics, CKA exam | Production, long-term management |
Command & Configuration Reference
Generate YAML Template
# Create without applying
kubectl run diagnostic-pod --image=busybox --dry-run=client -o yaml > pod.yaml
# View generated template
cat pod.yaml
Apply/Update Manifests
# Create or update (idempotent)
kubectl apply -f pod.yaml
# Apply from stdin
kubectl apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- name: nginx
image: nginx:alpine
EOF
Inspect Pod State
# Get YAML representation of running pod
kubectl get pod web -o yaml
# Watch pod status changes
kubectl get pod web --watch
# Show pod events
kubectl describe pod web
Delete Pods
# Graceful delete (30s grace period by default)
kubectl delete pod web
# Force immediate deletion
kubectl delete pod web --grace-period=0 --force
Common Pitfalls
Pitfall: Port Conflicts in Multi-Container Pods Two containers in same pod both bind port 8080.
- Why: Containers share network namespace and IP. Port conflicts occur like on a single OS.
- Fix: Assign different ports to each container or use init containers for port binding orchestration.
Pitfall: Bare Pods Without High Availability Deploying raw Pod manifests and expecting self-healing on node failure.
- Why: Bare pods are unmanaged; if node crashes, pod is lost forever. No controller reschedules it.
- Fix: Always use Deployment, StatefulSet, or DaemonSet to wrap pods. Controllers detect pod death and reschedule.
Pitfall: Assuming Pod IP Persistence Code or config hardcodes a pod IP address for service-to-service communication.
- Why: Pods are ephemeral; IPs change whenever pods restart or reschedule.
- Fix: Use Kubernetes Services with stable DNS names (e.g.,
http://backend:8080). CoreDNS resolves to current pod IPs.
Interview Questions
Q — What do all containers within the same pod share? How does this affect port binding? All containers in a pod share a network namespace (same IP, port space) and can mount shared storage volumes. Port binding is shared across containers—if container A binds port 8080, container B cannot bind the same port on the same pod IP. Attempting to do so causes container B to crash with address-already-in-use error.
Q — Describe the four mandatory YAML keys in a Kubernetes manifest and their purposes.
apiVersion defines the API schema and parsing rules. kind specifies the resource type (Pod, Deployment, Service, etc.). metadata contains identification info (name, namespace, labels for organization). spec contains the actual configuration details defining the resource’s desired state (container images, ports, resource limits, storage mounts).
Q — Compare imperative and declarative approaches to managing pods. When would you use each?
Imperative commands (kubectl run) are quick for diagnostics or one-off operations but not auditable or repeatable. Declarative YAML files are version-controllable, repeatable, self-documenting, and enable GitOps; suitable for production. In the CKA exam, use imperative commands for speed on familiar tasks; in production, use declarative YAML for traceability and collaboration.