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 like sed, awk, python, or dig 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

k8s
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!