Migrate Init Containers to Concepts (#2438)

* Initial commit for Init Containers migration to Concepts section

* Add 1.5 beta include file

* Change include to renamed user-guide-content-moved.md file

* Fix Concepts/KO/Pods ToC

* reformat examples to bullet points

* fix formatting

* Add back Detailed Behavior, Support and compatibility

* Adjust formatting issues

* revised based on feedback from Steve

* complete sentence rewrite
This commit is contained in:
Andrew Chen 2017-02-09 10:18:59 -08:00 committed by mengyuan
parent 554d6b7e9f
commit 667c1818dc
4 changed files with 192 additions and 166 deletions

View File

@ -9,12 +9,14 @@ toc:
- docs/concepts/tools/kubectl/object-management-using-imperative-commands.md
- docs/concepts/tools/kubectl/object-management-using-imperative-config.md
- docs/concepts/tools/kubectl/object-management-using-declarative-config.md
- title: Kubernetes Objects
section:
- docs/concepts/abstractions/overview.md
- docs/concepts/abstractions/pod.md
- title: Pods
section:
- docs/concepts/abstractions/pod.md
- docs/concepts/abstractions/init-containers.md
- title: Controllers
section:
- docs/concepts/abstractions/controllers/statefulsets.md

1
_includes/1-5-beta.md Normal file
View File

@ -0,0 +1 @@
***NOTE: This feature is beta in Kubernetes 1.5.***

View File

@ -0,0 +1,184 @@
---
assignees:
- erictune
title: Init Containers
---
{% capture overview %}
This page provides an overview of Init Containers, which are specialized
Containers that run before app Containers and can contain utilities or setup
scripts not present in an app image.
{% endcapture %}
{:toc}
{% include 1-5-beta.md %}
**Once the feature exits beta, Init Containers will be specified in the PodSpec
alongside the app `containers` array.**
{% capture body %}
## Understanding Init Containers
A [Pod](/docs/concepts/abstractions/pod/) can have multiple Containers running
apps within it, but it can also have one or more Init Containers, which are run
before the app Containers are started.
Init Containers are exactly like regular Containers, except:
* They always run to completion.
* Each one must complete successfully before the next one is started.
If an Init Container fails for a Pod, Kubernetes restarts the Pod repeatedly until the Init
Container succeeds. However, if the Pod has a `restartPolicy` of Never, it is not restarted.
To specify a Container as an Init Container, add the `annotations` key
`pod.beta.kubernetes.io/init-containers`. Its value should be a
JSON array of objects of type
[Container](http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_container).
The status of an Init Container is returned as another annotation,
`pod.beta.kubernetes.io/init-container-statuses`, which is an array of
container statuses similar to the `status.containerStatuses` field.
### Differences from regular Containers
Init Containers support all the fields and features of app Containers,
including resource limits, volumes, and security settings. However, the
resource requests and limits for an Init Container are handled slightly
differently, which are documented in [Resources](#resources) below. Also, Init Containers do not
support readiness probes because they must run to completion before the Pod can
be ready.
If multiple Init Containers are specified for a Pod, those Containers are run
one at a time in sequential order. Each must succeed before the next can run.
When all of the Init Containers have run to completion, Kubernetes initializes
the Pod and runs the application Containers as usual.
## What can Init Containers be used for?
Because Init Containers have separate images from app Containers, they
have some advantages for start-up related code:
* They can contain and run utilities that are not desirable to include in the
app Container image for security reasons.
* They can contain utilities or custom code for setup that is not present in an app
image. For example, there is no need to make an image `FROM` another image just to use a tool like
`sed`, `awk`, `python`, or `dig` during setup.
* The application image builder and deployer roles can work independently without
the need to jointly build a single app image.
* They use Linux namespaces so they have a different filesystem view from app Containers.
Consequently, they can be given access to Secrets that app Containers are not able to
access.
* They run to completion before any app Containers start, whereas app
Containers run in parallel, so Init Containers provide an easy way to block or
delay the startup of app Containers until some set of preconditions are met.
### Examples
Here are some ideas for how to use Init Containers:
* Wait for a service to be created with a shell command like:
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1
* Register this Pod with a remote server from the downward API with a command like:
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
* Wait for some time before starting the app Container with a command like `sleep 60`.
* Clone a git repository into a volume.
* Place values into a configuration file and run a template tool to dynamically
generate a configuration file for the the main app Container. For example,
place the POD_IP value in a configuration and generate the main app
configuration file using Jinja.
More detailed usage examples can be found in the [StatefulSets documentation](/docs/concepts/abstractions/controllers/statefulsets/)
and the [Production Pods guide](/docs/user-guide/production-pods.md#handling-initialization).
## Detailed behavior
During the startup of a Pod, the Init Containers are started in order, after the
network and volumes are initialized. Each Container must exit successfully before
the next is started. If a Container fails to start due to the runtime or
exits with failure, it is retried according to the Pod `restartPolicy`. However,
if the Pod `restartPolicy` is set to Always, the Init Containers use
`RestartPolicy` OnFailure.
A Pod cannot be `Ready` until all Init Containers have succeeded. The ports on an
Init Container are not aggregated under a service. A Pod that is initializing
is in the `Pending` state but should have a condition `Initializing` set to true.
If the Pod is [restarted](#pod-restart-reasons), all Init Containers must
execute again.
Changes to the Init Container spec are limited to the container image field.
Altering an Init Container image field is equivalent to restarting the Pod.
Because Init Containers can be restarted, retried, or re-executed, Init Container
code should be idempotent. In particular, code that writes to files on `EmptyDirs`
should be prepared for the possibility that an output file already exists.
Init Containers have all of the fields of an app Container. However, Kubernetes
prohibits `readinessProbe` from being used because Init Containers cannot
define readiness distinct from completion. This is enforced during validation.
Use `activeDeadlineSeconds` on the Pod and `livenessProbe` on the Container to
prevent Init Containers from failing forever. The active deadline includes Init
Containers.
The name of each app and Init Container in a Pod must be unique; a
validation error is thrown for any Container sharing a name with another.
### Resources
Given the ordering and execution for Init Containers, the following rules
for resource usage apply:
* The highest of any particular resource request or limit defined on all Init
Containers is the *effective init request/limit*
* The Pod's *effective request/limit* for a resource is the higher of:
* the sum of all app Containers request/limit for a resource
* the effective init request/limit for a resource
* Scheduling is done based on effective requests/limits, which means
Init Containers can reserve resources for initialization that are not used
during the life of the Pod.
* QoS tier of the Pod's *effective QoS tier* is the QoS tier for Init Containers
and app containers alike.
Quota and limits are applied based on the effective Pod request and
limit.
Pod level cgroups are based on the effective Pod request and limit, the
same as the scheduler.
### Pod restart reasons
A Pod can restart, causing re-execution of Init Containers, for the following
reasons:
* A user updates the PodSpec causing the Init Container image to change.
App Container image changes only restart the app Container.
* The Pod infrastructure container is restarted. This is uncommon and would
have to be done by someone with root access to nodes.
* All containers in a Pod are terminated while `restartPolicy` is set to Always,
forcing a restart, and the Init Container completion record has been lost due
to garbage collection.
## Support and compatibility
A cluster with Kubelet and Apiserver version 1.4.0 or greater supports Init
Containers with the beta annotations. Support varies for other combinations of
Kubelet and Apiserver versions; see the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md) for details.
{% endcapture %}
{% capture whatsnext %}
* [Creating a Pod that has an Init Container](/docs/tasks/configure-pod-container/configure-pod-initialization/#creating-a-pod-that-has-an-init-container)
{% endcapture %}
{% include templates/concept.md %}

View File

@ -1,168 +1,7 @@
---
assignees:
- erictune
title: Init Containers
---
* TOC
{:toc}
In addition to having one or more main containers (or **app containers**), a
pod can also have one or more **init containers** which run before the app
containers. Init containers allow you to reduce and reorganize setup scripts
and "glue code".
## Overview
An init container is exactly like a regular container, except that it always
runs to completion and each init container must complete successfully before
the next one is started. If the init container fails, Kubernetes will restart
the pod until the init container succeeds. If a pod is marked as `RestartNever`,
the pod will fail if the init container fails.
You specify a container as an init container by adding an annotation.
The annotation key is `pod.beta.kubernetes.io/init-containers`. The annotation
value is a JSON array of [objects of type `v1.Container`
](http://kubernetes.io/docs/api-reference/v1/definitions/#_v1_container)
Once the feature exits beta, the init containers will be specified on the Pod
Spec alongside the app `containers` array.
The status of the init containers is returned as another annotation -
`pod.beta.kubernetes.io/init-container-statuses` -- as an array of the
container statuses (similar to the `status.containerStatuses` field).
Init containers support all of the same features as normal containers,
including resource limits, volumes, and security settings. The resource
requests and limits for an init container are [handled slightly differently](
#resources). Init containers do not support readiness probes since they will
run to completion before the pod can be ready.
An init container has all of the fields of an app container.
If you specify multiple init containers for a pod, those containers run one at
a time in sequential order. Each must succeed before the next can run. Once all
init containers have run to completion, Kubernetes initializes the pod and runs
the application containers as usual.
## What are Init Containers Good For?
Because init containers have separate images from application containers, they
have some advantages for start-up related code. These include:
* they can contain utilities that are not desirable to include in the app container
image for security reasons,
* they can contain utilities or custom code for setup that is not present in an app
image. (No need to make an image `FROM` another image just to use a tool like
`sed`, `awk`, `python`, `dig`, etc during setup).
* the application image builder and the deployer roles can work independently without
the need to jointly build a single app image.
Because init containers have different filesystem view (Linux namespaces) from
app containers, they can be given access to Secrets that the app containers are
not able to access.
Since init containers run to completion before any app containers start, and
since app containers run in parallel, they provide an easier way to block or
delay the startup of application containers until some precondition is met.
Because init containers run in sequence and there can be multiple init containers,
they can be composed easily.
Here are some ideas for how to use init containers:
- Wait for a service to be created with a shell command like:
`for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; exit 1`
- Register this pod with a remote server with a command like:
`curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d 'instance=$(POD_NAME)&ip=$(POD_IP)'`
using `POD_NAME` and `POD_IP` from the downward API.
- Wait for some time before starting the app container with a command like `sleep 60`.
- Clone a git repository into a volume
- Place values like a POD_IP into a configuration file, and run a template tool (e.g. jinja)
to generate a configuration file to be consumed by the main app contianer.
Complete usage examples can be found in the [StatefulSets
documentation](/docs/concepts/abstractions/controllers/statefulsets/) and the [Production Pods
guide](/docs/user-guide/production-pods.md#handling-initialization).
## Detailed Behavior
Each pod may have 0..N init containers defined along with the existing
1..M app containers.
On startup of the pod, after the network and volumes are initialized, the init
containers are started in order. Each container must exit successfully before
the next is invoked. If a container fails to start (due to the runtime) or
exits with failure, it is retried according to the pod RestartPolicy, except
when the pod restart policy is RestartPolicyAlways, in which case just the init
containers use RestartPolicyOnFailure.
A pod cannot be ready until all init containers have succeeded. The ports on an
init container are not aggregated under a service. A pod that is being
initialized is in the `Pending` phase but should has a condition `Initializing`
set to `true`.
If the pod is [restarted](#pod-restart-reasons) all init containers must
execute again.
Changes to the init container spec are limited to the container image field.
Altering an init container image field is equivalent to restarting the pod.
Because init containers can be restarted, retried, or reexecuted, init container
code should be idempotent. In particular, code that writes to files on EmptyDirs
should be prepared for the possibility that an output file already exists.
An init container has all of the fields of an app container. The following
fields are prohibited from being used on init containers by validation:
* `readinessProbe` - init containers must exit for pod startup to continue,
are not included in rotation, and so cannot define readiness distinct from
completion.
Init container authors may use `activeDeadlineSeconds` on the pod and
`livenessProbe` on the container to prevent init containers from failing
forever. The active deadline includes init containers.
The name of each app and init container in a pod must be unique - it is a
validation error for any container to share a name.
### Resources
Given the ordering and execution for init containers, the following rules
for resource usage apply:
* The highest of any particular resource request or limit defined on all init
containers is the **effective init request/limit**
* The pod's **effective request/limit** for a resource is the higher of:
* sum of all app containers request/limit for a resource
* effective init request/limit for a resource
* Scheduling is done based on effective requests/limits, which means
init containers can reserve resources for initialization that are not used
during the life of the pod.
* QoS tier of the pod's **effective QoS tier** is the QoS tier for init containers
and app containers alike.
Quota and limits are applied based on the effective pod request and
limit.
Pod level cGroups are based on the effective pod request and limit, the
same as the scheduler.
## Pod Restart Reasons
A Pod may "restart", causing reexecution of init containers, for the following
reasons:
* An init container image is changed by a user updating the Pod Spec.
* App container image changes only restart the app container.
* The pod infrastructure container is restarted.
* This is uncommon and would have to be done by someone with root access to nodes.
* All containers in a pod are terminated, requiring a restart (RestartPolicyAlways) AND the record of init container completion has been lost due to garbage collection.
## Support and compatibility
A cluster with Kubelet and Apiserver version 1.4.0 or greater supports init
containers with the beta annotations. Support varies for other combinations of
Kubelet and Apiserver version; see the [release notes
](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md) for details.
{% include user-guide-content-moved.md %}
* [Init Containers](/docs/concepts/abstractions/init-containers/)