TL;DR (Quick Summary)#
- Sidecar Pattern: Extends primary container capabilities (e.g., streaming logs to S3, fetching secret tokens).
- Adapter Pattern: Standardizes output from the primary container (e.g., transforming legacy log formats to JSON).
- Ambassador Pattern: Acts as a local proxy for outgoing database connections (e.g., proxying DB traffic to Redis or Cloud SQL).
- InitContainers: Run sequentially to completion before app containers start (e.g., waiting for a database port to open).
1. Multi-Container Pod Architecture Patterns#
graph TD
subgraph SidecarPattern ["1. Sidecar Pattern"]
App1["App Container
(Writes /var/log/app.log)"] <== Shared Volume ==> Sidecar1["Log Shipper Container
(Streams to Elastic/S3)"]
end
subgraph AdapterPattern ["2. Adapter Pattern"]
App2["Legacy App
(Plaintext Metrics)"] --> Adapter2["Adapter Container
(Transforms to Prometheus format)"]
end
subgraph AmbassadorPattern ["3. Ambassador Pattern"]
App3["App Container
(Connects to localhost:6379)"] --> Ambassador3["Proxy Container
(Routes to Redis Cluster)"]
end
2. Hands-on Manifests & Terminal Drills#
Pattern A: Sidecar Log Collector Pod#
Create a Pod named sidecar-pod where the primary app writes log entries to a shared /var/log volume, and a sidecar container reads and outputs them to standard output.
sidecar-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: sidecar-pod
namespace: default
spec:
volumes:
- name: log-volume
emptyDir: {}
containers:
- name: main-app
image: busybox:1.36
command: ["/bin/sh", "-c", "while true; do echo '$(date) INFO Processing order' >> /var/log/app.log; sleep 2; done"]
volumeMounts:
- name: log-volume
mountPath: /var/log
- name: sidecar-logger
image: busybox:1.36
command: ["/bin/sh", "-c", "tail -n+1 -f /var/log/app.log"]
volumeMounts:
- name: log-volume
mountPath: /var/logApply and verify sidecar logging output:
kubectl apply -f sidecar-pod.yaml
kubectl logs -f sidecar-pod -c sidecar-loggerPattern B: InitContainer Database Pre-flight Check#
Create a Pod named web-app that uses an initContainer to wait until a database service db-service is reachable on port 5432 before starting the main container.
init-container-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
initContainers:
- name: check-db-ready
image: busybox:1.36
command: ['sh', '-c', 'until nc -z -w 2 db-service 5432; do echo "Waiting for DB..."; sleep 2; done;']
containers:
- name: main-web
image: nginx:1.25-alpine
ports:
- containerPort: 80Verify InitContainer execution status:
kubectl get pod web-app -w
# Output transitions: Init:0/1 -> PodInitializing -> Running3. CKAD Speed Tips for Multi-Container Pods#
Do NOT write Pod YAML from scratch! Generate the multi-container template using kubectl dry-run:
kubectl run sidecar-pod --image=busybox:1.36 --dry-run=client -o yaml -- sh -c "sleep 3600" > pod.yamlOpen pod.yaml in Vim and duplicate the containers: block (yy then p in Vim).
Summary & Next Steps#
In this episode, we covered:
- Sidecar, Adapter, and Ambassador multi-container design patterns.
- Pre-flight setup using
initContainers. - Generating dry-run YAML templates rapidly for CKAD exam tasks.
In CKAD Episode 2: Deployments, Rollouts & Canary Releases, we will master zero-downtime deployment updates, rollback revisions, and Helm chart releases!

