Init Container

Init Container的應用場景

當咱們在運用一個服務以前,一般會作一些初始化的工做,而這些工做通常只須要運行一次,成功後就再也不運行。爲此kubernetes 引入了Init Container,用於在啓動應用容器以前啓動一個或多個「初始化」容器,完成應用容器的所需的預製條件。html

Init Containers與常規的容器很是相似,可是它一些獨有的特徵:nginx

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

Init Container 一般有以下應用方式:git

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

具體的應用場景示例:shell

  • 如使用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容器啓動前更改默認起始頁面內容:api

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重啓場景以下:markdown

  • init container的鏡像被更新時, init Container將會從新運行,致使Pod重啓。僅更新應用容器的鏡像,只會使得應用容器被重啓。
  • Pod的 pause鏡像更新時, Pod將會重啓。
  • 若Pod 中的全部應用容器都終止了,而且restartPolicy=always, 則Pod將會重啓。
相關文章
相關標籤/搜索