【问题标题】:How to send traffic from Service to Pod while Pod is in termination grace period如何在 Pod 处于终止宽限期时将流量从 Service 发送到 Pod
【发布时间】:2018-10-19 12:14:56
【问题描述】:

我有一个附加了 Service 和 Horizo​​ntalPodAutoscaler 的部署(A pod)。我希望能够控制缩减过程并在 pod 关闭之前进行一些清理。问题是,清理可能需要很长时间,并且要完成一些其他服务(B pod)应该能够访问试图关闭的 pod。

为了实现这一点,我将部署 A 设置为具有长 spec.terminationGracePeriodSeconds 值。当一个 pod 获得 SIGTERM 时,它开始完成并在完成后关闭进程。

从 pod A 获取 SIGTERM 开始,它不再接收来自 pod B 的连接,因为服务从端点删除了它的 IP - 使得 pod A 无法完成它的清理。

尝试使用 ClusterIP 和 Headless 服务,两者的作用相同。

如何让服务在获得 SIGTERM 后继续向 pod A 发送流量?我不介意 B pod 的请求在尝试访问 A pod 时出错。

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    由于终止流程设计,无法做到这一点。

    这里是终止进程的documentation的摘录:

    1. 用户发送命令删除 Pod,默认宽限期(30 秒)

    2. API 服务器中的 Pod 会更新,超过该时间后 Pod 被视为“死亡”以及宽限期。

    3. Pod 在客户端命令中列出时显示为“Terminating”
    4. (与 3 同时)当 Kubelet 看到一个 Pod 被标记为终止,因为 2 中的时间已经设置,它开始 pod 关闭过程。

      1. 如果 pod 定义了 preStop 挂钩,则会在 pod 内部调用它。如果在宽限期到期后 preStop 挂钩仍在运行,则将调用第 2 步,并延长一小段(2 秒)的宽限期。
      2. 向 Pod 中的进程发送 TERM 信号。
    5. (与 3 同时)Pod 已从服务的端点列表中删除,并且不再被视为复制控制器正在运行的 Pod 集的一部分。缓慢关闭的 Pod 可以继续为流量提供服务,因为负载平衡器(如服务代理)将它们从轮换中移除。

    6. 当宽限期到期时,任何仍在 Pod 中运行的进程都会被 SIGKILL 杀死。
    7. Kubelet 将通过设置宽限期 0(立即删除)来完成 API 服务器上 Pod 的删除。 Pod 从 API 中消失,不再从客户端可见。

    因此,在解析“SIGTERM”信号时,Pod 将在服务中注销,您无法避免它。

    【讨论】:

      【解决方案2】:

      使用以下方式配置您的服务:

      spec.publishNotReadyAddresses: true
      

      然后,即使您的 pod 处于 Terminating 状态,它们也会收到流量,正如 Kubernetes docs 所解释的那样:

      publishNotReadyAddresses 设置为 true 时,表示 DNS 实现必须为与服务关联的端点发布子集的 notReadyAddresses。默认值为假。设置此字段的主要用例是使用 StatefulSet 的 Headless Service 为其 Pod 传播 SRV 记录,而不考虑它们是否已准备好用于对等发现。

      请注意spec.publishNotReadyAddresses only works in Kubernetes v1.11+。 在较旧的集群中,使用service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" 注释来获取similar behaviour

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-04
        • 2021-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-28
        • 2021-07-08
        相关资源
        最近更新 更多