ITPub博客

首页 > 数据库 > 数据库开发技术 > ?Kubernetes 中如何优雅的停服

?Kubernetes 中如何优雅的停服

原创 数据库开发技术 作者:云原生运维技术 时间:2023-02-23 22:26:00 0 删除 编辑


在负责实际生产中的敏感性业务时,我们经常会发现在发布或者底层基础设施异常时,业务会在短暂的时间内出现不可访问,虽然 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



原文作者:云原生运维技术;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2017-01-18

  • 博文量
    53
  • 访问量
    20337