Contents

Kubernetes 优雅终止 pod

Contents

文本翻译自: https://itnext.io/how-do-you-gracefully-shut-down-pods-in-kubernetes-fb19f617cd67


https://miro.medium.com/v2/0*95EBbIEaG9T2_N5V.png

当你执行 kubectl delete pod 时,pod 被删除, endpoint 控制器从 service 和 etcd 中删除该 pod 的 IP 地址和端口。

你可以使用 kubectl describe service 观察到这一点。

https://miro.medium.com/v2/0*u1dqT-9CWfJPzSz-.png

但远不止如此!

多个组件都会同步变更至本地 endpoint 列表:

  • kube-proxy 通过本地 endpoint 列表来编写 iptables 规则
  • CoreDNS 使用 endpoint 重新配置 DNS

Ingress 控制器、Istio 等也是如此。

https://miro.medium.com/v2/0*for72y-XTvmvKZuF.png

所有这些组件都将(最终)删除以前的 endpoint,这样就再也没有流量可以到达它了。

同时,kubelet 也收到了变化的通知,并删除了 pod。

当 kubelet 在其余组件之前删除 pod 时会发生什么?

https://miro.medium.com/v2/0*7tK2_LUn-gwGEAad.png

不幸的是,你会遇到停机, 因为 kube-proxy、CoreDNS、ingress 控制器等组件仍在使用该 IP 地址来路由流量。

所以,你可以做什么?

等待!

https://miro.medium.com/v2/0*Ew5wmjSUW1wQmti9.png

如果在删除 Pod 之前等待足够长的时间,飞行中的流量仍然可以解析,并且可以将新流量分配给其他 Pod。

你应该如何等待?

https://miro.medium.com/v2/0*344P0iQtxQxJNzi8.png

当 kubelet 删除一个 pod 时,它会经历以下步骤:

  • 触发 preStop 钩子(如果有)。
  • 发送 SIGTERM
  • 发送 SIGKILL 信号(默认 30 秒后)。

https://miro.medium.com/v2/0*LrgZBq0nLMJIPfz4.png

你可以使用preStop挂钩来插入人工延迟。

https://miro.medium.com/v2/0*wItrocVhRzm4DYMm.png

你可以在你的应用程序中监听 SIGTERM 信号并等待。

此外,你可以优雅地停止该过程并在等待完成后退出。

Kubernetes 给你 30 秒的时间来这样做(时长可配置)。

https://miro.medium.com/v2/0*Lj2c8E2Cyb-TJwXP.png

你应该等待 10 秒、20 秒还是 30 秒?

没有单一的答案。

虽然传播 endpoint 可能只需要几秒钟,但 Kubernetes 不保证任何时间,也不保证所有组件将同时完成。

https://miro.medium.com/v2/0*2qhqDUVV50rrTCYU.png

如果你想探索更多,这里有一些链接: