公众号关注 「奇妙的 Linux 世界」
设为「星标」,每天带你玩转 Linux !
在负责实际生产中的敏感性业务时,我们经常会发现在发布或者底层基础设施异常时,业务会在短暂的时间内出现不可访问,虽然 Kubernetes 架构可以帮助我们很快的进行自动化修复,但是依然会存在一定时间的 downtime,本篇文章来介绍下如何对 Kubernetes 中的业务进行优雅停服。
当我们输入 kubectl delete pod
时,对应的 pod 会被删除掉,同时 endpoint controller 会从 Service 和 etcd 中移除它的 IP 地址和端口。
此时,我们可以通过 kubectl describe service
来观测整个过程。
describe svc
但就这还不够。
k8s 中存在多个组件去同步本地的 endpoints 列表
kube-proxy
会保存本地的 endpoints 列表去写入 iptables 规则CoreDNS
使用 endpoint 列表去重新配置 DNS entries
例如 Ingress 控制器,Istio 等也是如此同步的。
所有这些组件都将(最终)删除之前的端点,这样就不会有流量再次到达它。
同时,kubelet 也会收到更改通知并删除 pod。
那么当 kubelet 在其他组件之前删除 pod 时会发生什么呢?
不幸的是,此时你的业务会经历一段时间的 downtime ,因为诸如 kube-proxy,CoreDNS,Ingress 控制器等组件会仍然使用该 IP 地址来路由流量。
所以,我们应该如何去处理此类情况,尽可能的减少我们业务的 downtime 时间呢?
如果在删除 pod 之前等待足够长的时间,传输中的流量仍然可以解决,并且新的流量可以分配给其他 pod。
所以,我们应该通过何种方式来在删除 pod 之前等待一段时间呢?
当 kubelet 删除 一个 pod 时,它将经历以下步骤:
触发 preStop hook (如果有的话)
发送 SIGTERM 信号
发送 SIGKILL 信号 (after 30 seconds)
因此,我们可以使用 preStop 钩子来拆入人为的延迟
也可以在应用程序中接受 SIGTERM 信号并等待
此外,您可以优雅地停止该过程,并在完成等待后退出。
Kubernetes 默认给我们设置了 30s 来做相关的事情。
那我们应该等待多久呢?10s,20s 还是 30s 呢?其实没有一个标准的答案。
虽然 endpoints 的同步只需要花费很短的时间,但是 Kubernetes 不能保证任何时间,也不能保证所有组件都能同时完成。
相关链接:
https://learnk8s.io/graceful-shutdown
https://freecontent.manning.com/handling-client-requests-properly-with-kubernetes/
https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods
https://medium.com/tailwinds-navigator/-kubernetes-tip-how-to-gracefully-handle-pod-deletion-b28d23644ccc
https://medium.com/flant-com/kubernetes-graceful-shutdown-nginx-php-fpm-d5ab266963c2
https://www.openshift.com/blog/kubernetes-pods-life
本文转载自:「云原生运维技术」,原文:https://url.hi-linux.com/fq7SJ,版权归原作者所有。欢迎投稿,投稿邮箱: editor@hi-linux.com。
最近,我们建立了一个技术交流微信群。目前群里已加入了不少行业内的大神,有兴趣的同学可以加入和我们一起交流技术,在 「奇妙的 Linux 世界」 公众号直接回复 「加群」 邀请你入群。
你可能还喜欢
点击下方图片即可阅读
CentOS 停止技术支持后,我们应该如何选择适合的操作系统?
点击上方图片,『美团|饿了么』外卖红包天天免费领
更多有趣的互联网新鲜事,关注「奇妙的互联网」视频号全了解!