Kubernetes Init Container

In many scenarios, the following initialization operations are required before starting an application.

  • Wait for other associated components (such as a database or a background service) to run correctly.
  • Generate configuration files based on environment variables or configuration templates.
  • Get the required configuration locally from a remote database, or register yourself into some central data.
  • Download a dependency package or do some pre-configuration on the system.

Kubernetes V1.3 introduced a new special init Container for the Alpha version (which was updated to the Beta version in Kubernetes V1.5), It is used to start one or more “initialization” containers before starting app Containers to complete the preconditions required by the application containers. Init Containers are essentially the same as application containers, but they are one-run tasks that must be successfully executed before the system moves on to the next container. According to the Pod RestartPolicy, if init Container fails and RestartPolicy is set to Never, the Pod will fail to start. If RestartPolicy=Always is set, the Pod is automatically restarted.

After v1.8, the Init Container feature was fully mature and its definition was put into Pod spec.initContainers.

The following uses the Nginx application as an example. Before starting Nginx, initialize busyBox to create an index.html home file for Nginx. A shared volume is set up for init Container and Nginx to provide Nginx access to the index.html set by init Container.

nginx-init-containers.yaml

apiVersion: v1``kind: Pod``metadata:``  ``name: nginx``  ``annotations:``spec:``  ``initContainers:``  ``- name: ``install``    ``image: busybox``    ``command``:``    ``- wget``    ``- ``"-O"``    ``- ``"/work-dir/index.html"``    ``- http:``//kubernetes``.io``    ``volumeMounts:``    ``- name: workdir``      ``mountPath: ``"/work-dir"``  ``containers:``  ``- name: nginx``    ``image: nginx``    ``ports:``    ``- containerPort: 80``    ``volumeMounts:``    ``- name: workdir``      ``mountPath: ``"/usr/share/nginx/html"``  ``dnsPolicy: Default``  ``volumes:``  ``- name: workdir``    ``emptyDir: {}

Create this Pod:

$ kubectl apply -f nginx-init-containers.yaml

The init process is not complete:

$ kubectl get po nginx``NAME      READY     STATUS     RESTARTS   AGE``nginx     0``/1       Init:0``/1   0          23s``# or``$ kubectl get po``NAME      READY     STATUS            RESTARTS   AGE``nginx     0``/1       PodInitializing   0          1m

After the init container completes successfully, the system continues to expect the Nginx container to check the Pod status again:

$  kubectl get po nginx``NAME      READY     STATUS    RESTARTS   AGE``nginx     1``/1       Running   0          1m

When the Pod is installed, you can see that the system first creates and runs the init container (named install) and then continues to create and run the Nginx container:

$ kubectl describe po nginx

Execute the process to expand the source code

Nginx container contains the index.html file from init Container.

$ kubectl ``exec -it nginx ``cat /usr/share/nginx/html/index``.html

Execution result Expand the source code

The differences between an Init Container and an application container are as follows:

(1) The operation mode of init Containers is different from that of application containers. They must be executed before application containers. When multiple Init containers are set, they are run one by one. And you can run an init Container only after the previous init Container runs successfully. After all init Containers have run successfully, Kubernetes initializes the Pod information and starts creating and running the application container.

(2) You can also set resource limits, volume usage, and security policies in init Container definitions. However, resource limits are set slightly differently from application containers.

  • If multiple Init Containers define resource request/resource limits, the maximum value is taken as the resource request/resource limit value for all init Containers.
  • The effective resource request/resource limit value of Pod takes the greater of the following. A) Sum of resource request values/resource limit values of all application containers. B) Init Container valid resource request value/resource limit value.
  • The scheduling algorithm is calculated based on Pod’s valid resource request/resource limit values, which means that init Container can reserve system resources for initialization, even if subsequent application containers do not need to use these resources.
  • The valid QoS level of Pod applies to init Containers and application containers.
  • Resource quotas and limits will be based on Pod’s valid resource requests/limits, consistent with the scheduling mechanism.
  • Init Container cannot set readinessProbe probes because they must run successfully before normal containers defined in Pod can continue to run.

During a Pod Restart, init Container will be restarted. The scenario for a Pod Restart is as follows:

  • When the image of the Init Container is updated, the Init Container will run again, causing the Pod to restart. Only updating the application container will restart the application container.
  • When the Pod infrastructure container (Pause) is updated, the Pod restarts.
  • If all application containers in Pod have stopped and RestartPolicy=Always, Pod will restart.