Init Containers in Kubernetes
This is the era of containerization and orchestration where majority of the application are following the trend of running on a container which are further deployed in a Kubernetes cluster. It’s sometimes necessary to prepare the main container which will be running our application or the main logic.
There can also be situations where we need to execute a particular utilities or setup scripts that are not present in our main image ( as it would make it heavy and we only need it once in the beginning ).
What are Init Containers ?
Kubernetes provides special type of containers that runs to completion before the main app's container and Kubernetes will repeatedly restarts the Pod until the init container succeeds. Some of its properties are :
- Contains utilities or setup scripts not present in an app image ( making images light-weight)
- always run to completion
- if you specify multiple init containers for a Pod, Kubelet will runs each init container sequentially and each of the init container must succeed before the next can run.
- init containers support all the fields and features of app containers, including resource limits, volumes, and security settings.
Lets create a pod with init-container
Here in this example we have contains 2 init-container where the first container will simply print a message and second one will sleep for 30 seconds after which our main container will come into action.
apiVersion: v1 kind: Pod metadata: name: simple-pod1 labels: purpose: initContainers-demo spec: initContainers: - name: init-busybox1 image: busybox command: ["echo","I am init-conatiner"] - name: init-busybox2 image: busybox command: ["sleep","30"] containers: - name: main-busybox image: busybox command: ["echo","Hello main container"] restartPolicy: Never
Now bring this pod up and you must get similar output
$ kubectl apply -f simple-pod.yml pod/simple-pod1 created //you can see the status of init-container $ kubectl get pods NAME READY STATUS RESTARTS AGE simple-pod1 0/1 Init:0/1 0 27s //and the pod comes to the the completion after a minimun of 30s (sleep time of second init-container) $ kubectl get po NAME READY STATUS RESTARTS AGE simple-pod1 0/1 Completed 0 36s
How they come in Action !
First the kubelet will wait until the networking and storage are ready so that it can start running init containers.
It then runs the Pod’s init containers in the order they appear in the Pod’s spec.
Each init container must exit successfully before the next container starts.
A Pod cannot be in Ready state until all init containers have succeeded.
If the Pod Restarts, or is restarted, all init containers are executed again.
Note : Altering an init container image field is equivalent to restarting the Pod.
Few Use Cases
- Init containers can contain utilities or custom code for setup that are not present in an app image.
- They can be given access to Secrets that app containers cannot access.
- Clone a Git repository into a Volume
- It can be used to wait for a service to start that is to be used by main app
- An init container is a good candidate for delaying the application initialization until one or more dependencies are available.
Real life example
While setting-up an Elasticsearch cluster we all have gone through the situation in which we need to set few things before running the main container .
role: elastic-master spec: initContainers: - name: init-container1 image: busybox command: - sysctl - -w - vm.max_map_count=262144 securityContext: privileged: true - name: init-container2 image: busybox:latest command: - sh - -c - chown -R 1000:1000 /usr/share/elasticsearch/data securityContext: privileged: true volumeMounts: - name: elastic-master-vol mountPath: /usr/share/elasticsearch/data containers: - name: elastic-master-container image: docker.elastic.co/elasticsearch/elasticsearch:7.7.0 env: - name: node.name valueFrom: fieldRef: fieldPath: metadata.name - name: cluster.name value: "elasticsearch-cluster" - name: node.master
In the above snippet of the yaml file we are setting the value for vm.max_map_count and we are also changing the access permission for the mounted directory that the elasticsearch will use when it starts.
Lets sum-up !!!
Init-containers are special containers and Kubernetes will always execute them to completion before the main container(s) are executed. They can also be used in scenarios where you might want to wait for a service being available, want to configure things at runtime, or init some data in a database.
Also init-containers do not support lifecycle, liveness probe, readiness probe, or startup probe because they must run to completion.