

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

# 設定容器生命週期掛鉤
<a name="lifecycle-hooks"></a>

在正常的容器關閉期間，您的應用程式應該透過啟動關閉來回應`SIGTERM`訊號，以便用戶端不會經歷任何停機時間。您的應用程式應執行清除程序，如下所示：
+ 儲存資料
+ 關閉檔案描述項
+ 關閉資料庫連線
+ 正常完成傳輸中請求
+ 及時退出以滿足 Pod 終止請求

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

[容器生命週期掛鉤](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)可讓容器了解其管理生命週期中的事件。在執行對應的生命週期關聯時，容器可以執行在處理常式中實作的程式碼。容器生命週期掛鉤為 Kubernetes 和雲端的非同步性質提供了解決方法。這種方法可以防止遺失在輸入資源之前轉送到終止 Pod 的連線，並`iptables`更新為不將新流量傳送到 Pod。

容器生命週期、 `Endpoint`和 `EndpointSlice`是不同 APIs的一部分。請務必協調這些 APIs。不過，當 Pod 終止時，Kubernetes API 會同時通知 kubelet （容器生命週期） 和`EndpointSlice`控制器。如需包括圖表的詳細資訊，請參閱《*Amazon EKS 最佳實務指南*》中的 [Gracefully 處理用戶端請求](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html#_gracefully_handle_the_client_requests)。

當 `kubelet``SIGTERM`傳送至 Pod 時，`EndpointSlice`控制器正在終止`EndpointSlice`物件。該終止會通知 Kubernetes API 伺服器，通知每個節點`kube-proxy`的 更新 `iptables`。雖然這些動作同時發生，但它們之間沒有相依性或序列。容器收到`SIGKILL`訊號的機率很高，遠比每個節點`kube-proxy`上的 更新本機`iptables`規則還早。在這種情況下，可能的情況包括下列項目：
+ 如果您的應用程式在收到 時立即並暗中捨棄處理中的請求和連線`SIGTERM`，用戶端會看到`500`錯誤。
+ 如果您的應用程式確保所有處理中的請求和連線在收到 時完全處理`SIGTERM`，則在寬限期內，新的用戶端請求仍會傳送到應用程式容器，因為`iptables`規則可能尚未更新。在清除程序關閉容器上的伺服器通訊端之前，這些新請求將產生新的連線。當寬限期結束時，在`SIGTERM`傳送 之後建立的新連線會無條件捨棄。

若要解決先前的案例，您可以實作應用程式內整合或 PreStop 生命週期掛鉤。如需包括圖表的詳細資訊，請參閱《*Amazon EKS 最佳實務指南*》中的[優雅關機應用程式](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html#_gracefully_shutdown_applications)。

**注意**  
無論應用程式是否正常關閉，或是`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 文件中的[容器掛](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks)鉤，以及《*Amazon EKS 最佳實務指南*》中的[逐步關閉應用程式](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html#_gracefully_shutdown_applications)。