Kubernetes 容器生命周期回調(diào)

2022-04-29 11:16 更新

概述

類似于許多具有生命周期回調(diào)組件的編程語言框架,例如 Angular、Kubernetes 為容器提供了生命周期回調(diào)。 回調(diào)使容器能夠了解其管理生命周期中的事件,并在執(zhí)行相應(yīng)的生命周期回調(diào)時運行在處理程序中實現(xiàn)的代碼。

容器回調(diào)

有兩個回調(diào)暴露給容器:

?PostStart ?

這個回調(diào)在容器被創(chuàng)建之后立即被執(zhí)行。 但是,不能保證回調(diào)會在容器入口點(ENTRYPOINT)之前執(zhí)行。 沒有參數(shù)傳遞給處理程序。

?PreStop ?

在容器因 API 請求或者管理事件(諸如存活態(tài)探針、啟動探針失敗、資源搶占、資源競爭等) 而被終止之前,此回調(diào)會被調(diào)用。 如果容器已經(jīng)處于已終止或者已完成狀態(tài),則對 preStop 回調(diào)的調(diào)用將失敗。 在用來停止容器的 TERM 信號被發(fā)出之前,回調(diào)必須執(zhí)行結(jié)束。 Pod 的終止寬限周期在 ?PreStop ?回調(diào)被執(zhí)行之前即開始計數(shù),所以無論 回調(diào)函數(shù)的執(zhí)行結(jié)果如何,容器最終都會在 Pod 的終止寬限期內(nèi)被終止。 沒有參數(shù)會被傳遞給處理程序。

回調(diào)處理程序的實現(xiàn) 

容器可以通過實現(xiàn)和注冊該回調(diào)的處理程序來訪問該回調(diào)。 針對容器,有兩種類型的回調(diào)處理程序可供實現(xiàn):

  • Exec - 在容器的 cgroups 和名稱空間中執(zhí)行特定的命令(例如 ?pre-stop.sh?)。 命令所消耗的資源計入容器的資源消耗。
  • HTTP - 對容器上的特定端點執(zhí)行 HTTP 請求。

回調(diào)處理程序執(zhí)行

當(dāng)調(diào)用容器生命周期管理回調(diào)時,Kubernetes 管理系統(tǒng)根據(jù)回調(diào)動作執(zhí)行其處理程序, ?httpGet ?和 ?tcpSocket ?在kubelet 進程執(zhí)行,而 ?exec ?則由容器內(nèi)執(zhí)行 。

回調(diào)處理程序調(diào)用在包含容器的 Pod 上下文中是同步的。 這意味著對于 ?PostStart ?回調(diào),容器入口點和回調(diào)異步觸發(fā)。 但是,如果回調(diào)運行或掛起的時間太長,則容器無法達到 ?running ?狀態(tài)。

?PreStop ?回調(diào)并不會與停止容器的信號處理程序異步執(zhí)行;回調(diào)必須在 可以發(fā)送信號之前完成執(zhí)行。 如果 ?PreStop ?回調(diào)在執(zhí)行期間停滯不前,Pod 的階段會變成 ?Terminating ?并且一直處于該狀態(tài),直到其 ?terminationGracePeriodSeconds ?耗盡為止, 這時 Pod 會被殺死。 這一寬限期是針對 ?PreStop ?回調(diào)的執(zhí)行時間及容器正常停止時間的總和而言的。 例如,如果 ?terminationGracePeriodSeconds ?是 60,回調(diào)函數(shù)花了 55 秒鐘 完成執(zhí)行,而容器在收到信號之后花了 10 秒鐘來正常結(jié)束,那么容器會在其 能夠正常結(jié)束之前即被殺死,因為 ?terminationGracePeriodSeconds ?的值 小于后面兩件事情所花費的總時間(55+10)。

如果 ?PostStart ?或 ?PreStop ?回調(diào)失敗,它會殺死容器。

用戶應(yīng)該使他們的回調(diào)處理程序盡可能的輕量級。 但也需要考慮長時間運行的命令也很有用的情況,比如在停止容器之前保存狀態(tài)。

回調(diào)遞送保證

回調(diào)的遞送應(yīng)該是 至少一次,這意味著對于任何給定的事件, 例如 ?PostStart ?或 ?PreStop?,回調(diào)可以被調(diào)用多次。 如何正確處理被多次調(diào)用的情況,是回調(diào)實現(xiàn)所要考慮的問題。

通常情況下,只會進行單次遞送。 例如,如果 HTTP 回調(diào)接收器宕機,無法接收流量,則不會嘗試重新發(fā)送。 然而,偶爾也會發(fā)生重復(fù)遞送的可能。 例如,如果 kubelet 在發(fā)送回調(diào)的過程中重新啟動,回調(diào)可能會在 kubelet 恢復(fù)后重新發(fā)送。

調(diào)試回調(diào)處理程序

回調(diào)處理程序的日志不會在 Pod 事件中公開。 如果處理程序由于某種原因失敗,它將播放一個事件。 對于 ?PostStart?,這是 ?FailedPostStartHook ?事件,對于 ?PreStop?,這是 ?FailedPreStopHook ?事件。 要自己生成失敗的 ?FailedPreStopHook ?事件,請修改 lifecycle-events.yaml 文件將 postStart 命令更改為 ”badcommand“ 并應(yīng)用它。 以下是通過運行 ?kubectl describe pod lifecycle-demo? 后你看到的一些結(jié)果事件的示例輸出:

Events:
  Type     Reason               Age              From               Message
  ----     ------               ----             ----               -------
  Normal   Scheduled            7s               default-scheduler  Successfully assigned default/lifecycle-demo to ip-XXX-XXX-XX-XX.us-east-2...
  Normal   Pulled               6s               kubelet            Successfully pulled image "nginx" in 229.604315ms
  Normal   Pulling              4s (x2 over 6s)  kubelet            Pulling image "nginx"
  Normal   Created              4s (x2 over 5s)  kubelet            Created container lifecycle-demo-container
  Normal   Started              4s (x2 over 5s)  kubelet            Started container lifecycle-demo-container
  Warning  FailedPostStartHook  4s (x2 over 5s)  kubelet            Exec lifecycle hook ([badcommand]) for Container "lifecycle-demo-container" in Pod "lifecycle-demo_default(30229739-9651-4e5a-9a32-a8f1688862db)" failed - error: command 'badcommand' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: \"badcommand\": executable file not found in $PATH: unknown\r\n"
  Normal   Killing              4s (x2 over 5s)  kubelet            FailedPostStartHook
  Normal   Pulled               4s               kubelet            Successfully pulled image "nginx" in 215.66395ms
  Warning  BackOff              2s (x2 over 3s)  kubelet            Back-off restarting failed container


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號