K8s中的容器生命周期中的鉤子

1.概述

類似于許多具有組件生命周期鉤子的編程語言框架怎憋,例如Angular扛或,Kubernetes為Containers提供了生命周期鉤子敲街。 鉤子使Container能夠了解其管理生命周期中的事件闷愤,并在執(zhí)行相應(yīng)的生命周期鉤子時運行在處理程序中實現(xiàn)的代碼砌创。

2.容器鉤子(以下為官方原文)

There are two hooks that are exposed to Containers:

PostStart

This hook executes immediately after a container is created. However, there is no guarantee that the hook will execute before the container ENTRYPOINT. No parameters are passed to the handler.

PreStop

This hook is called immediately before a container is terminated due to an API request or management event such as liveness probe failure, preemption, resource contention and others. A call to the preStop hook fails if the container is already in terminated or completed state. It is blocking, meaning it is synchronous, so it must complete before the call to delete the container can be sent. No parameters are passed to the handler.

A more detailed description of the termination behavior can be found in Termination of Pods.


主要注意以下幾點:

  1. PostStart hook是在容器創(chuàng)建(created)之后立馬被調(diào)用,并且PostStart跟容器的ENTRYPOINT是異步執(zhí)行的社牲,無法保證它們之間的順序
  2. PreStop hook是容器處于Terminated狀態(tài)時立馬被調(diào)用(也就是說要是Job任務(wù)的話粪薛,執(zhí)行完之后其狀態(tài)為completed悴了,所以不會觸發(fā)PreStop的鉤子)搏恤,同時PreStop是同步阻塞的,PreStop執(zhí)行完才會執(zhí)行刪除Pod的操作

3.Hook handler execution

When a Container lifecycle management hook is called, the Kubernetes management system executes the handler in the Container registered for that hook.

Hook handler calls are synchronous within the context of the Pod containing the Container. This means that for a PostStart hook, the Container ENTRYPOINT and hook fire asynchronously. However, if the hook takes too long to run or hangs, the Container cannot reach a running state.

The behavior is similar for a PreStop hook. If the hook hangs during execution, the Pod phase stays in a Terminating state and is killed after terminationGracePeriodSeconds of pod ends. If a PostStart or PreStop hook fails, it kills the Container.

Users should make their hook handlers as lightweight as possible. There are cases, however, when long running commands make sense, such as when saving state prior to stopping a Container.


主要注意以下幾點:

  1. PostStart會阻塞容器成為Running狀態(tài)
  2. PreStop會阻塞容器的刪除湃交,但是過了terminationGracePeriodSeconds時間后熟空,容器會被強制刪除
  3. 如果PreStop或者PostStart失敗的話, 容器會被殺死

4.Example

apiVersion: v1
kind: Pod
metadata:
  name: test-post-start
spec:
  containers:
  - name: test-post-start-container1
    image: busybox
    command: ["/bin/sh", "-c", "sleep 600"]
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "sleep 20"]
  - name: test-post-start-container
    image: busybox
    command: ["/bin/sh", "-c", "echo $(date) 'written by entrypoint' >> log.log && sleep 600"]
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo $(date) 'written by post start' >> log.log && sleep 5"]

部署這個pod之后,通過kubectl describe pod test-post-start后得到以下結(jié)果

Events:
  Type    Reason     Age   From                 Message
  ----    ------     ----  ----                 -------
  Normal  Scheduled  1m    default-scheduler    Successfully assigned default/test-post-start to node012060
  Normal  Pulling    59s   kubelet, node012060  pulling image "busybox"
  Normal  Pulled     54s   kubelet, node012060  Successfully pulled image "busybox"
  Normal  Created    54s   kubelet, node012060  Created container
  Normal  Started    54s   kubelet, node012060  Started container
  Normal  Pulling    34s   kubelet, node012060  pulling image "busybox"
  Normal  Pulled     29s   kubelet, node012060  Successfully pulled image "busybox"
  Normal  Created    29s   kubelet, node012060  Created container
  Normal  Started    29s   kubelet, node012060  Started container
  
# 進入到容器里面查看log.log
Thu Jun 13 07:44:57 UTC 2019 written by entrypoint
Thu Jun 13 07:44:57 UTC 2019 written by post start

從這個例子我們可以得到以下結(jié)論

  1. 一個Pod中容器的啟動時有順序的搞莺,排在前面容器的先啟動息罗。同時第一個容器執(zhí)行完ENTRYPOINT和PostStart之后,k8s才會創(chuàng)建第二個容器(這樣的話就可以保證第一個容器創(chuàng)建多長時間后再啟動第二個容器)
  2. 并且PostStart跟容器的ENTRYPOINT是異步執(zhí)行的才沧,無法保證它們之間的順序, PostStart并不會阻塞ENTRYPOINT的啟動

