W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
本頁(yè)提供了 Init 容器的概覽。Init 容器是一種特殊容器,在 Pod 內(nèi)的應(yīng)用容器啟動(dòng)之前運(yùn)行。Init 容器可以包括一些應(yīng)用鏡像中不存在的實(shí)用工具和安裝腳本。
你可以在 Pod 的規(guī)約中與用來(lái)描述應(yīng)用容器的 ?containers
?數(shù)組平行的位置指定 Init 容器。
每個(gè) Pod 中可以包含多個(gè)容器, 應(yīng)用運(yùn)行在這些容器里面,同時(shí) Pod 也可以有一個(gè)或多個(gè)先于應(yīng)用容器啟動(dòng)的 Init 容器。
Init 容器與普通的容器非常像,除了如下兩點(diǎn):
如果 Pod 的 Init 容器失敗,kubelet 會(huì)不斷地重啟該 Init 容器直到該容器成功為止。 然而,如果 Pod 對(duì)應(yīng)的 ?restartPolicy
?值為 "Never",并且 Pod 的 Init 容器失敗, 則 Kubernetes 會(huì)將整個(gè) Pod 狀態(tài)設(shè)置為失敗。
為 Pod 設(shè)置 Init 容器需要在 Pod 規(guī)約 中添加 ?initContainers
?字段, 該字段以 Container 類型對(duì)象數(shù)組的形式組織,和應(yīng)用的 ?containers
?數(shù)組同級(jí)相鄰。 參閱 API 參考的容器章節(jié)了解詳情。
Init 容器的狀態(tài)在 ?status.initContainerStatuses
? 字段中以容器狀態(tài)數(shù)組的格式返回 (類似 ?status.containerStatuses
? 字段)。
Init 容器支持應(yīng)用容器的全部字段和特性,包括資源限制、數(shù)據(jù)卷和安全設(shè)置。 然而,Init 容器對(duì)資源請(qǐng)求和限制的處理稍有不同,在下面資源節(jié)有說(shuō)明。
同時(shí) Init 容器不支持 ?lifecycle
?、?livenessProbe
?、?readinessProbe
?和 ?startupProbe
?, 因?yàn)樗鼈儽仨氃?nbsp;Pod 就緒之前運(yùn)行完成。
如果為一個(gè) Pod 指定了多個(gè) Init 容器,這些容器會(huì)按順序逐個(gè)運(yùn)行。 每個(gè) Init 容器必須運(yùn)行成功,下一個(gè)才能夠運(yùn)行。當(dāng)所有的 Init 容器運(yùn)行完成時(shí), Kubernetes 才會(huì)為 Pod 初始化應(yīng)用容器并像平常一樣運(yùn)行。
因?yàn)?nbsp;Init 容器具有與應(yīng)用容器分離的單獨(dú)鏡像,其啟動(dòng)相關(guān)代碼具有如下優(yōu)勢(shì):
sed
?、?awk
?、?python
?或 ?dig
?這樣的工具而去 ?FROM
?一個(gè)鏡像來(lái)生成一個(gè)新的鏡像。下面是一些如何使用 Init 容器的想法:
for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register \
-d 'instance=$(<POD_NAME>)&ip=$(<POD_IP>)'
sleep 60
下面的例子定義了一個(gè)具有 2 個(gè) Init 容器的簡(jiǎn)單 Pod。 第一個(gè)等待 ?myservice
?啟動(dòng), 第二個(gè)等待 ?mydb
?啟動(dòng)。 一旦這兩個(gè) Init容器 都啟動(dòng)完成,Pod 將啟動(dòng) ?spec
?節(jié)中的應(yīng)用容器。
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.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
你通過(guò)運(yùn)行下面的命令啟動(dòng) Pod:
kubectl apply -f myapp.yaml
輸出類似于:
pod/myapp-pod created
使用下面的命令檢查其狀態(tài):
kubectl get -f myapp.yaml
輸出類似于:
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 6m
或者查看更多詳細(xì)信息:
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
如需查看 Pod 內(nèi) Init 容器的日志,請(qǐng)執(zhí)行:
kubectl logs myapp-pod -c init-myservice # 查看第一個(gè) Init 容器
kubectl logs myapp-pod -c init-mydb # 查看第二個(gè) Init 容器
在這一刻,Init 容器將會(huì)等待至發(fā)現(xiàn)名稱為 ?mydb
?和 ?myservice
?的 Service。
如下為創(chuàng)建這些 Service 的配置文件:
---
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
創(chuàng)建 ?mydb
?和 ?myservice
?服務(wù)的命令:
kubectl create -f services.yaml
輸出類似于:
service "myservice" created
service "mydb" created
這樣你將能看到這些 Init 容器執(zhí)行完畢,隨后 ?my-app
? 的 Pod 進(jìn)入 ?Running
?狀態(tài):
kubectl get -f myapp.yaml
輸出類似于:
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 9m
在 Pod 啟動(dòng)過(guò)程中,每個(gè) Init 容器會(huì)在網(wǎng)絡(luò)和數(shù)據(jù)卷初始化之后按順序啟動(dòng)。 kubelet 運(yùn)行依據(jù) Init 容器在 Pod 規(guī)約中的出現(xiàn)順序依次運(yùn)行之。
每個(gè) Init 容器成功退出后才會(huì)啟動(dòng)下一個(gè) Init 容器。 如果某容器因?yàn)槿萜鬟\(yùn)行時(shí)的原因無(wú)法啟動(dòng),或以錯(cuò)誤狀態(tài)退出,kubelet 會(huì)根據(jù) Pod 的 ?restartPolicy
?策略進(jìn)行重試。 然而,如果 Pod 的 ?restartPolicy
?設(shè)置為 "Always",Init 容器失敗時(shí)會(huì)使用 ?restartPolicy
?的 "OnFailure" 策略。
在所有的 Init 容器沒(méi)有成功之前,Pod 將不會(huì)變成 ?Ready
?狀態(tài)。 Init 容器的端口將不會(huì)在 Service 中進(jìn)行聚集。正在初始化中的 Pod 處于 ?Pending
?狀態(tài), 但會(huì)將狀況 ?Initializing
?設(shè)置為 false。
如果 Pod 重啟,所有 Init 容器必須重新執(zhí)行。
對(duì) Init 容器規(guī)約的修改僅限于容器的 ?image
?字段。 更改 Init 容器的 ?image
?字段,等同于重啟該 Pod。
因?yàn)?nbsp;Init 容器可能會(huì)被重啟、重試或者重新執(zhí)行,所以 Init 容器的代碼應(yīng)該是冪等的。 特別地,基于 ?emptyDirs
?寫(xiě)文件的代碼,應(yīng)該對(duì)輸出文件可能已經(jīng)存在做好準(zhǔn)備。
Init 容器具有應(yīng)用容器的所有字段。然而 Kubernetes 禁止使用 ?readinessProbe
?, 因?yàn)?nbsp;Init 容器不能定義不同于完成態(tài)(Completion)的就緒態(tài)(Readiness)。 Kubernetes 會(huì)在校驗(yàn)時(shí)強(qiáng)制執(zhí)行此檢查。
在 Pod 上使用 ?activeDeadlineSeconds
?和在容器上使用 ?livenessProbe
?可以避免 Init 容器一直重復(fù)失敗。 ?activeDeadlineSeconds
?時(shí)間包含了 Init 容器啟動(dòng)的時(shí)間。 但建議僅在團(tuán)隊(duì)將其應(yīng)用程序部署為 Job 時(shí)才使用 ?activeDeadlineSeconds
?, 因?yàn)?nbsp;?activeDeadlineSeconds
?在 Init 容器結(jié)束后仍有效果。 如果你設(shè)置了 ?activeDeadlineSeconds
?,已經(jīng)在正常運(yùn)行的 Pod 會(huì)被殺死。
在 Pod 中的每個(gè)應(yīng)用容器和 Init 容器的名稱必須唯一; 與任何其它容器共享同一個(gè)名稱,會(huì)在校驗(yàn)時(shí)拋出錯(cuò)誤。
在給定的 Init 容器執(zhí)行順序下,資源使用適用于如下規(guī)則:
配額和限制適用于有效 Pod 的請(qǐng)求和限制值。 Pod 級(jí)別的 cgroups 是基于有效 Pod 的請(qǐng)求和限制值,和調(diào)度器相同。
Pod 重啟會(huì)導(dǎo)致 Init 容器重新執(zhí)行,主要有如下幾個(gè)原因:
pause
?容器) 被重啟。這種情況不多見(jiàn), 必須由具備 root 權(quán)限訪問(wèn)節(jié)點(diǎn)的人員來(lái)完成。
restartPolicy
?設(shè)置為 "?Always
?",Pod 中所有容器會(huì)終止而強(qiáng)制重啟。 由于垃圾收集機(jī)制的原因,Init 容器的完成記錄將會(huì)丟失。
當(dāng) Init 容器的鏡像發(fā)生改變或者 Init 容器的完成記錄因?yàn)槔占仍虮粊G失時(shí), Pod 不會(huì)被重啟。這一行為適用于 Kubernetes v1.20 及更新版本。如果你在使用較早 版本的 Kubernetes,可查閱你所使用的版本對(duì)應(yīng)的文檔。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: