本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
設定容器生命週期掛鉤
在正常容器關閉期間,您的應用程式應該透過啟動關閉來回應SIGTERM
訊號,以便用戶端不會經歷任何停機時間。您的應用程式應執行清除程序,如下所示:
儲存資料
關閉檔案描述項
關閉資料庫連線
正常完成傳輸中的請求
及時結束,以滿足 Pod 終止請求
設定足夠長的寬限期,以便完成清除。若要了解如何回應SIGTERM
訊號,請參閱您用於應用程式的程式設計語言文件。
容器生命週期掛鉤iptables
更新為不將新流量傳送到 Pod。
容器生命週期和端點和 EndpointSlice 是不同 APIs的一部分。請務必協調這些 APIs。不過,當 Pod 終止時,Kubernetes API 會同時通知 kubelet (適用於容器生命週期) 和EndpointSlice
控制器。如需包括圖表的詳細資訊,請參閱《EKS 最佳實務指南》中的 Gracefully 處理用戶端請求
當 kubelet
SIGTERM
傳送至 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
如需詳細資訊,請參閱容器掛鉤