1. Multi-container Pod Patterns
Containers in the same Pod share: network (same IP), IPC, and can share storage volumes. Use multiple containers when they need tight coordination.
| Pattern | Role | Real-world Example |
|---|---|---|
| Sidecar | Extend/enhance the main container (same lifecycle) | Log shipper, service mesh proxy (Envoy), config reloader |
| Ambassador | Proxy traffic to/from the main container | Local proxy cache, connection multiplexer |
| Adapter | Transform the main container's output | Metrics format converter (app → Prometheus format) |
Sidecar Pattern:
┌─────────────────────────────────────────────┐
│ POD │
│ ┌──────────────┐ ┌─────────────────┐ │
│ │ App │ │ Log Sidecar │ │
│ │ Container │ │ (Fluentd) │ │
│ └──────┬───────┘ └────────┬────────┘ │
│ │ │ │
│ └──── Shared Volume ──┘ │
│ /var/log/app │
└─────────────────────────────────────────────┘
2. Multi-container Pod YAML
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
- name: web
image: nginx:1.21
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
- name: log-shipper
image: fluent/fluentd:v1.14
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
readOnly: true # Sidecar reads, doesn't write
volumes:
- name: shared-logs
emptyDir: {} # Ephemeral, lost when pod deleted
Exam tip: CKAD often gives tasks to create Pods with a sidecar container. Key points: you need a shared volume for containers to communicate, and both containers must mount the volume at the correct path. Sidecars typically mount with
readOnly: true.
3. Init Containers
Init Containers run before main containers and must complete successfully before the Pod starts. Use for: DB migration, waiting for a dependency, pre-populating a volume.
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
initContainers:
- name: wait-for-db
image: busybox
command: ['sh', '-c', 'until nc -z postgres-service 5432; do sleep 2; done']
- name: db-migrate
image: myapp:1.0
command: ['python', 'manage.py', 'migrate']
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8000
| Property | Init Container | Regular Container |
|---|---|---|
| Execution order | Sequential, all before app | Parallel start |
| Must complete? | Yes (exit 0) | Runs continuously |
| Liveness probe | Not supported | Supported |
| Resources | Counted separately | Normal requests/limits |
4. Cheat Sheet
| Exam Question | Answer |
|---|---|
| Log collection from app container? | Sidecar with shared volume |
| Wait for service before starting? | Init Container |
| Run DB migration before app? | Init Container with migration command |
| Shared storage between containers? | emptyDir volume |
5. Practice Questions
Q1: You need to ensure a Pod's main application only starts after a config file is downloaded from an external URL. What is the best approach?
- A) Use a Sidecar container to download the file
- B) Use an Init Container that runs wget and completes before the main container starts ✓
- C) Use a DaemonSet to pre-populate config on all nodes
- D) Mount a ConfigMap as the initial configuration
Explanation: Init Containers run sequentially before main containers and must complete (exit 0). They're perfect for "prerequisites" like downloading config, waiting for services, or running migrations. Sidecar runs in parallel alongside the main container.
Q2: Two containers in the same Pod need to share data. Container A writes to /tmp/data, Container B reads from /tmp/data. What should you configure?
- A) ExternalDNS shared volume
- B) emptyDir volume mounted at /tmp/data in both containers ✓
- C) A PersistentVolumeClaim for each container
- D) ConfigMap mounted as a volume
Explanation: emptyDir is created when a Pod is assigned to a Node, and deleted when the Pod is removed. It's perfect for sharing ephemeral data between containers in the same Pod. Both containers mount it at the same path.
Q3: A Pod has a single Init Container that keeps failing (exit code 1). What happens to the main application container?
- A) The main container starts after a timeout
- B) The main container is skipped and the Pod succeeds
- C) The main container never starts; Pod shows Init:Error or Init:CrashLoopBackOff ✓
- D) The init container failure is ignored if main container is defined
Explanation: Init Containers MUST exit with code 0. If they fail, Kubernetes restarts them based on Pod's restartPolicy. The main container never starts until all init containers complete successfully.