Kubernetes Init Containers

By Alwyn Botha, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud’s incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

This tutorial lets you use 5 different Pods to learn how Init Containers work. Init Containers are containers that run before the main container runs with your containerized application. They normally contain setup scripts that prepares an environment for you containerized application. Init Containers also ensure the wider server environment is ready for your application to start to run.

You can find a detailed list of what these containers can be used for in the official Kubernetes documentation.

Basic Demo: Init Containers That Just Sleeps (Too Slow)

All the demos in this tutorial have Init Containers that simply just sleeps or exits.

The reason is that this tutorial aims to teach you the syntax and use of Init Containers.

Once you understand this you are welcome to make your Init Containers run all the complex initializations your production applications need.

Let’s create a Pod with 2 Init Containers that just echos and sleeps .

We will then investigate the Pod output to learn what got done and why.

Create the Pod.

Let’s investigate the creation of this Pod over the next 30 seconds.

Here is the output of kubectl get po I ran every 3 seconds — for 30 seconds.

Later on:

The status field describes best what happened:

  • Init:0/2 … Pod initializes
  • Init:1/2 … Init Container 1 running
  • Init:2/2 … Init Container 2 running ( I missed catching that ouput line )
  • PodInitializing … main Pod initializing
  • Running … main Pod is running

This process took 33 seconds, but it is not the fault of Init Containers. ( We will fix that in section 2 )

Init Containers must all complete successfully before the main Pod may run.

All my-init-container-1 had to do was:

command: [‘sh’, ‘-c’, ‘echo my-init-container-1 start; sleep 2;echo my-init-container-1 complete;’]

It did so successfully. We will see the logs in a second.

All my-init-container-2 had to do was:

command: [‘sh’, ‘-c’, ‘echo my-init-container-2 start; sleep 2;echo my-init-container-2 complete;’]

It did so successfully. We will see the logs in a second.

All myapp-container-1 had to do was:

command: [‘sh’, ‘-c’, ‘echo The app is running! && sleep 3600’]

It did so successfully. We will see the logs right now

Note the 2 Init Containers slept for 2 seconds between their start and complete message.

The last output of pod/myapp-pod shows The app is running!

In this very simple demo our 2 Init Containers slept for 2 seconds each ( pretending that to be setup work that will enable our main Pod to run successfully. )

That is the totality of Init Containers : they must run successfully before main Pod runs. They run in sequence … 1 and 2. It’s as simple as that.

Another way to investigate the state of our Pod is to use kubectl describe pod/myapp-pod .

The rest of this tutorial only contains the important state and exit code fields — to understand it more easily.

It is much easier to read the output of this command.

Right at the top

Init Container 1 Terminated because it Completed successfully with exit code 0.

Init Container 2 exact same thing:

Init Container 2 Terminated because it Completed successfully with exit code 0.

myapp-container is Running and ready:

Its command was:

command: [‘sh’, ‘-c’, ‘echo The app is running! && sleep 3600’]

It is now successfully sleeping 3600 seconds.

Why This Demo Took 30 Seconds?

The reason this demo took 30 seconds is since each container had to go pull busybox from the Internet.

We fix that in section 2 of this tutorial.

Basic Demo: Init Containers That Just Sleeps

Delete our previous Pod:

Continue reading below while that is running.

We specify imagePullPolicy: IfNotPresent in the Pod spec below.

That causes the Pod to ONLY go pull our busybox image from the Internet if it is not present on the local server.

Busybox is tiny and your Internet speed may be awesome, this still makes massive time difference.

The second problem this section fix is that that it deletes a Pod immediately.

We do that by specifying terminationGracePeriodSeconds: 0 as you can see in spec below.

Create the YAML file for our Pod 2 using the text below:

Create the Pod.

Investigate to determine if this Pod got running faster:

Look only at last 10 lines of this output. 7 seconds to get main container started versus 33 seconds before.

Note we have 2 Init Containers sleeping 2 seconds each = 4 seconds. So the overall time for just our main container is 3 seconds.

All 3 containers use busybox. Note the message:

