1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        如何優(yōu)雅地關閉Kubernetes集群中的Pod

        共 4043字,需瀏覽 9分鐘

         ·

        2021-03-31 14:00

        原文標題:Gracefully Shutting Down Pods in a Kubernetes Cluster

        發(fā)布時間:Jan 26, 2019

        原文鏈接:https://blog.gruntwork.io/zero-downtime-server-updates-for-your-kubernetes-cluster-902009df5b33

        文章作者:yorinasub17

        這是我們實現(xiàn) Kubernetes 集群零停機時間更新的第二部分。在本系列的第一部分中,我們列舉出了簡單粗暴地使用kubectl drain 命令清除集群節(jié)點上的 Pod 的問題和挑戰(zhàn)。在這篇文章中,我們將介紹解決這些問題和挑戰(zhàn)的手段之一:優(yōu)雅地關閉 Pod。

        Pod驅(qū)逐的生命周期

        默認情況下,kubectl drain命令驅(qū)逐節(jié)點上的 Pod 時會遵循 Pod 的生命周期,這意味著整個過程會遵守以下規(guī)則:

        • kubectl drain將向控制中心發(fā)出刪除目標節(jié)點上的 Pod 的請求。隨后,請求將通知目標節(jié)點上的 kubelet 開始關閉 Pod。
        • 節(jié)點上的kubelet 將會調(diào)用 Pod 里的 preStop 鉤子。
        • preStop 鉤子執(zhí)行完成后,節(jié)點上的kubelet 會向Pod容器中運行的程序發(fā)送 TERM信號 (SIGTERM)。
        • 節(jié)點上的kubelet將最多等待指定的寬限期(在pod上指定,或從命令行傳入;默認為30秒)然后關閉容器,然后強行終止進程(使用SIGKILL)。注意,這個寬限期包括執(zhí)行 preStop鉤子的時間。

        譯注:Kubelet 終止Pod前的等待寬限期有兩種方式指定

        1. 在Pod定義里通過Pod模板的spec.terminationGracePeriodSeconds 設定
        2. kubectl delete pod {podName} --grace-period=60

        基于此流程,我們可以利用應用程序 Pod 中的preStop鉤子和信號處理來正常關閉應用程序,以便在最終終止應用程序之前對其進行“清理”。例如,假如有一個工作進程從隊列中讀取信息然后處理任務,我們可以讓應用程序捕獲 TERM 系統(tǒng)信號,以指示該應用程序應停止接受新任務,并在所有當前任務完成后停止運行?;蛘撸绻\行的應用程序無法修改以捕獲 TERM 信號(例如第三方應用程序),則可以使用preStop鉤子來實現(xiàn)該服務提供的自定義API,來正常關閉應用。

        在我們的示例中,Nginx 默認情況下不能處理 TERM 信號,因此,我們將改為依靠 Pod 的 preStop鉤子實現(xiàn)正常停止Nginx。我們將修改資源定義,將生命周期鉤子添加到容器的spec定義中,如下所示:

        lifecycle:
          preStop:
            exec:
              command: [
                # Gracefully shutdown nginx
                "/usr/sbin/nginx", "-s", "quit"
              ]

        應用此配置后,在將 TERM 信號發(fā)送給容器中的Nginx進程之前,kebulet 調(diào)用 Pod 的生命周期鉤子發(fā)出命令 / usr / sbin / nginx -s quit。請注意,由于該命令將會正常停止 Nginx 進程和 Pod,因此 TERM 信號實際上在這個例子中是一個空操作。

        在定義文件添加了生命周期鉤子后,整個 Deployment 資源的定義變成了下面這樣

        ---
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: nginx-deployment
          labels:
            app: nginx
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: nginx
          template:
            metadata:
              labels:
                app: nginx
            spec:
              containers:
              - name: nginx
                image: nginx:1.15
                ports:
                - containerPort: 80
                lifecycle:
                  preStop:
                    exec:
                      command: [
                        # Gracefully shutdown nginx
                        "/usr/sbin/nginx", "-s", "quit"
                      ]

        停機后的后續(xù)流量

        使用上面的preStop鉤子正常關閉 Pod 可以確保 Nginx 在處理完現(xiàn)存流量有才會停止。但是,你可能會發(fā)現(xiàn),Nginx 容器在關閉后仍會繼續(xù)接收到流量,從而導致服務出現(xiàn)停機時間。

        為了了解造成這個問題的原因,讓我們來看一個示例圖。假定該節(jié)點已接收到來自客戶端的流量。應用程序會產(chǎn)生一個工作線程來處理請求。我們用在 Nginx Pod 示例圖內(nèi)的圓圈表示該工作線程。

        正在處理請求的Nginx

        假設在工作線程處理請求的同時,集群的運維人員決定對 Node1 進行維護。運維運行了kubectl drain node-1 后,節(jié)點上的kubelet 會執(zhí)行 Pod 設置的preStop鉤子,開始進入Nginx進程正常關閉的流程。

        對節(jié)點進行維護,清出節(jié)點上的Pod時會先執(zhí)行preStop鉤子

        由于 Nginx 仍要處理已存流量的請求,所以進入正常關閉流程后 Nginx 不會馬上終止進程,但是會拒絕處理后續(xù)到達的流量,向新請求返回錯誤。

        在這個時間點,假設一個新的服務請求到達了 Pod 上層的 Service,因為此時 Pod 仍然是上層 Service 的Endpoint,所以這個即將關閉的 Pod 仍然可能會接收到 Service 分發(fā)過來的請求。如果 Pod 真的接收到了分發(fā)過來的新請求 Nginx 就會拒絕處理并返回錯誤。

        譯注:推薦閱讀學練結(jié)合快速掌握K8s Service控制器

        Nginx處于關閉流程時會拒絕新來的請求

        最終 Nginx 將完成對原始已存請求的處理,隨后kubelet會刪除 Pod,節(jié)點完成排空。

        Nginx 處理完已存請求后終止進程
        Pod停止運行,kubelet刪除Pod

        為什么會這樣呢?如何避免在Pod執(zhí)行關閉期間接受到來自客戶端的請求呢?在本系列的下一部分中,我們會更詳細地介紹 Pod 的生命周期,并給出如何在 preStop 鉤子中引入延遲為 Pod 進行摘流,以減輕來自 Service 的后續(xù)流量的影響。



        瀏覽 38
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            一区二区三区无码专区 | 久久伊人天堂 | 婷婷狠狠爱| 青青操黄色视频 | 印度三级a做爰全过程 | 男人亚洲天堂网 | 免费裸体打屁屁羞羞免费 | 操逼视频在线播放 | 91麻豆精品国产91久久久吃药 | 大香蕉人人在线 |