Kubernetes Init Containers: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
 
(18 intermediate revisions by the same user not shown)
Line 9: Line 9:
=Overview=
=Overview=


An ''init container'' is a specialized container that runs before the [[Kubernetes_Pod_and_Container_Concepts#Application_Containers|application containers]], and can contain utilities or setup scripts not present in the application image. If a pod declares init containers, the application containers are only run after all init container complete successfully.
An '''init container''' is a specialized container that runs before the [[Kubernetes_Pod_and_Container_Concepts#Application_Containers|application containers]], and can contain utilities or setup scripts not present in the application image. If a pod declares init containers, the application containers are only run after all init container complete successfully.


An init container always runs to completion, and if more than one init containers are declared, each one is executed sequentially and must complete successfully before the next one is started. This is the reason init containers do not support readiness probes: they must succeed. If an init container fails, Kubernetes will restart the Pod repeatedly until the init container succeeds, unless the pod has a "[[Kubernetes_Pod_and_Container_Concepts#Container_Restart_Policy|restartPolicy]]" of "Never".
An init container always runs to completion, and if more than one init containers are declared, each one is executed sequentially and must complete successfully before the next one is started. This is the reason init containers do not support readiness probes: they must succeed. If an init container fails, Kubernetes will restart the Pod repeatedly until the init container succeeds, unless the pod has a "[[Kubernetes_Pod_and_Container_Concepts#Container_Restart_Policy|restartPolicy]]" of "Never".


While an init container is executed, it shows as "Init:*/*", alongside the deployment container.
While an init container is executed, it shows as "Init:*/*", alongside the deployment container (also see [[Kubernetes_Pod_and_Container_Concepts#Pod_Status|Pod Status]]).


  kubectl get pods
  kubectl get pods
Line 23: Line 23:


Init containers can be used to run utilities that do not belong in application [[Kubernetes_Pod_and_Container_Concepts#Application_Containers|application container]] images for security reasons. They can also contain utilities for setup or dependency wait loops: they run to completion before any application containers start, whereas application containers run in parallel, so init containers provide an easy way to block or delay the startup of application containers until some set of preconditions are met. The application image builder and deployer roles can work independently without the need to jointly build a single application image. Because they use Linux namespaces so that they have different filesystem views from application containers, they can be given access to Secrets that application containers should not be able to access.
Init containers can be used to run utilities that do not belong in application [[Kubernetes_Pod_and_Container_Concepts#Application_Containers|application container]] images for security reasons. They can also contain utilities for setup or dependency wait loops: they run to completion before any application containers start, whereas application containers run in parallel, so init containers provide an easy way to block or delay the startup of application containers until some set of preconditions are met. The application image builder and deployer roles can work independently without the need to jointly build a single application image. Because they use Linux namespaces so that they have different filesystem views from application containers, they can be given access to Secrets that application containers should not be able to access.
='initContainers' Pod Manifest Section=
The pod manifest section corresponding to '[[Kubernetes_Pod_Manifest#initContainers|initContainers]]' has the same schema as the sections corresponding to the main '[[Kubernetes_Pod_Manifest#containers|containers]]' section.
For more details see: {{Internal|Kubernetes_Pod_Manifest#initContainers|Pod Manifest}}


=Lifecycle and Behavior=
=Lifecycle and Behavior=
Line 28: Line 34:


==Timeout==
==Timeout==


An init container must finish initializing within <font color=darkgray>TODO: how much?</font> otherwise it puts the deployment into an error state:
An init container must finish initializing within <font color=darkgray>TODO: how much?</font> otherwise it puts the deployment into an error state:
Line 34: Line 39:
  NAME        READY    STATUS    RESTARTS  AGE
  NAME        READY    STATUS    RESTARTS  AGE
  a-1-deploy  0/1      Error    0          13m
  a-1-deploy  0/1      Error    0          13m
==Pod Status Relative to init Containers==
As reported by <code>kubectl get pods</code>.
* <code>Init:N/M</code> The pod has M init containers, and N have completed so far.
* <code>Init:Error</code> An init container has failed to execute.
* <code>Init:CrashLoopBackOff</code> An init container has failed repeatedly.
* <code>Pending</code>. In respect to init containers, the pod has not yet begun executing init containers.
* <code>Running</code>. In respect to init containers, the pod has already finished executing the init containers.
* <code>ContainerCreating</code>.
* <code>PodInitializing</code>. In respect to init containers, the pod has already finished executing the init containers.


=Resources=
=Resources=
Line 41: Line 56:
=Examples=
=Examples=


==Service Dependency==
==Service Dependency with nslookup==
 
An init container can be used to ensure that a [[Kubernetes_Service_Concepts#Service|service]] the pod depends on is up and endpoints have been associated with it. A service can be looked up in DNS after it reaches that state, so we can use nslookup from the init container. A typical init container checking on the availability of a service with nslookup is configured as follows:
 
<syntaxhighlight lang='yaml'>
apiVersion: apps/v1
kind: Deployment
spec:
  ...
  template:
    spec:
      initContainers:
        - name: wait-on-cassandra
          image: busybox:1.28
          command: ['sh', '-c', 'until nslookup cassandra; do echo waiting for cassandra to start ...; sleep 2; done']
    ...
</syntaxhighlight>
 
"cassandra" is the name of the service that gives access to Cassandra pods.
 
{{Warn|We found that some busybox images introduced nslookup problems - nslookup did not work as expected. 1.28 is one of those images that works well.}}
 
==Init Container that Timeouts after a While==


An init container can be used to ensure that a [[Kubernetes_Service_Concepts#Service|service]] the pod depends on is up and endpoints have been associated with it.
<syntaxhighlight lang='yaml'>
apiVersion: apps/v1
kind: Deployment
spec:
  ...
  template:
    spec:
      initContainers:
        - name: timeout-init-container
          image: busybox:1.28
          command:
            - /bin/sh
            - -c
            - 'timeout_sec=20; t0=$(date +%s); while [ $(expr $(date +%s) - ${t0} - ${timeout_sec}) -lt 0 ]; do echo .; sleep 1; exit 0; done; exit 1'
    ...
</syntaxhighlight>


==Application Dependency with curl==
==Application Dependency with curl==


{{External|https://github.com/NovaOrdis/playground/tree/master/openshift/applications/service-dependency}}
{{External|https://github.com/NovaOrdis/playground/tree/master/openshift/applications/service-dependency}}
=Troubleshooting=
The stdout/stderr of an init container can be displayed with:
kubectl logs [-f] -c <''init-container-name''> <''pod-name''>
More on [[Kubernetes_Pod_Operations#Troubleshooting_Containers|troubleshooting pods and containers]].

Latest revision as of 23:33, 26 September 2021

External

Internal

Overview

An init container is a specialized container that runs before the application containers, and can contain utilities or setup scripts not present in the application image. If a pod declares init containers, the application containers are only run after all init container complete successfully.

An init container always runs to completion, and if more than one init containers are declared, each one is executed sequentially and must complete successfully before the next one is started. This is the reason init containers do not support readiness probes: they must succeed. If an init container fails, Kubernetes will restart the Pod repeatedly until the init container succeeds, unless the pod has a "restartPolicy" of "Never".

While an init container is executed, it shows as "Init:*/*", alongside the deployment container (also see Pod Status).

kubectl get pods
NAME         READY     STATUS     RESTARTS   AGE
a-1-7k94g    0/1       Init:0/1   0          3m
a-1-deploy   1/1       Running    0          3m

Init containers support all the fields and the features of the application containers including resource limits, volumes and security settings. However, the resource requests and limits for an init container are handled slightly differently, as described in Resources below.

Init containers can be used to run utilities that do not belong in application application container images for security reasons. They can also contain utilities for setup or dependency wait loops: they run to completion before any application containers start, whereas application containers run in parallel, so init containers provide an easy way to block or delay the startup of application containers until some set of preconditions are met. The application image builder and deployer roles can work independently without the need to jointly build a single application image. Because they use Linux namespaces so that they have different filesystem views from application containers, they can be given access to Secrets that application containers should not be able to access.

'initContainers' Pod Manifest Section

The pod manifest section corresponding to 'initContainers' has the same schema as the sections corresponding to the main 'containers' section.

For more details see:

Pod Manifest

Lifecycle and Behavior

init Containers - Detailed Behavior

Timeout

An init container must finish initializing within TODO: how much? otherwise it puts the deployment into an error state:

NAME         READY     STATUS    RESTARTS   AGE
a-1-deploy   0/1       Error     0          13m

Pod Status Relative to init Containers

As reported by kubectl get pods.

  • Init:N/M The pod has M init containers, and N have completed so far.
  • Init:Error An init container has failed to execute.
  • Init:CrashLoopBackOff An init container has failed repeatedly.
  • Pending. In respect to init containers, the pod has not yet begun executing init containers.
  • Running. In respect to init containers, the pod has already finished executing the init containers.
  • ContainerCreating.
  • PodInitializing. In respect to init containers, the pod has already finished executing the init containers.

Resources

init Containers - Resources

Examples

Service Dependency with nslookup

An init container can be used to ensure that a service the pod depends on is up and endpoints have been associated with it. A service can be looked up in DNS after it reaches that state, so we can use nslookup from the init container. A typical init container checking on the availability of a service with nslookup is configured as follows:

apiVersion: apps/v1
kind: Deployment
spec:
  ...
  template:
    spec:
      initContainers:
        - name: wait-on-cassandra
          image: busybox:1.28
          command: ['sh', '-c', 'until nslookup cassandra; do echo waiting for cassandra to start ...; sleep 2; done']
    ...

"cassandra" is the name of the service that gives access to Cassandra pods.


We found that some busybox images introduced nslookup problems - nslookup did not work as expected. 1.28 is one of those images that works well.

Init Container that Timeouts after a While

apiVersion: apps/v1
kind: Deployment
spec:
  ...
  template:
    spec:
      initContainers:
        - name: timeout-init-container
          image: busybox:1.28
          command: 
            - /bin/sh
            - -c
            - 'timeout_sec=20; t0=$(date +%s); while [ $(expr $(date +%s) - ${t0} - ${timeout_sec}) -lt 0 ]; do echo .; sleep 1; exit 0; done; exit 1'
    ...

Application Dependency with curl

https://github.com/NovaOrdis/playground/tree/master/openshift/applications/service-dependency

Troubleshooting

The stdout/stderr of an init container can be displayed with:

kubectl logs [-f] -c <init-container-name> <pod-name>

More on troubleshooting pods and containers.