Introduction
A sidecar container runs in the same Pod as an application container and supports the application while it is running. This is different from an init container, which must finish before the app starts. Sidecars are commonly used for log shipping, proxying, synchronization, or other helper behavior that should share the Pod lifecycle.
In this lab, you will create a multi-container Pod with an app container that writes log lines into a shared emptyDir volume and a sidecar container that follows that file. You will inspect both containers, read sidecar logs, and then put the same sidecar pattern into a Deployment template.
Prepare a Sidecar Namespace
In this step, you will prepare a clean namespace for sidecar practice.
Start in /home/labex/project. You will write a Pod manifest and a Deployment manifest in this directory.
mkdir -p /home/labex/project
cd /home/labex/project
Check that the Kubernetes API server is reachable. If the VM has just started and the node is not ready yet, wait a few seconds and run the command again.
kubectl get nodes --request-timeout=5s
Expected output includes:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
Wait until the cluster networking Pod is Ready before creating workloads.
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
Expected output:
pod/calico-node-... condition met
Create a namespace named ckad-prep-sidecar:
kubectl create namespace ckad-prep-sidecar
Set this namespace as the current context namespace:
kubectl config set-context --current --namespace=ckad-prep-sidecar
Confirm the current namespace:
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
Expected output:
ckad-prep-sidecar
Create a Multi-Container Pod
In this step, you will create a Pod with an application container and a sidecar container.
Both containers mount the same emptyDir volume at /var/log/shared. The app container writes log lines into /var/log/shared/app.log. The sidecar container runs at the same time and uses tail -f to stream that file. The touch command creates the file before tail -f starts, so the sidecar can wait safely even if the app has not written its first line yet.
Create sidecar-pod.yaml:
cat > sidecar-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: sidecar-demo
labels:
app: sidecar-demo
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: shared-logs
emptyDir: {}
containers:
- name: app
image: busybox:1.36
command:
- /bin/sh
- -c
- 'i=1; while true; do echo "app-line-${i}" >> /var/log/shared/app.log; i=$((i+1)); sleep 2; done'
volumeMounts:
- name: shared-logs
mountPath: /var/log/shared
- name: log-sidecar
image: busybox:1.36
command:
- /bin/sh
- -c
- 'touch /var/log/shared/app.log; tail -n +1 -f /var/log/shared/app.log'
volumeMounts:
- name: shared-logs
mountPath: /var/log/shared
EOF
Apply the manifest:
kubectl apply -f sidecar-pod.yaml
Expected output:
pod/sidecar-demo created
Wait until the Pod is Ready. A multi-container Pod is Ready only when all regular containers are ready.
kubectl wait --for=condition=Ready pod/sidecar-demo --timeout=120s
Expected output:
pod/sidecar-demo condition met
List the container names in the Pod:
kubectl get pod sidecar-demo -o 'jsonpath={.spec.containers[*].name}{"\n"}'
Expected output:
app log-sidecar
Inspect Sidecar Collaboration
In this step, you will confirm that both containers are running and that the sidecar is streaming the app's log file.
First inspect container readiness. The output prints each container name and whether it is ready.
kubectl get pod sidecar-demo -o 'jsonpath={range .status.containerStatuses[*]}{.name}{" "}{.ready}{"\n"}{end}'
Expected output includes:
app true
log-sidecar true
Read the app container logs. The app writes normal stdout only when the shell command starts; its repeated lines go into the shared file.
kubectl logs sidecar-demo -c app --tail=5
The app container may not print repeated lines to stdout. The important evidence is in the shared file and the sidecar logs.
Read the shared file through the app container:
kubectl exec sidecar-demo -c app -- sh -c 'tail -n 3 /var/log/shared/app.log'
Expected output includes app log lines:
app-line-...
app-line-...
app-line-...
Now read the sidecar logs. Because the sidecar tails the same file, its logs should include the same kind of lines.
kubectl logs sidecar-demo -c log-sidecar --tail=3
Expected output includes:
app-line-...
app-line-...
app-line-...
Add the Sidecar Pattern to a Deployment
In this step, you will put the sidecar pattern into a Deployment template.
Standalone Pods are useful for learning, but applications usually run through controllers. A Deployment can create replacement Pods, and each replacement Pod will include both the app container and the sidecar container from the template.
Create sidecar-deployment.yaml:
cat > sidecar-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: sidecar-worker
spec:
replicas: 1
selector:
matchLabels:
app: sidecar-worker
template:
metadata:
labels:
app: sidecar-worker
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: shared-logs
emptyDir: {}
containers:
- name: app
image: busybox:1.36
command:
- /bin/sh
- -c
- 'i=1; while true; do echo "worker-line-${i}" >> /var/log/shared/worker.log; i=$((i+1)); sleep 2; done'
volumeMounts:
- name: shared-logs
mountPath: /var/log/shared
- name: log-sidecar
image: busybox:1.36
command:
- /bin/sh
- -c
- 'touch /var/log/shared/worker.log; tail -n +1 -f /var/log/shared/worker.log'
volumeMounts:
- name: shared-logs
mountPath: /var/log/shared
EOF
Apply the Deployment:
kubectl apply -f sidecar-deployment.yaml
Expected output:
deployment.apps/sidecar-worker created
Wait until the Deployment is available:
kubectl wait --for=condition=Available deployment/sidecar-worker --timeout=120s
Expected output:
deployment.apps/sidecar-worker condition met
Find the Pod created by the Deployment:
worker_pod="$(kubectl get pods -l app=sidecar-worker -o 'jsonpath={.items[0].metadata.name}')"
echo "$worker_pod"
Expected output shows a generated Pod name:
sidecar-worker-...
Read the sidecar logs from the Deployment-created Pod:
kubectl logs "$worker_pod" -c log-sidecar --tail=3
Expected output includes:
worker-line-...
worker-line-...
worker-line-...
Summary
You created a multi-container Pod with an app container and a sidecar container, used an emptyDir volume to share a log file, confirmed that both containers run together, and moved the same sidecar pattern into a Deployment template. You now know when a sidecar fits: it supports the application while the application is running.


