Init Containers
In Kubernetes, a Pod is not just a single container. It can hold multiple containers that work together.
Init Containers are special containers that run - and complete - before your main application containers start. They are the "prep cooks" of Kubernetes: they chop the vegetables and prep the station so the "head chef" (your app) can start cooking immediately.
Why Use Them?
- Security: Your main app image can be small and secure (e.g.,
distroless), while the Init Container contains the heavy tools (curl, git, netcat) needed for setup. - Blocking Startup: You can force your app to wait until a Database or API is actually online.
- Sequential Setup: You can chain multiple steps: "Clone Git Repo" $\rightarrow$ "Decrypt Secrets" $\rightarrow$ "Start App".
Visualizing the Flow
Init Containers run sequentially. If you have three Init Containers, Number 2 will not start until Number 1 finishes successfully.
graph LR
subgraph "Pod Lifecycle"
Start((Pod Created)) --> Init1[Init Container 1]
Init1 -->|Success| Init2[Init Container 2]
Init2 -->|Success| Main[Main App Container Starts]
Init1 -.->|Fail| Restart[Restart Pod]
Init2 -.->|Fail| Restart
end
The "Shared Volume" Pattern
The most common use case for Init Containers is to fetch data (like a config file or a plugin) and hand it off to the main application.
Since containers in a Pod share storage, you use a simple emptyDir volume as a "drop box."
- Init Container: Mounts volume at
/data. Downloads file. Exits. - Main Container: Mounts volume at
/config. Reads the file.
apiVersion: v1
kind: Pod
metadata:
name: git-sync-demo
spec:
volumes:
- name: content
emptyDir: {}
initContainers:
- name: git-cloner
image: alpine/git
args:
- clone
- --single-branch
- --
- https://github.com/kubernetes/kubernetes
- /data
volumeMounts:
- name: content
mountPath: /data
containers:
- name: web-server
image: nginx
volumeMounts:
- name: content
mountPath: /usr/share/nginx/html
New in v1.29: Native Sidecars
Historically, Init Containers had to die before the main app started. This made it hard to run "Sidecars" (helper apps like Log Shippers or Service Mesh proxies) that need to start before the app but keep running.
As of Kubernetes v1.29, we have SidecarContainers.
If you set restartPolicy: Always on an init container, Kubernetes treats it as a "Sidecar":
- It starts before the main app.
- It keeps running in the background.
- It does not block the main app from starting (once the sidecar is "Ready").
initContainers:
- name: my-sidecar
image: my-log-agent
restartPolicy: Always # <--- The Magic Switch
Best Practices
- Idempotency: Init containers may run multiple times (if the Pod restarts). Ensure your script handles this (e.g., "If file exists, skip download").
- Lightweight Images: Don't use a 1GB Ubuntu image just to run
sleep 5. Usebusyboxoralpine. - Active Deadline: If your Init Container gets stuck (e.g., trying to reach a firewall-blocked DB), your Pod will be stuck in
Init:0/1forever. SetactiveDeadlineSecondson the Pod if you want it to eventually fail.
Summary
- Init Containers run sequentially and must complete successfully before the main app starts.
- Use them to wait for dependencies or configure data.
- Use Shared Volumes to pass data from the Init Container to the Main Container.
- New Feature: Use
restartPolicy: Alwaysto create Native Sidecars that start first but keep running.