20. 优雅的 Pod 关闭

Kubernetes 开始终止一个 Pod 时,它首先向该 Pod 中的所有容器发送一个 TERM 信号。 当 Linkerd proxy sidecar 收到此信号时, 它将立即开始正常关闭, 拒绝所有新请求并允许现有请求在关闭之前完成。

这意味着如果 Pod 的主容器在代理收到 TERM 信号后尝试进行任何新的网络调用, 这些网络调用将失败。 这也会对终止 Pod 的客户端和作业资源(job resources)产生影响。

客户端更新缓慢

Kubernetes 终止一个 Pod 之前,它首先从该 Pod 所属的任何服务的端点资源中删除该 Pod。 这意味着该服务的客户端应该在终止之前停止向 Pod 发送流量。 但是,某些客户端接收端点更新的速度可能很慢, 并且可能会在 Pod 的代理已经收到 TERM 信号并开始正常关闭后尝试向终止 Pod 发送请求。 这些请求将失败。

为了缓解这种情况,使用 --wait-before-exit-seconds flaglinkerd inject 来使用 preStop 钩子将 Linkerd 代理对 TERM 信号的处理延迟给定的秒数。 在开始正常关闭之前,此延迟为慢速客户端提供了额外的时间来接收端点更新。 为了从该选项中获得最大收益,主容器应该有自己的 preStop 钩子, 其中的 sleep 命令的周期小于为代理 sidecar 设置的周期。 并且它们都不能大于为整个 pod 配置的 terminationGracePeriodSeconds

示例

       # application container
        lifecycle:
          preStop:
            exec:
              command:
                - /bin/bash
                - -c
                - sleep 20

    # for entire pod
    terminationGracePeriodSeconds: 160

Job Resources

作为 job resource 一部分的 Pod 会一直运行,直到 Pod 中的所有容器都完成。 但是,Linkerd 代理容器会持续运行,直到收到 TERM 信号。 这意味着已注入的 job pods 将继续运行,即使主容器已完成。

已经提议更好地支持 sidecar containers in Kubernetes, Linkerd 将在该支持可用时利用该支持。