Init containers run when a pod is first initialized. Their job is to run bootstrapping tasks before a pod’s primary application container runs. Init containers are great for separating preparation steps from operations. They run in sequence, each one completing their assigned task before the next init container or any application container runs. If any of them fail, Kubernetes considers the pod unhealthy and attempts to restart the pod’s containers (including the init containers) according to the Pod’s restartPolicy setting.
Using init containers has many benefits, some of my favorites are:
- Leaner application images – all preparation steps are executed in separate, and potentially reusable, containers, offloading utilities that would only be used on boot by the application container anyway
- Easier to spot failures – init container logs are stored separately from app container logs; if the bootstrapping activity was done by the application container in, for example, a “docker-entrypoint.sh” script, you would need to debug the entire script! With init containers, you can simply list logs from the container to see what’s going wrong
- Fewer instances of unprepared or half-running app containers – the main application only starts when init container preparations complete successfully. If any of the Init containers fail to prepare the pod for app execution, the application never starts.
- Security boundaries – privileged system calls can be made by init containers during bootstrapping and restricted at application runtime
In this quick video, we show two ways init containers support app containers within a pod:
Init C1 pulls a generic config file template from a Git repository, renders the template with live values from its environment and saves it to a shared volume.
Init C2 runs a process that retrieves a backup snapshot from an object store, unpacks it, and places it in a persistent volume so that the new pod can pick up where an old one left off.
When the primary application container comes up it mounts to the shared volume to retrieve the template rendered by Init C1 and mounts the persistent volume to initialize itself from the backup prepared by Init C2.