1. 程式人生 > >Init Container

Init Container

獲得 不同的 單個 文件系統權限 ech event 自身 要求 usr

Init Container的應用場景

當我們在運用一個服務之前,通常會做一些初始化的工作,而這些工作一般只需要運行一次,成功後就不再運行。為此kubernetes 引入了Init Container,用於在啟動應用容器之前啟動一個或多個“初始化”容器,完成應用容器的所需的預制條件。

Init Containers與常規的容器非常類似,但是它一些獨有的特征:

  • 他們僅運行一次,成功後就會退出。
  • 每個容器必須在成功執行完成後,系統才能繼續執行下一個容器。
  • 如果Init Container運行失敗,kubernetes 將會重復重啟Pod,直到Init Container 成功運行,但是如果 Pod的重啟策略(restartPolicy)設置為Never,則Pod不會重啟。
  • Init Container支持普通應用Container的所有參數,包括資源限制,掛載卷,安全設置等。但是Init Container 在資源的申請和限制上略有不同,同時,由於Init Container必須在Pod ready之前完成並退出,所以它不支持 readiness 探針。

Init Container 通常有如下應用方式:

  • 處於安全的考慮,可以將自定義的代碼和工具使用Init Container運行,而不必添加到 應用 容器的鏡像中。
  • 應用程序映像的構建和部署者角色可以彼此獨立,無需共同構建單個應用程序映像
  • 使用不同的Linux命名空間,可以使它們具有來自應用容器的不同文件系統權限。 因此,Init Container可以獲得應用程序容器無法訪問的Secrets。
  • Init Container在任何應用程序容器啟動之前運行完畢,而應用程序容器通常是並行運行的,因此初始容器提供了一種簡單的方法來阻止或延遲應用程序容器的啟動,直到滿足一些前提條件。

具體的應用場景示例:

  • 如使用shell 命令,等待服務被創建:for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • 如使用downward API將自身Pod信息註冊到遠程服務器上:curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()’
  • 在啟動應用之前,等待一段時間:sleep 60
  • 從git倉庫拉取配置或代碼到指定的掛載卷中
  • 使用模板工具動態的生成配置,並給配置文件添加合適的參數。如使用Jinja模板將POD IP添加到應用容器的配置中。

定義Init Container

這裏定義一個nginx,在nginx容器啟動前更改默認起始頁面內容:

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  initContainers:
  - name: init-myservice
    image: busybox
    command: [‘sh‘, ‘-c‘, ‘echo "this init-container test page" > /html/index.html‘]
    volumeMounts:
    - name: index-dir
      mountPath: "/html"
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts: 
    - name: index-dir
      mountPath: /usr/share/nginx/html
  volumes:
  - name: index-dir
    emptyDir: {}

創建容器後,可以看到,先執行初始化操作:

# kubectl  get pod
NAME        READY     STATUS     RESTARTS   AGE
myapp-pod   0/1       Init:0/1   0          12s

# 顯示正在初始化:
# kubectl  get pod
NAME        READY     STATUS            RESTARTS   AGE

myapp-pod   0/1       PodInitializing   0          22s

# kubectl  get pod -o wide
NAME        READY     STATUS    RESTARTS   AGE       IP          NODE
myapp-pod   1/1       Running   0          38s       10.2.74.5   10.0.0.3

#日誌信息:
# kubectl  describe pod
Events:
  Type    Reason                 Age   From               Message
  ----    ------                 ----  ----               -------
  Normal  Scheduled              29s   default-scheduler  Successfully assigned myapp-pod to 10.0.0.3
  Normal  SuccessfulMountVolume  29s   kubelet, 10.0.0.3  MountVolume.SetUp succeeded for volume "index-dir"
  Normal  SuccessfulMountVolume  29s   kubelet, 10.0.0.3  MountVolume.SetUp succeeded for volume "default-token-hmvnc"
  Normal  Pulling                28s   kubelet, 10.0.0.3  pulling image "busybox"
  Normal  Pulled                 16s   kubelet, 10.0.0.3  Successfully pulled image "busybox"
  Normal  Created                16s   kubelet, 10.0.0.3  Created container
  Normal  Started                16s   kubelet, 10.0.0.3  Started container
  Normal  Pulling                15s   kubelet, 10.0.0.3  pulling image "nginx"
  Normal  Pulled                 1s    kubelet, 10.0.0.3  Successfully pulled image "nginx"
  Normal  Created                1s    kubelet, 10.0.0.3  Created container
  Normal  Started                1s    kubelet, 10.0.0.3  Started container

註意事項

Pod中的每個應用程序和Init Container的名稱必須是唯一的; 任何Container與另一個Container共享一個名稱都會引發驗證錯誤。

在Pod重新啟動時, init Container 將會重新運行,那麽所執行的初始化操作也會再次執行,這就要求Init Container的操作是可以重復執行的。例如上面的示例中,在對掛載目錄中文件的添加前,可以先判斷文件是否已經存在的處理,來防止出錯。
常見的Pod重啟場景如下:

  • init container的鏡像被更新時, init Container將會重新運行,導致Pod重啟。僅更新應用容器的鏡像,只會使得應用容器被重啟。
  • Pod的 pause鏡像更新時, Pod將會重啟。
  • 若Pod 中的所有應用容器都終止了,並且restartPolicy=always, 則Pod將會重啟。

Init Container