Skip to content

Instantly share code, notes, and snippets.

@surajsaini95
Created May 19, 2020 11:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save surajsaini95/41c0da300bd3d49bfb0425bac506fcc2 to your computer and use it in GitHub Desktop.
Save surajsaini95/41c0da300bd3d49bfb0425bac506fcc2 to your computer and use it in GitHub Desktop.

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.

Thanks for Keeping Up...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment