

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 配置容器生命周期挂钩
<a name="lifecycle-hooks"></a>

在容器正常关闭期间，您的应用程序应通过开始关闭来响应`SIGTERM`信号，这样客户端就不会遇到任何停机时间。您的应用程序应运行清理程序，如下所示：
+ 保存数据
+ 关闭文件描述符
+ 关闭数据库连接
+ 优雅地完成机上请求
+ 及时退出以满足 pod 终止请求

设置足够长的宽限期以完成清理。要了解如何响应`SIGTERM`信号，请参阅用于应用程序的编程语言的文档。

[容器生命周期挂钩](https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)使容器能够感知其管理生命周期中的事件。当执行相应的生命周期挂钩时，容器可以运行在处理程序中实现的代码。容器生命周期挂钩为 Kubernetes 和云的异步性质提供了一种解决方法。这种方法可以防止在入口资源之前转发到终止的 pod 并`iptables`更新为不向 pod 发送新流量的连接丢失。

容器生命周期`Endpoint`、和`EndpointSlice`是不同 API 的一部分。编排这些 API 很重要。但是，当 Pod 被终止时，Kubernetes API 会同时通知 kubelet（用于容器生命周期）和控制器。`EndpointSlice`有关更多信息（包括图表），请参阅 *Amazon EKS 最佳实践指南*中的[优雅处理客户请求](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`

使用带有`sleep`命令的`preStop`挂钩来延迟发送`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)和 A *mazon EKS* [最佳实践指南中的优雅关闭](https://docs.aws.amazon.com/eks/latest/best-practices/load-balancing.html#_gracefully_shutdown_applications)应用程序。