5.鉤子使用的具體例子

使用 prestop hook 保證服務(wù)安全退出

在實際生產(chǎn)環(huán)境中使用spring框架迈喉,由于服務(wù)更新過程中绍刮,服務(wù)容器被直接終止,部分請求仍然被分發(fā)到終止的容器挨摸,導(dǎo)致出現(xiàn)500錯誤孩革,這部分錯誤的請求數(shù)據(jù)占比較少,也可以忽略得运。
考慮添加優(yōu)雅的終止方式膝蜈,將錯誤請求降到最低,直至沒有錯誤出現(xiàn)熔掺。


這里介紹 spring cloud 的服務(wù)發(fā)現(xiàn)組件:
Eureka 是一個基于 REST 的服務(wù)饱搏,作為服務(wù)注冊中心,用于定位服務(wù)來進行中間層服務(wù)器的負載均衡和故障轉(zhuǎn)移置逻。各服務(wù)啟動時,會向Eureka Server注冊自己的信息(IP,端口,服務(wù)信息等),Eureka Server會存儲這些信息.微服務(wù)啟動后,會周期性(默認30秒)的向Eureka Server發(fā)送心跳以續(xù)約自己的”租期”推沸,并可以從eureka中獲取其他微服務(wù)的地址信息,執(zhí)行相關(guān)的邏輯考慮現(xiàn)在eureka server 修改注冊實例的狀態(tài)券坞,暫停服務(wù)( InstanceStatus.OUT_OF_SERVICE )坤学,保留一段時間后,再刪除服務(wù)报慕。

禁用某個服務(wù):

curl -X PUT “http://admin:admin@192.168.101.100:8761/eureka/apps/{appName}/{instanceId}/status?value=OUT_OF_SERVICE"

說明:admin:admin是eureka的登錄名和密碼深浮,如果沒有,直接去掉前面這段眠冈;
instanceId是上面打開的鏈接顯示的服務(wù)列表中的標簽內(nèi)容,如:myapp:192.168.1.100:8080

在k8s 中的具體操作:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: NAME-service-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: NAME-service
  template:
    metadata:
      labels:
        app: NAME-service
    spec:
      containers:
      - name: NAME-service
        lifecycle:
          preStop:
            exec:
              command:
                - "/bin/sh"
                - "-c"
                - " \
                  APPLICATION=NAME-service; \
                  APPLICATION_PORT=8016; \
                  curl -s -X PUT http://eureka01-server.domain.com/eureka/apps/${APPLICATION}/$(hostname):${APPLICATION}:${APPLICATION_PORT}/status?value=OUT_OF_SERVICE; \
                  sleep 30; \
                  "

刪除了無用的信息飞苇,重點關(guān)注 lifecycle,首先定義了服務(wù)名和端口的環(huán)境變量蜗顽,把這部分單獨作為變量布卡,便于不同的服務(wù)進行修改。使用 curl PUT 到eureka 配置狀態(tài)為 OUT_OF_SERVICE雇盖。配置一個sleep時間忿等,作為服務(wù)停止緩沖時間。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末崔挖,一起剝皮案震驚了整個濱河市贸街,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狸相,老刑警劉巖薛匪,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異脓鹃,居然都是意外死亡逸尖,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娇跟,“玉大人岩齿,你說我怎么就攤上這事“” “怎么了纯衍?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長苗胀。 經(jīng)常有香客問我襟诸,道長,這世上最難降的妖魔是什么基协? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任歌亲,我火速辦了婚禮,結(jié)果婚禮上澜驮,老公的妹妹穿的比我還像新娘陷揪。我一直安慰自己,他們只是感情好杂穷,可當(dāng)我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布悍缠。 她就那樣靜靜地躺著,像睡著了一般耐量。 火紅的嫁衣襯著肌膚如雪飞蚓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天廊蜒,我揣著相機與錄音趴拧,去河邊找鬼。 笑死山叮,一個胖子當(dāng)著我的面吹牛著榴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屁倔,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼脑又,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了锐借?” 一聲冷哼從身側(cè)響起问麸,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞎饲,沒想到半個月后口叙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡嗅战,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驮捍。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡疟呐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出东且,到底是詐尸還是另有隱情启具,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布珊泳,位于F島的核電站鲁冯,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏色查。R本人自食惡果不足惜薯演,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望秧了。 院中可真熱鬧跨扮,春花似錦、人聲如沸验毡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晶通。三九已至璃氢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間狮辽,已是汗流浹背拔莱。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隘竭,地道東北人塘秦。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像动看,于是被迫代替她去往敵國和親尊剔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容