Container image “busybox” already present on machine

26 seconds saved getting busybox 3 times on a fast Internet connection.

Unfortunately you cannot use imagePullPolicy: IfNotPresent in your prod environment. In prod you probably should pull your latest image from your private repository every time a Pod is started ( to get the latest version ) .

If we now delete our Pod …

and use

the Pod will be gone: immediately .

terminationGracePeriodSeconds: 0 allows us to quickly test Pods in development .


Determine a proper terminationGracePeriodSeconds for your prod use cases.

Basic Demo: Init Containers That Crash Forever

Init Containers must complete successfully before the main container can run.

Now we demo Init Container number 1 crashing : exit code = 1 … and observe the effects.

Note name: my-init-container-1 command … exit 1

Create the Pod.

kubectl create -f myInitPod-3.yaml

pod/myapp-pod created

Get detail on currently running Pods:

CrashLoopBackOff — this means that container 1 starts, exit 1 crashes, the Kubernetes tries again with same results. Its in a crash loop.

Investigate this further

Look at last 5 lines. Container got started and created 3 times in 20 seconds. It is in a crash loop

Running kubectl get po again.

Restarted 3 times in 89 seconds.

Our Pod is broken. Init Container 2 did not even try running, since Init Container 1 has crashed.

Our main Pod did not even get close to try to run — process stopped at Init Container 1 that crashes repeatedly.

Delete our problem Pod:

Ensure it is gone:

We just proved this is true: Init Containers must complete successfully before the main container can run.

They MUST succeed in creating environment for main container otherwise the main container cannot start.

The default restartPolicy is Always. Pod will continue trying to start forever.

We fix this in next section.

Basic Demo: Init Containers That Crash Just Once

It may be that in your prod environment you want your Pod to terminate immediately when its Init Containers crash.

You do that by specifying restartPolicy: Never in your Pod spec.

Let’s create a Pod with such a spec and see what happens when it encounters an exit code 1 error in its Init Container number one.

Note restartPolicy: Never below:

Investigate Pod status:

30 seconds later

restartPolicy: Never prevents Pod from repeatedly restarting.

At the top we see Init Container 1 terminated with exit code 1.

Init Container 2 state is Waiting for Init Container 1 to finish.

Main container myapp-container is also waiting.

restartPolicy: Never terminates a Pod when it encounters an error.

We can now delete our broken Pod:

Check its gone:

Realistic Production Init Container Simulation

In production, your Init Containers may take longer than a second to finish.

This last section of the tutorial creates 4 Init Containers that each run for 3 seconds.

The main container then sleeps for 10 seconds and exits.

Let’s see what you should normally observe in a live prod environment where all your Init Containers and containers are running successfully.

Note there are no exit 1 ( errors ) in this Pod spec below: just sleep 3 or sleep 10.

I removed terminationGracePeriodSeconds: 0 This simulates a live Pod: it must take the default 30 seconds to terminate gracefully.

Create the Pod.

Here is the output of kubectl get po I ran every 3 seconds — for 30 seconds.

Several noteworthy things here:

  • restarts stay 0 … no errors and no restarts
  • there are 4 Init Containers
  • while Init Container 1 to 4 are busy the READY status is zero
  • only after all 4 Init Containers finish do STATUS change to Running 1/1
  • Running 1/1 this means that one running container out of all ONE existing containers in the Pod.

Init Containers cease after they complete — at the end we have only ONE container running.

Last line STATUS : Completed. Our Pod ran its sleep for 10 seconds ( from age 19 to 30 sec ) then completes successfully.

We can now delete our final Pod:

Check its gone:

Interesting. Pod got deleted immediately. It did not linger in the terminating state for 30 seconds, probably because its STATUS was completed already. It had no final cleanup to do.

This was the state of our Pod before deletion:

Its State: Terminated because of Reason: Completed with Exit Code: 0

It could be deleted immediately since there was nothing running and hence nothing to catch and process a shutdown signal.

Clean Up

No cleanup needed since we deleted the Pods immediately after use.


Written by

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store