From 667c1818dc139ac0b0c382d0711ba80ec3fece63 Mon Sep 17 00:00:00 2001 From: Andrew Chen Date: Thu, 9 Feb 2017 10:18:59 -0800 Subject: [PATCH] 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 --- _data/concepts.yml | 8 +- _includes/1-5-beta.md | 1 + docs/concepts/abstractions/init-containers.md | 184 ++++++++++++++++++ docs/user-guide/pods/init-container.md | 165 +--------------- 4 files changed, 192 insertions(+), 166 deletions(-) create mode 100644 _includes/1-5-beta.md create mode 100644 docs/concepts/abstractions/init-containers.md diff --git a/_data/concepts.yml b/_data/concepts.yml index 4f41c2c818..4227231cc1 100644 --- a/_data/concepts.yml +++ b/_data/concepts.yml @@ -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 diff --git a/_includes/1-5-beta.md b/_includes/1-5-beta.md new file mode 100644 index 0000000000..abccaa303c --- /dev/null +++ b/_includes/1-5-beta.md @@ -0,0 +1 @@ +***NOTE: This feature is beta in Kubernetes 1.5.*** \ No newline at end of file diff --git a/docs/concepts/abstractions/init-containers.md b/docs/concepts/abstractions/init-containers.md new file mode 100644 index 0000000000..1bea00b3a2 --- /dev/null +++ b/docs/concepts/abstractions/init-containers.md @@ -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=$()&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 %} \ No newline at end of file diff --git a/docs/user-guide/pods/init-container.md b/docs/user-guide/pods/init-container.md index ce7679d40e..90a862ea02 100644 --- a/docs/user-guide/pods/init-container.md +++ b/docs/user-guide/pods/init-container.md @@ -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/) \ No newline at end of file