設定容器生命週期掛鉤 - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

設定容器生命週期掛鉤

在正常容器關閉期間,您的應用程式應該透過啟動關閉來回應SIGTERM訊號,以便用戶端不會經歷任何停機時間。您的應用程式應執行清除程序,如下所示:

  • 儲存資料

  • 關閉檔案描述項

  • 關閉資料庫連線

  • 正常完成傳輸中的請求

  • 及時結束,以滿足 Pod 終止請求

設定足夠長的寬限期,以便完成清除。若要了解如何回應SIGTERM訊號,請參閱您用於應用程式的程式設計語言文件。

容器生命週期掛鉤可讓容器了解其管理生命週期中的事件。執行對應的生命週期關聯時,容器可以執行在處理常式中實作的程式碼。容器生命週期掛鉤為 Kubernetes 和雲端的非同步性質提供了解決方法。這種方法可以防止遺失在輸入資源之前轉送到終止 Pod 的連線,並iptables更新為不將新流量傳送到 Pod。

容器生命週期和端點和 EndpointSlice 是不同 APIs的一部分。請務必協調這些 APIs。不過,當 Pod 終止時,Kubernetes API 會同時通知 kubelet (適用於容器生命週期) 和EndpointSlice控制器。如需包括圖表的詳細資訊,請參閱《EKS 最佳實務指南》中的 Gracefully 處理用戶端請求

kubeletSIGTERM傳送至 Pod 時,EndpointSlice控制器會終止EndpointSlice物件。該終止會通知 Kubernetes API 伺服器,通知 每個節點kube-proxy的 更新 iptables。雖然這些動作同時發生,但它們之間沒有相依性或序列。在每個節點kube-proxy上的 更新本機iptables規則之前,容器收到SIGKILL訊號的機率很高。在這種情況下,可能的情況包括下列項目:

  • 如果您的應用程式在接收到用戶端時立即並暗中捨棄處理中的請求和連線SIGTERM, ,則會出現500錯誤。

  • 如果您的應用程式確保所有處理中的請求和連線在收到 時完全處理SIGTERM,則在寬限期內,新的用戶端請求仍會傳送至應用程式容器,因為iptables規則可能尚未更新。在清除程序關閉容器上的伺服器通訊端之前,這些新請求將產生新的連線。當寬限期結束時,SIGTERM傳送 後建立的新連線會無條件捨棄。

若要解決先前的案例,您可以實作應用程式內整合或 PreStop 生命週期關聯。如需包括圖表的詳細資訊,請參閱《EKS 最佳實務指南》中的逐步關閉應用程式

注意:無論應用程式是否正常關閉,或是preStop勾點的結果,應用程式容器最終都會在寬限期結束時透過 終止SIGKILL

使用preStop勾點搭配 sleep命令來延遲傳送 SIGTERM。這有助於在輸入物件將新連線路由至 Pod 時,繼續接受新連線。測試 sleep命令的時間值,以確保將 Kubernetes 和其他應用程式相依性的任何延遲納入考量,如下列範例所示:

apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: containers: - name: nginx lifecycle: # This "sleep" preStop hook delays the Pod shutdown until # after the Ingress Controller removes the matching Endpoint or EndpointSlice preStop: exec: command: - /bin/sleep - "20" # This period should be turned to Ingress/Service Mesh update latency

如需詳細資訊,請參閱容器掛鉤EKS 最佳實務 – 負載平衡 (逐步關閉應用程式)