Kubernetes init containers: Use cases and working examples
Learn how Kubernetes init containers work with two working examples. Covers single init containers, multiple sequential init containers, service dependency checks, and shared volume patterns.
9 lessons · 27 min · Intermediate
Written by
Marketing Team at Civo
Written by
Marketing Team at Civo
Init containers are containers that run to completion before the main container in a pod starts. They run sequentially: the first init container runs and completes, then the second, and so on. The main container does not start until every init container has completed successfully.
Init containers have access to the same volumes, network, and environment as the main container, but their lifecycle is separate. None of the pod's liveness or readiness probes apply to init containers.
Use cases
- Fetching assets or configuration before the main container starts: An init container can download files, render templates, or pull configuration from an internal service and write the result to a shared volume. The main container starts with everything it needs already in place. In production this pattern is commonly used to fetch config from object storage or an internal configuration service rather than public URLs.
- Waiting for a dependency to be ready: An init container can poll a database, a messaging queue, or another service using
nslookuporcurland only complete once the dependency is reachable. This prevents the main container from starting before its prerequisites exist, avoiding crashloopbackoff caused by a missing dependency. - Modifying the filesystem before the main container starts: An init container can set file permissions, write configuration files to a shared volume, or clone a git repository that the main container then uses. This is useful when the main container image cannot be modified but needs certain files or permissions at startup.
- Reducing attack surface: Utilities needed only during setup, such as
curl,wget, or database migration tools, can live in an init container rather than the main container image. The main container image stays lean and does not expose those tools at runtime.
Example 1: single init container with a shared volume
This pod uses an init container to fetch an HTML page from civo.com and write it to a shared volume. The nginx main container then serves that file.
apiVersion: v1kind: Podmetadata:name: init-demo1spec:initContainers:- name: installimage: busyboxcommand: ["wget", "-O", "/work-dir/index.html", "http://civo.com"]volumeMounts:- name: workdirmountPath: /work-dircontainers:- name: nginximage: nginxports:- containerPort: 80volumeMounts:- name: workdirmountPath: /usr/share/nginx/htmlvolumes:- name: workdiremptyDir: {}
Note: the wget pattern above requires the init container to have network access to the target URL. In production, this pattern is more commonly used to fetch configuration from an internal service or object storage endpoint rather than a public URL.
kubectl apply -f init1.yamlkubectl get pods
Expected output while the init container is running:
NAME READY STATUS RESTARTS AGEinit-demo1 0/1 Init:0/1 0 5s
Expected output once the init container completes and nginx starts:
NAME READY STATUS RESTARTS AGEinit-demo1 1/1 Running 0 15s
Exec into the pod and verify nginx is serving the fetched HTML:
kubectl exec -it init-demo1 -- sh
curl localhost
The HTML from civo.com is returned. Exit the pod:
exit
Describe the pod to see the init container lifecycle in the events:
kubectl describe pod init-demo1
In the Events section you will see busybox pulled first, the init container started and completed, and then the nginx container started. The Init Containers section shows what command ran and its exit status.
Example 2: multiple init containers as a dependency gate
This pod has two init containers that check whether two services exist before the main container starts. The pod stays in a waiting state until both services are reachable.
apiVersion: v1kind: Podmetadata:name: init-demo2spec:initContainers:- name: wait-for-appserviceimage: busyboxcommand: ["sh", "-c", "until nslookup appservice; do echo waiting for appservice; sleep 2; done"]- name: wait-for-dbserviceimage: busyboxcommand: ["sh", "-c", "until nslookup dbservice; do echo waiting for dbservice; sleep 2; done"]containers:- name: mainimage: busyboxcommand: ["sh", "-c", "echo main container started && sleep 3600"]
Apply the pod before the services exist:
kubectl apply -f init2.yamlkubectl get pods
Expected output — neither init container has completed:
NAME READY STATUS RESTARTS AGEinit-demo2 0/1 Init:0/2 0 10s
Describe the pod to see which init container is running:
kubectl describe pod init-demo2
In the Init Containers section you will see wait-for-appservice in Running state and wait-for-dbservice in Waiting state. The pod status shows Init:0/2.
Now create the services the init containers are waiting for:
kubectl apply -f init2svc.yaml
Watch the pod transition:
kubectl get pods -w
Expected output as each init container completes:
NAME READY STATUS RESTARTS AGEinit-demo2 0/1 Init:0/2 0 30sinit-demo2 0/1 Init:1/2 0 35sinit-demo2 0/1 PodInitializing 0 40sinit-demo2 1/1 Running 0 45s
Init:0/2 means no init containers have completed. Init:1/2 means the first has completed and the second is running. PodInitializing means both init containers have completed and the main container is starting.

Marketing Team at Civo
Civo is the Sovereign Cloud and AI platform designed to help developers and enterprises build without limits. We bridge the gap between the openness of the public cloud and the rigorous security of private environments, delivering full cloud parity across every deployment. As a team, we are dedicated to providing scalable compute, lightning-fast Kubernetes, and managed services that are ready in minutes. Through CivoStack Enterprise and our FlexCore appliance, we empower organizations to maintain total data sovereignty on their own hardware.
Our mission is to make the cloud faster, simpler, and fairer. By providing enterprise-grade NVIDIA GPUs and streamlined model management, we ensure that high-performance AI and machine learning are accessible to everyone. Built for transparency and performance, the Civo Team is here to give you total control over your infrastructure, your data, and your spend.
Share this lesson