本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
設定容器生命週期掛鉤
在正常的容器關閉期間,您的應用程式應該透過啟動關閉來回應SIGTERM訊號,以便用戶端不會經歷任何停機時間。您的應用程式應執行清除程序,如下所示:
-
儲存資料
-
關閉檔案描述項
-
關閉資料庫連線
-
正常完成傳輸中請求
-
及時退出以滿足 Pod 終止請求
設定足夠長的寬限期,以便清除完成。若要了解如何回應SIGTERM訊號,請參閱您用於應用程式的程式設計語言文件。
容器生命週期掛鉤iptables更新為不將新流量傳送到 Pod。
容器生命週期、 Endpoint和 EndpointSlice是不同 APIs的一部分。請務必協調這些 APIs。不過,當 Pod 終止時,Kubernetes API 會同時通知 kubelet (容器生命週期) 和EndpointSlice控制器。如需包括圖表的詳細資訊,請參閱《Amazon EKS 最佳實務指南》中的 Gracefully 處理用戶端請求。
當 kubeletSIGTERM傳送至 Pod 時,EndpointSlice控制器正在終止EndpointSlice物件。該終止會通知 Kubernetes API 伺服器,通知每個節點kube-proxy的 更新 iptables。雖然這些動作同時發生,但它們之間沒有相依性或序列。容器收到SIGKILL訊號的機率很高,遠比每個節點kube-proxy上的 更新本機iptables規則還早。在這種情況下,可能的情況包括下列項目:
-
如果您的應用程式在收到 時立即並暗中捨棄處理中的請求和連線
SIGTERM,用戶端會看到500錯誤。 -
如果您的應用程式確保所有處理中的請求和連線在收到 時完全處理
SIGTERM,則在寬限期內,新的用戶端請求仍會傳送到應用程式容器,因為iptables規則可能尚未更新。在清除程序關閉容器上的伺服器通訊端之前,這些新請求將產生新的連線。當寬限期結束時,在SIGTERM傳送 之後建立的新連線會無條件捨棄。
若要解決先前的案例,您可以實作應用程式內整合或 PreStop 生命週期掛鉤。如需包括圖表的詳細資訊,請參閱《Amazon 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
如需詳細資訊,請參閱 Kubernetes 文件中的容器掛