Home › CKA › Topics › Practice tasks › Sidecars & Init Containers
CKA · Workloads & Scheduling

Sidecars & Init Containers

Update the existing wordpress Deployment in the wordpress-ns namespace, adding a sidecar container named sidecar using the busybox:stable image to the existing pod.

Check live lab access → All CKA tasks

Live lab access

This task description is public. Its live lab requires full access; six other CKA labs are available in Free Practice with AI Lab Coach.

Create an account to continue →

Explore the six free labs with AI Lab Coach →

Read the brief on any device. Use a desktop or laptop for the terminal lab. Nothing starts until you choose Start.

The task

Task

Update the existing wordpress Deployment in the wordpress-ns namespace, adding a sidecar container named sidecar using the busybox:stable image to the existing pod.

The new sidecar container has to run the following command:

/bin/sh -c tail -f /var/log/wordpress.log

Use an emptyDir volume named logs, mounted at /var/log in both the wordpress and sidecar containers, to make the log file wordpress.log available to the co-located container. The volume must be named logs.

Original Prepium workshop · Tested on Kubernetes v1.35.0 on 1 October 2026 in a kind cluster. Native sidecar containers are stable since Kubernetes v1.33 and enabled by default since v1.29. Run this independent example in a disposable cluster.

Share a log file through emptyDir, and see why native sidecars exist

Containers in one Pod share a network namespace but not a filesystem. To let a helper read files the main container writes, mount the same volume into both. An emptyDir volume is created empty when the Pod starts, lives as long as the Pod, and is the standard way to hand files between co-located containers.

The helper can be declared in two ways. A classic sidecar is just another entry under containers. A native sidecar is an entry under initContainers with restartPolicy: Always: it starts before the main containers, keeps running beside them, and is stopped automatically when they finish.

report  ── writes  /logs/app.log ──┐
                                   ├── emptyDir "logs"
shipper ── tail -F /logs/app.log ──┘

1. Run the same Job both ways

Save the classic version as sidecar-classic-job.yaml:

apiVersion: batch/v1
kind: Job
metadata:
  name: report-classic
  namespace: prepium-tutorial
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      volumes:
        - name: logs
          emptyDir: {}
      containers:
        - name: report
          image: busybox:1.36
          command: ["/bin/sh", "-c", "for i in 1 2 3 4 5; do echo line-$i >> /logs/app.log; sleep 2; done"]
          volumeMounts:
            - name: logs
              mountPath: /logs
        - name: shipper
          image: busybox:1.36
          command: ["/bin/sh", "-c", "touch /logs/app.log; tail -F /logs/app.log"]
          volumeMounts:
            - name: logs
              mountPath: /logs

And the native version as sidecar-native-job.yaml. The only structural change is where shipper is declared and its restartPolicy: Always:

apiVersion: batch/v1
kind: Job
metadata:
  name: report-native
  namespace: prepium-tutorial
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      volumes:
        - name: logs
          emptyDir: {}
      initContainers:
        - name: shipper
          image: busybox:1.36
          restartPolicy: Always
          command: ["/bin/sh", "-c", "touch /logs/app.log; tail -F /logs/app.log"]
          volumeMounts:
            - name: logs
              mountPath: /logs
      containers:
        - name: report
          image: busybox:1.36
          command: ["/bin/sh", "-c", "for i in 1 2 3 4 5; do echo line-$i >> /logs/app.log; sleep 2; done"]
          volumeMounts:
            - name: logs
              mountPath: /logs
kubectl create namespace prepium-tutorial
kubectl apply -f sidecar-classic-job.yaml -f sidecar-native-job.yaml
kubectl -n prepium-tutorial get jobs --watch

2. Read the result

After about a minute, report-native shows Complete 1/1. report-classic is still Running 0/1 and stays that way. Look at its Pod:

kubectl -n prepium-tutorial get pods -l job-name=report-classic
kubectl -n prepium-tutorial get pods -l job-name=report-classic \
  -o jsonpath='{range .items[0].status.containerStatuses[*]}{.name}: {.state}{"\n"}{end}'

The Pod is 1/2 NotReady: report terminated with exit code 0, but shipper is still running its tail -F. A Job's Pod only succeeds when all regular containers have exited, and a log follower never exits. This is the problem native sidecars solve. Kubernetes knows shipper in the native version is a sidecar, so it terminates it once report finishes and the Job completes.

3. Prove the volume was shared

kubectl -n prepium-tutorial logs job/report-native -c shipper

The shipper printed line-1 through line-5, which it could only have read from the file report wrote into the shared volume. If you see nothing, compare the mountPath in both containers: the volume name must match the volumes entry and both mounts must point at the directory the writer uses.

4. When the classic form is fine

In a long-running Deployment, the main container never exits either, so a classic sidecar works and is still common in existing manifests and exam tasks. Native sidecars add two guarantees that matter more as Pods get stricter: they are started (and, with a startup probe, ready) before the main containers, and they are stopped after them. If a task tells you exactly which list to put the container in, follow the task. If you are choosing, the native form is the modern default.

Example checkEvidence
Helper container exists with the requested name and imageContainer listed in the Pod spec
Volume is sharedSame volume name mounted in both containers at the expected path
Helper sees the datakubectl logs -c <helper> shows the writer's lines

Cleanup: kubectl delete namespace prepium-tutorial. Reference: Sidecar containers and emptyDir. Next, try init containers and native sidecars on CKAD.

Exam
CKA
Domain
Workloads & Scheduling
Grading
Programmatic · partial credit

What this tests

Run and schedule workloads - deployments, autoscaling, taints and tolerations, affinity, and resource limits. On the CKA exam, Workloads & Scheduling tasks are graded purely on what you build in the cluster - not multiple choice - so the only way to get faster is to do them on a real cluster against a clock.

Practice it for real

The public description lets you study the task before signing up. Full access includes every live lab. Six selected CKA scenarios are included in Free Practice, with five shared sessions each week. You solve the task in a real terminal, hit validate, and a programmatic checker scores exactly what you got right and wrong (with partial credit). You can open the solution while practising, then retry and use the failed checks to improve your score.

Related CKA tasks