天天看點

容器生命周期的鈎子

容器鈎子

容器中有兩個鈎子:

PostStart

這個鈎子在容器建立後立即執行。

但是,并不能保證鈎子将在容器ENTRYPOINT之前運作。

沒有參數傳遞給處理程式。

PreStop

這個鈎子在容器終止之前立即被調用。

它是阻塞的,意味着它是同步的, 是以它必須在删除容器的調用發出之前完成。

鈎子處理程式的實作

容器可以通過實作和注冊該鈎子的處理程式來通路鈎子。

可以為容器實作兩種類型的鈎子處理程式:

Exec - 在容器的cgroups和命名空間内執行一個特定的指令,比如pre-stop.sh。

該指令消耗的資源被計入容器。

HTTP - 對容器上的特定的端點執行HTTP請求。

鈎子處理程式的執行

當容器生命周期管理鈎子被調用後,Kubernetes管理系統執行該鈎子在容器中注冊的處理程式。

在含有容器的Pod的上下文中鈎子處理程式的調用是同步的。

這意味着對于PostStart鈎子, 容器ENTRYPOINT和鈎子執行是異步的。

然而,如果鈎子花費太長時間以至于不能運作或者挂起, 容器将不能達到running狀态。

PreStop鈎子的行為是類似的。

如果鈎子在執行期間挂起, Pod階段将停留在running狀态并且永不會達到failed狀态。

如果PostStart或者PreStop鈎子失敗, 它會殺死容器。

使用者應該使他們的鈎子處理程式盡可能的輕量。

然而,有些情況下,長時間運作指令是合理的, 比如在停止容器之前預先儲存狀态。

鈎子傳遞保證

鈎子傳遞打算至少一次,這意味着對于給定的事件,一個鈎子可能被多次調用, 例如對于PostStart或者PreStop。

它是由鈎子的實作來正确的處理這個。

通常,隻有單次傳遞。

例如,如果一個HTTP鈎子的接收者挂掉不能接收流量, 該鈎子不會嘗試重新發送。

然而,在一些極不常見的情況下,可能發生兩次傳遞。

例如,如果在發送鈎子的途中kubelet重新開機, 該鈎子可能在kubelet啟動之後重新發送。

調試鈎子處理程式

在Pod的事件中沒有鈎子處理程式的日志。 如果一個處理程式因為某些原因運作失敗,它廣播一個事件。

對于PostStart, 這是FailedPostStartHook事件, 對于PreStop, 這是FailedPreStopHook事件。

可以通過運作<code>kubectl describe pod &lt;pod_name&gt;</code>來檢視這些事件。

給容器生命周期設定操作事件,定義預啟動和預結束事件操作

本實驗将會建立含有一個容器的Pod,我們将會給這個容器設定預啟動和預結束操作。

下面是Pod的配置檔案:

在這個配置檔案裡,你可以看到postStart指令在容器目錄/usr/share下寫了一個message檔案, preStop指令停止容器。這在容器被因錯誤而結束時很有幫助。

建立Pod:

<code>kubectl create -f https://k8s.io/docs/tasks/configure-pod-container/lifecycle-events.yaml</code>

驗證Pod裡的容器是否運作:

<code>kubectl get pod lifecycle-demo</code>

連接配接到Pod裡容器的shell:

<code>kubectl exec -it lifecycle-demo -- /bin/bash</code>

在shell裡,驗證postStart是否建立了message檔案:

<code>root@lifecycle-demo:/# cat /usr/share/message</code>

輸出顯示了檔案确實被建立了:

<code>Hello from the postStart handler</code>

說明

Kubernetes在容器建立之後就會馬上發送postStart事件,但是并沒法保證一定會 這麼做,它會在容器入口被調用之前調用postStart操作,因為postStart的操作跟容器的操作是異步的,而且Kubernetes控制台會鎖住容器直至postStart完成,是以容器隻有在 postStart操作完成之後才會被設定成為RUNNING狀态。

Kubernetes在容器結束之前發送preStop事件,并會在preStop操作完成之前一直鎖住容器 狀态,除非Pod的終止時間過期了。

繼續閱讀