ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Kubernetes 中优雅停止服务的那些事

2022-05-31 20:31:53  阅读:202  来源: 互联网

标签:负载 Kubernetes 优雅 停止 均衡器 Pod 连接


前言

所谓 "优雅停止服务" 一般指不对线上产生影响,或尽可能减少影响地停止服务产生的影响。

现在高可用服务一般由多实例构成,并且客户端请求由负载均衡器 (Load Balancer) 统一路由。

优雅停止流程大致如下:

  • 先通知负载均衡器将该实例从后端列表中移除
  • 结束当前实例上连接
  • 待当前实例上连接结束或超过限定时间后,停止服务

在实际 Kubernetes 分布式系统中,要做好这件事有许多细节需要注意。本文以 TiDB Server 的优雅停止举例,说明 Kubernetes 中 Pod 删除流程,我们可以做什么,来实现优雅地停止服务。

在使用姿势上,我们并不引入新的流程。而是结合 Kubernetes 提供容器生命周期扩展点实现功能。

从负载均衡器下线

Pod 在标记删除后,Kubernetes 的 Endpoint 控制器会开始将 Pod 的 IP 从 Sevice 后端移除。kube-proxy 以及外部的负载均衡器实现,就会将其从后端移除。

同时 Pod 在标记删除后,kubelet 也会停止容器。这两项操作,由不同组件在发现 Pod 即将删除后操作,并没有先后顺序。若进程在负载均衡器将 Pod IP 从后端移除前,kubelet 就将容器停止,则仍然可能会有新的请求,尝试连接一个不存在的 IP 。若业务层没有重试机制,则请求会失败。

所以,我们需要等待一段时间,再去停止容器。我们可以借助 preStopHook 钩子,在容器停止前等待一段时间:

lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10"]

我们不采用同步方案,让负载均衡器与 kubelet 严格地保证操作顺序执行,因为会过于复杂,且与具体外部负载均衡器实现耦合。例子中的 sleep 时间,可结合生产环境中负载均衡器下线后端反应时间来调整。

结束当前实例上连接

前面我们实现了,先让 Pod 从负载均衡器下线,再结束进程,以避免新的请求在进程结束后,连入进来。但进程还存在当前连接,我们需要结束进程前,先通知进程主动通知客户端关闭连接等。

这步操作与具体的业务的实现有关,我们以 tidb-server 举例。

kubelet 的默认停止容器使用的 SIGTERM 信号,tidb-server 在此信号下会进行优雅退出,但超时时间只有 15 秒,若线上有比较耗时较长的请求,是不够当前连接正常退出的。

tidb-server 在收到 SIGQUIT 信号时会进行不限时的优雅退出,流程如下:

  • 关闭 listeners
  • 遍历当前连接,关闭空闲连接
  • 其余的尝试在应用层协议通知客户端主动关闭

因此,我们不可能使用 kubelet 的默认停止容器使用的 SIGTERM 信号,而是应主动发送 SIGQUIT 给 tidb-server 进程通知其以更优雅的方式运行。

lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10 && kill -QUIT 1"]

PID 1 为容器内 root 进程。注意需要将进行作为 root 进程运行,或者 root 进程可以将信号转发给子业务进程,比如使用 tini 时。

优雅停止超时时间

前面我们不仅在停止服务前通知负载均衡器先将 Pod IP 从后端移除,同时通知应用采用主动通知并结束当前连接后,再退出。但还有一个问题是,许多时候,当前连接要完全优雅结束需要很久,比如一些长连接应用。Kubelet 给 Pod 默认允许的优雅退出时间是 30s,我们需要结合具体应用,配置恰当的超时时间。可以在 pod.spec.terminationGracePeriodSeconds 字段配置:

terminationGracePeriodSeconds: 60
lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10 && kill -QUIT 1"]

至此,我们就实现了完美的优雅退出方案。

结语

我们可以将优雅退出阶段分为以下几部分:

  • 通知负载均衡器将 Pod IP 从后端列表下线
  • 通知应用优雅结束当前连接
  • 配置合理的超时时间,给予应用足够的优雅退出时间

其中具体时间参数,以及通知应用方法需要结合具体应用而定。本文抛砖引玉,以 tidb-server 为例,主要分析思路,和 Kubernetes 中可采用机制。

转发自:https://zhuanlan.zhihu.com/p/188674410

标签:负载,Kubernetes,优雅,停止,均衡器,Pod,连接
来源: https://www.cnblogs.com/fuyuteng/p/16332122.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有