22-pod-initContainer

cucytoman發表於2019-10-10

concepts/workloads/pods/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

本作品採用《CC 協議》,轉載必須註明作者和本文連結