系列目錄html
一個pod裏能夠運行多個容器,它也能夠運行一個或者多個初始容器,初始容器先於應用容器運行,除了如下兩點外,初始容器和普通容器沒有什麼兩樣:python
它們老是run to completion
linux
一個初始容器必須成功運行另外一個才能運行git
若是pod中的一個初始容器運行失敗,則kubernetes會嘗試重啓pod直到初始容器成功運行,若是pod的重啓策略設置爲從不(never)
,則不會重啓.docker
建立容器時,在podspec裏添加initContainers
字段,則指定容器即爲初始容器,它們的返回狀態做爲數組保存在.status.initContainerStatuses
裏(與普通容器狀態存儲字段.status.containerStatuses
相似)shell
初始容器支持全部普通容器的特徵,包括資源配額限制和存儲卷以及安全設置.可是對資源申請和限制處理初始容器略有不一樣,下面會介紹.此外,初始容器不支持可用性探針(readiness probe),由於它在ready
以前必須run to completion
api
若是在一個pod裏指定了多個初始容器,則它們會依次
啓動起來(pod內的普通容器並行啓動),而且只有上一個成功下一個才能啓動.當全部的初始容器都啓動了,kubernetes纔開始啓普通應用容器.數組
因爲初始容器和普通應用容器是分開的鏡像,所以他在作一些初始化工做頗有優點:安全
它們能夠包含而且運行一些出於安全考慮不適合和應用放在一塊的小工具.bash
它們能夠一些小工具和自定義代碼來作些初始化工做,這樣就不須要在普通應用容器裏使用sed
,awk
,python
或者dig
來作初始化工做了
應用構建者和發佈者能夠獨立工做,而沒必要再聯合起來處理同一個pod
它們使用linux namespaces
所以它們和普通應用pod擁有不一樣的文件系統視圖.所以他們能夠被賦予普通應用容器獲取不到的secrets
它們在應用容器啓動前運行,所以它們能夠阻止或者延緩普通應用容器的初始化直到須要的條件知足
示例:
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=$(<POD_NAME>)&ip=$(<POD_IP>)'
在容器啓動以前等待必定時間:例如sleep 60
克隆一個git倉庫到存儲目錄
經過模板工具動態把一些值寫入到主應用程序的配置文件裏.
更多詳細示例請查看pod應用環境佈置指南
apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] - name: init-mydb image: busybox command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
以上pod定義包含兩個初始容器,第一個等待myservice
服務可用,第二個等待mydb
服務可用,這兩個pod執行完成,應用容器開始執行.
下面是myservice
和mydb
兩個服務的yaml文件
kind: Service apiVersion: v1 metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- kind: Service apiVersion: v1 metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
上面定義的pod能夠經過如下使用初始化和調試
kubectl create -f myapp.yaml pod/myapp-pod created
kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 0/1 Init:0/2 0 6m
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
kubectl logs myapp-pod -c init-myservice # Inspect the first init container kubectl logs myapp-pod -c init-mydb # Inspect the second init container
當咱們啓動mydb
和myservice
兩個服務後,咱們能夠看到初始容器完成而且myapp-pod
pod被建立.
kubectl create -f services.yaml service/myservice created service/mydb created
kubectl get -f myapp.yaml NAME READY STATUS RESTARTS AGE myapp-pod 1/1 Running 0 9m
這些示例很是簡單可是應該能爲你建立本身的初始容器提供一些靈感
在啓動pod的過程當中,在存儲卷和網絡建立之後,初始容器依次建立.上一個容器必須返回成功下一個才能啓動,若是因爲運行時錯誤或者其它異常退出,它會依照restartPolicy
來重試,然而,若是restartPolicy
設置爲Always
,初始容器實際上使用的是OnFailure
策略
若是pod重啓了,則全部的初始容器要從新執行
對初始容器的spec
的更改僅限於鏡像(image)
字段的修改,更改了初始容器的鏡像字段至關於重啓pod
因爲初始容器能夠被重啓,重試和從新執行,所以它裏面的代碼應當是冪等的,尤爲是寫入文件到EmptyDirs
的代碼應當注意文件可能已經存在
容器中的全部初始容器和普通容器名稱必須唯一.
基於初始容器的執行順序,如下關於資源的規則適用:
對於特定資源,全部初始容器申請的最高的生效
對於pod,相同資源申請取如下二者較高的一個:
1) 全部普通應用容器申請的資源總和
2) 初始容器申請的生效的資源(上面說到,初始容器申請資源取全部初始容器申請最大的一個)
調度基於生效的初始請求,這就意味着初始容器能夠申請預留資源,即使在pod之後的整個生命週期都用不到
一個pod基於如下列出的緣由,會重啓,從新執行初始容器:
用戶更新初始容器的PodSpec
致使鏡像發生改變.普通應用容器改變只會使應用容器重啓
因爲restartPolicy
被設置爲Always
,致使全部容器均被停止,強制重啓,因爲垃圾回收初始容器的初始狀態記錄丟失