1. 程式人生 > 其它 >Kubernetes 中優雅停止服務的那些事

Kubernetes 中優雅停止服務的那些事

前言

所謂 "優雅停止服務" 一般指不對線上產生影響,或儘可能減少影響地停止服務產生的影響。

現在高可用服務一般由多例項構成,並且客戶端請求由負載均衡器 (Load Balancer) 統一路由。

優雅停止流程大致如下:

  • 先通知負載均衡器將該例項從後端列表中移除
  • 結束當前例項上連線
  • 待當前例項上連線結束或超過限定時間後,停止服務

在實際 Kubernetes 分散式系統中,要做好這件事有許多細節需要注意。本文以 TiDB Server 的優雅停止舉例,說明 Kubernetes 中 Pod 刪除流程,我們可以做什麼,來實現優雅地停止服務。

在使用姿勢上,我們並不引入新的流程。而是結合 Kubernetes 提供

容器生命週期擴充套件點實現功能。

從負載均衡器下線

Pod 在標記刪除後,Kubernetes 的 Endpoint 控制器會開始將 Pod 的 IP 從 Sevice 後端移除。kube-proxy 以及外部的負載均衡器實現,就會將其從後端移除。

同時 Pod 在標記刪除後,kubelet 也會停止容器。這兩項操作,由不同元件在發現 Pod 即將刪除後操作,並沒有先後順序。若程序在負載均衡器將 Pod IP 從後端移除前,kubelet 就將容器停止,則仍然可能會有新的請求,嘗試連線一個不存在的 IP 。若業務層沒有重試機制,則請求會失敗。

所以,我們需要等待一段時間,再去停止容器。我們可以藉助 preStopHook 鉤子,在容器停止前等待一段時間:

lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10"]

我們不採用同步方案,讓負載均衡器與 kubelet 嚴格地保證操作順序執行,因為會過於複雜,且與具體外部負載均衡器實現耦合。例子中的 sleep 時間,可結合生產環境中負載均衡器下線後端反應時間來調整。

結束當前例項上連線

前面我們實現了,先讓 Pod 從負載均衡器下線,再結束程序,以避免新的請求在程序結束後,連入進來。但程序還存在當前連線,我們需要結束程序前,先通知程序主動通知客戶端關閉連線等。

這步操作與具體的業務的實現有關,我們以 

tidb-server 舉例。

kubelet 的預設停止容器使用的 SIGTERM 訊號,tidb-server 在此訊號下會進行優雅退出,但超時時間只有 15 秒,若線上有比較耗時較長的請求,是不夠當前連線正常退出的。

tidb-server 在收到 SIGQUIT 訊號時會進行不限時的優雅退出,流程如下:

  • 關閉 listeners
  • 遍歷當前連線,關閉空閒連線
  • 其餘的嘗試在應用層協議通知客戶端主動關閉

因此,我們不可能使用 kubelet 的預設停止容器使用的 SIGTERM 訊號,而是應主動傳送 SIGQUIT 給 tidb-server 程序通知其以更優雅的方式執行。

lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10 && kill -QUIT 1"]

PID 1 為容器內 root 程序。注意需要將進行作為 root 程序執行,或者 root 程序可以將訊號轉發給子業務程序,比如使用 tini 時。

優雅停止超時時間

前面我們不僅在停止服務前通知負載均衡器先將 Pod IP 從後端移除,同時通知應用採用主動通知並結束當前連線後,再退出。但還有一個問題是,許多時候,當前連線要完全優雅結束需要很久,比如一些長連線應用。Kubelet 給 Pod 預設允許的優雅退出時間是 30s,我們需要結合具體應用,配置恰當的超時時間。可以在 pod.spec.terminationGracePeriodSeconds 欄位配置:

terminationGracePeriodSeconds: 60
lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10 && kill -QUIT 1"]

至此,我們就實現了完美的優雅退出方案。

結語

我們可以將優雅退出階段分為以下幾部分:

  • 通知負載均衡器將 Pod IP 從後端列表下線
  • 通知應用優雅結束當前連線
  • 配置合理的超時時間,給予應用足夠的優雅退出時間

其中具體時間引數,以及通知應用方法需要結合具體應用而定。本文拋磚引玉,以 tidb-server 為例,主要分析思路,和 Kubernetes 中可採用機制。

轉發自:https://zhuanlan.zhihu.com/p/188674410