22-pod-initContainer
concepts/workloads/pods/init-containers/
Init Containers
This page provides an overview of init containers: specialized containers that run before app containers in a Pod. Init containers can contain utilities or setup scripts not present in an app image. 本页概述了init容器:在中的应用程序容器之前运行的专用容器[pod](https://kubernetes.io/docs/concepts/worklo... overview/)。init容器可以包含应用程序映像中不存在的实用程序或安装脚本
You can specify init containers in the Pod specification alongside the containers
array (which describes app containers).
Understanding init containers
A 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. 一个POD可以有多个容器运行应用程序,但它也可以有一个或多个init容器,它们在应用程序容器启动之前运行。
Init containers are exactly like regular containers, exceptinit容器与常规容器完全相同,除了:
- Init containers always run to completion. init容器总是运行到完成(正常运行)。
- Each init container must complete successfully before the next one starts(必须在启动其他容器之前启动).
If a Pod’s init container fails, Kubernetes repeatedly restarts the Pod until the init container succeeds. However, if the Pod has a restartPolicy
of Never, Kubernetes does not restart the Pod. 如果pod的init容器失败,kubernetes会反复重新启动pod,直到init容器成功为止。但是,如果pod的restartpolicy为never,则kubernetes不会重新启动pod。
To specify an init container for a Pod, add the initContainers
field into the Pod specification, as an array of objects of type Container, alongside the app containers
array. The status of the init containers is returned in .status.initContainerStatuses
field as an array of the container statuses (similar to the .status.containerStatuses
field).要为pod指定init容器,请将“init containers”字段添加到pod规范中,作为类型为[container](https://kubernetes.io/docs/reference/gener... api/v1.16/container-v1-core) ) 对象数组,与appcontainers
数组一起。init容器的状态在“.status.initcontainerstatus”字段中作为容器状态的数组返回(类似于“.status.containerstatus”字段)。
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 differently, as documented in Resources. init容器支持应用程序容器的所有字段和功能,包括资源限制、卷和安全设置。但是,init容器的资源请求和限制的处理方式不同,如
Also, init containers do not support readiness probes because they must run to completion before the Pod can be ready.此外,init容器不支持就绪探测,因为它们必须运行到完成,才能准备好pod。
If you specify multiple init containers for a Pod, Kubelet runs each init container sequentially. Each init container must succeed before the next can run. When all of the init containers have run to completion, Kubelet initializes the application containers for the Pod and runs them as usual. 如果为pod指定多个init容器,kubelet将按顺序运行每个init容器。每个init容器必须成功才能运行下一个。当所有的init容器都运行到完成时,kubelet初始化pod的应用程序容器并照常运行它们。
Using init containers
Because init containers have separate images from app containers, they have some advantages for start-up related code因为init容器有独立于app容器的映像,所以它们在与启动相关的代码中有一些优势:
- Init containers can contain utilities or custom code for setup that are not present in an app image. For example, there is no need to make an image
FROM
another image just to use a tool likesed
,awk
,python
, ordig
during setup.init容器可以包含应用程序映像中不存在的安装程序实用程序或自定义代码。例如,在安装过程中,不需要使用诸如“sed”、“awk”、“python”或“dig”之类的工具从另一个图像生成图像 - Init containers can securely run utilities that would make an app container image less secure.init容器可以安全地运行会降低应用程序容器映像安全性的实用程序。
- The application image builder and deployer roles can work independently without the need to jointly build a single app image.应用程序映像生成器和部署程序角色可以独立工作,而无需联合构建单个应用程序映像。
- Init containers can run with a different view of the filesystem than app containers in the same Pod. Consequently, they can be given access to Secrets that app containers cannot access. init容器与同一pod中的应用程序容器相比,可以使用不同的文件系统视图运行。因此,他们可以访问应用程序容器无法访问的机密。
- Because init containers run to completion before any app containers start, init containers offer a mechanism to block or delay app container startup until a set of preconditions are met. Once preconditions are met, all of the app containers in a Pod can start in parallel. 因为init容器在任何应用程序容器启动之前运行到完成,init容器提供了一种机制来阻止或延迟应用程序容器启动,直到满足一组先决条件。一旦满足了前提条件,pod中的所有应用程序容器都可以并行启动。
Examples
Here are some ideas for how to use init containers:
-
Wait for a Service to be created, using a shell one-line command like:
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; 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 main app container. For example, place the
POD_IP
value in a configuration and generate the main app configuration file using Jinja.
Init containers in use
This example defines a simple Pod that has two init containers. The first waits for myservice
, and the second waits for mydb
. Once both init containers complete, the Pod runs the app container from its spec
section.这个例子定义了一个简单的pod,它有两个init容器。第一个等待“myservice”,第二个等待“mydb”。一旦两个init容器都完成,pod就会从其“spec”部分运行app容器。
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
The following YAML file outlines the mydb
and myservice
services:
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
You can start this Pod by running:
kubectl apply -f myapp.yaml
pod/myapp-pod created
And check on its status with:
kubectl get -f myapp.yaml
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 6m
or for more details:
kubectl describe -f myapp.yaml
Name: myapp-pod
Namespace: default
[...]
Labels: app=myapp
Status: Pending
[...]
Init Containers:
init-myservice:
[...]
State: Running
[...]
init-mydb:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Containers:
myapp-container:
[...]
State: Waiting
Reason: PodInitializing
Ready: False
[...]
Events:
FirstSeen LastSeen Count From SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
16s 16s 1 {default-scheduler } Normal Scheduled Successfully assigned myapp-pod to 172.17.4.201
16s 16s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulling pulling image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Pulled Successfully pulled image "busybox"
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Created Created container with docker id 5ced34a04634; Security:[seccomp=unconfined]
13s 13s 1 {kubelet 172.17.4.201} spec.initContainers{init-myservice} Normal Started Started container with docker id 5ced34a04634
To see logs for the init containers in this Pod, run:
kubectl logs myapp-pod -c init-myservice # Inspect the first init container
kubectl logs myapp-pod -c init-mydb # Inspect the second init container
At this point, those init containers will be waiting to discover Services named mydb
and myservice
. 此时,这些init容器将等待发现名为 mydb
and myservice
Here’s a configuration you can use to make those Services appear:
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
To create the mydb
and myservice
services:
kubectl apply -f services.yaml
service/myservice created
service/mydb created
You’ll then see that those init containers complete, and that the myapp-pod
Pod moves into the Running state然后您将看到这些init容器已经完成,并且myapp pod进入running状态:
kubectl get -f myapp.yaml
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 9m
This simple example should provide some inspiration for you to create your own init containers. What’s next contains a link to a more detailed example. 这个简单的例子应该为您创建自己的init容器提供一些灵感。[下一步是什么](https://kubernetes.io/docs/concepts/worklo... containers/what-s-next)包含到更详细示例的链接。
Detailed behavior 详细行为
During the startup of a Pod, each init container starts in order, after the network and volumes are initialized. Each container must exit successfully before the next container starts. 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.在pod启动期间,每个init容器在网络和卷初始化后按顺序启动。每个容器必须在下一个容器启动之前成功退出。如果容器由于运行时而无法启动或因失败而退出,则根据pod“restartpolicy”重试该容器。但是,如果pod“restartpolicy”设置为always,则init容器将使用“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. 在所有init容器都成功之前,pod不能“就绪”。init容器上的端口不在服务下聚合。正在初始化的pod处于“挂起”状态,但应将“初始化”条件设置为true。
If the Pod restarts, or is restarted, 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. 对init容器规范的更改仅限于容器image字段。更改init容器映像字段相当于重新启动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容器,所以init容器代码应该是等幂的。特别是,写入“emptyDirs”上的文件的代码应该准备好,以防输出文件已经存在。
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. init容器拥有应用程序容器的所有字段。但是,kubernetes禁止使用“readinessprobe”,因为init容器不能定义与完成不同的就绪性。这在验证期间强制执行。
Use activeDeadlineSeconds
on the Pod and livenessProbe
on the container to prevent init containers from failing forever. The active deadline includes init containers. 在pod上使用“activedeadlineseconds”,在容器上使用“livenessprobe”,以防止init容器永远失败。活动的截止日期包括init容器。
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.pod中每个app和init容器的名称必须是唯一的;对于与其他容器共享名称的任何容器都会引发验证错误。
Resources
Given the ordering and execution for init containers, the following rules for resource usage apply 给定init容器的顺序和执行,下面的资源使用规则适用:
- The highest of any particular resource request or limit defined on all init containers is the effective init request/limit 在所有init容器上定义的任何特定资源请求或限制中,最高的是有效的init请求/限制
- The Pod’s effective request/limit for a resource is the higher of: POD对资源的有效请求/限制是
- 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. 调度是基于有效的请求/限制来完成的,这意味着init容器可以为初始化预留在pod生命周期中不使用的资源。
- The QoS (quality of service) tier of the Pod’s effective QoS tier is the QoS tier for init containers and app containers alike. pod的有效qos层的qos层是init容器和app容器的qos层。
Quota and limits are applied based on the effective Pod request and limit. 根据有效的POD请求和限制应用配额和限制。
Pod level control groups (cgroups) are based on the effective Pod request and limit, the same as the scheduler.pod级控制组(cgroup)基于有效的pod请求和限制,与调度器相同。
Pod restart reasons
A Pod can restart, causing re-execution of init containers, for the following reasons: pod可以重新启动,导致init容器重新执行,原因如下
- A user updates the Pod specification, causing the init container image to change. Any changes to the init container image restarts the Pod. App container image changes only restart the app container. 用户更新pod规范,导致init容器映像更改。对init容器映像的任何更改都将重新启动pod。应用程序容器映像更改仅重新启动应用程序容器。
- The Pod infrastructure container is restarted. This is uncommon and would have to be done by someone with root access to nodes. POD基础设施容器已重新启动。这是不常见的,必须由具有节点根访问权限的人来完成。
- 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. pod中的所有容器都将终止,而“restartpolicy”设置为always,从而强制重新启动,并且由于垃圾收集,init容器完成记录已丢失。
What's next
- Read about creating a Pod that has an init container
- Learn how to debug init containers
本作品采用《CC 协议》,转载必须注明作者和本文链接