记一次应用优雅下线排查经历

简介: 本文记录了一次线上应用发版时出现500错误的排查过程。问题出现在滚动更新过程中,部分请求调度到了正在下线的Pod,导致500错误。通过增加PreStop Hook、调整TerminationGracePeriodSeconds以及配置Java应用的优雅下线,最终解决了问题。此外,还发现SLB的长连接问题,并通过配置SLB优雅下线彻底解决了请求失败的情况。

1. 背景

最近和同事一起排查了下发版时应用会出现500错误的异常,感觉还是挺有意思的,这里做下记录,以便后续遇到问题时进行翻阅。

2. 问题状况

我们线上环境是使用的ack集群,发版时应用service对应的deployment下的pod会进行滚动更新,这种情况下会出现部分接口报500错误,初步判断是有请求调度到了正在下线中的pod,即Terminating状态,这样导致这部分请求出现报错。

3. 排查经过

出现这种问题时,已经考虑到是没做好优雅下线的问题,于是去网上搜了一下解决方式,做好java程序的优化下线,主要要做以下两件事情:

  1. 容器关闭时增加前置处理,让容器先不进行关闭操作,这样给k8s留出时间去修改服务的路由分发规则,同时增加容器优雅关闭时间 terminationGracePeriodSeconds,留出更多的时间供容器关闭。
  2. 应用内做好优雅下线设置。

3.1 容器配置修改

3.1.1 pod被删除原理

deployment下pod被删除时,会触发两条路径进行操作:
Pod层面

  1. Pod被删除会被置为Terminating状态
  2. Kubelet捕捉到Pod的变化,执行syncPod动作
  3. 如果Pod设置了PreStop Hook,会先执行PreStop Hook
  4. kubelet 对 Pod 中各个 container 发送调用 cri 接口中 StopContainer 方法,向 dockerd 发送 stop -t 指令,用 SIGTERM 信号以通知容器内应用进程开始优雅停止。
  5. 等待容器内应用进程完全停止,如果容器在 gracePeriod 执行时间内还未完全停止,就发送 SIGKILL 信号强制杀死应用进程(容器运行时处理)。
  6. 所有容器进程终止,清理 Pod 资源。

网络层面

  1. Pod 被删除,状态置为 Terminating。
  2. Endpoint Controller 将该 Pod 的 ip 从 Endpoint 对象中删除。
  3. Kube-proxy 根据 Endpoint 对象的改变更新 iptables/ipvs 规则,不再将流量路由到被删除的 Pod。
  4. 如果还有其他 Gateway 依赖 Endpoint 资源变化的,也会改变自己的配置(比如 Nginx Ingress Controller)。

具体关闭过程如下图所示:
image.png
通过上图可以得知,我们可以通过设置PreStop来sleep一定的时间,让网络层面有时间去修改路由规则,这样在pod关闭的时候,不会有请求进入,以避免出现问题,这也是优雅下线的主要设置。
因为TerminationGracePeriodSeconds是整个Pod的优雅下线等待时间,默认为30s,现在增加了PreStop执行时间后,TerminationGracePeriodSeconds时间也要进行相应的增加。

3.1.2 容器配置修改

修改deployment配置,进行以下操作:

  1. 增加PreStop Hook,在pod停止前sleep 30s,给k8s预留pod删除后修改endpoint中端点和iptables时间,使请求不会路由到正在关闭中的Pod上。
    image.png

  2. 增加TerminationGracePeriodSeconds到60s,因为有30s分给了PreStop Hook,所以将TerminationGracePeriodSeconds从30s改到60s。
    image.png

3.2 java应用内配置优雅下线

Spring Boot中启用优雅下线可以在配置中配置以下内容:

server:
    shutdown: graceful

spring:
    lifecycle:
         timeout-per-shutdown-phase: 30s

通过使用上述配置,Spring Boot 保证在收到 SIGTERM 后不再接受新请求,并在超时内完成所有正在进行的请求的处理。即使无法及时完成,也会记录相关信息,然后强制退出。对于 timeout 的值,应参考处理请求的最大允许持续时间。
这里可以看到,主要还是说正在进行的请求要预留时间进行处理,对于不接受新请求,如果前面路由没有正确修改,还是会有请求进来,只是被拒绝连接,这个请求一样没得到正确处理。

3.3 SLB长连接问题

经过前两项修改以后,进行了尝试,本来以为会没有500错误了,结果还是有错误出现,这里我以为是PreStop里sleep时间不够,于是就改大该时间到150s,发现还是不行,排查到这里有点没思路了,因为按前面的原理分析,这个优雅下线应该是没问题的了。这时候突然想到之前看过k8s的书,里面有关于Pod优雅关闭的描述,里面有提到Pod下线后,网络路由的修改并不会影响已有连接,也就是说虽然上面的设置会让新的连接指向新的Pod,但已有连接并不会改变,于是猜测是这个原因导致的,但怎么解决呢,当时并没有太多的思路。
后面同事查到SLB也可以进行优雅下线设置,进行设置后解决了问题,这里也印证了之前的想法是对的,就是已有连接导致的请求失败,只是当时不知道已有连接怎么设置断开,SLB设置优雅下线的方式为增加如下注解。
image.png
这个配置代表开启slb优雅下线,并且排空超时时间为30s,连接排空超时指定了在负载均衡器停止接收新连接之前,它将保持现有连接的时间。这个时间段内,负载均衡器会依旧允许现有的会话继续活动,从而为正在处理的请求争取时间,使其能够完成。
可以理解为负载均衡上已有连接在Pod已经是Terminating状态的情况下,会允许长连接再保持一段时间,用来处理已有请求,和应用内优雅下线处理类似。

4 总结

应用未优雅下线这个问题,前期根据网上信息进行设置,还是比较容易理解和配置的,但配置完了之后发现并不生效,这个时候由于缺少中间链路的日志信息,并不太清楚请求是落到哪个Pod导致的超时,所以导致排查一度比较困难和没有思路。当时虽然猜到了已有长连接可能存在影响,但不是特别确定,并且对怎么停掉之前的长连接不是特别有思路,要不然可以更快的解决问题,后续遇到这种还是应该沿着自己认为的方向接着去探索。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
SQL 监控 网络协议
线上故障如何快速排查?来看这套技巧大全
有哪些常见的线上故障?如何快速定位问题?本文详细总结工作中的经验,从服务器、Java应用、数据库、Redis、网络和业务六个层面分享线上故障排查的思路和技巧。较长,同学们可收藏后再看。
线上故障如何快速排查?来看这套技巧大全
|
4月前
|
Kubernetes 安全 Docker
在K8S中,在服务上线的时候Pod起不来怎么进行排查?
在K8S中,在服务上线的时候Pod起不来怎么进行排查?
|
7月前
|
SQL 监控 数据库
线上服务假死排查
线上服务假死排查
54 0
|
7月前
|
SQL 运维 监控
如何排查线上问题的?
在当今的互联网时代,线上问题对企业的业务连续性和用户体验产生的影响越来越大。无论是网站崩溃、应用性能下降,还是服务中断,这些问题都可能对企业的声誉和用户满意度造成严重影响。因此,快速、准确地排查并解决线上问题变得至关重要。本文将介绍一些高效的线上问题排查方法,帮助您在面对线上问题时,迅速定位并解决问题。我们将在接下来的内容中详细讨论如何利用日志分析、监控系统、代码审查等手段,以及如何制定有效的应急预案。通过这些策略的实施,您将能够提高线上问题的解决速度,减少对业务的影响,并提高用户满意度。
170 2
|
运维 监控 前端开发
记一次线上 bug 的排查分析过程及总结
记一次线上 bug 的排查分析过程及总结
记一次线上 bug 的排查分析过程及总结
|
SQL 存储 运维
能解决 80% 故障的排查思路 ,建议大家收藏。。
能解决 80% 故障的排查思路 ,建议大家收藏。。
261 0
能解决 80% 故障的排查思路 ,建议大家收藏。。
|
7月前
|
运维 监控 Java
线上故障突突突?如何紧急诊断、排查与恢复
本文简单介绍了阿里云上关于故障恢复、诊断的一些最佳实践。
线上故障突突突?如何紧急诊断、排查与恢复
|
运维 监控 NoSQL
排查线上问题的9种方式
排查线上问题的9种方式
 排查线上问题的9种方式
|
Web App开发 运维 前端开发
【分享】前端线上紧急排查工具
【分享】前端线上紧急排查工具
365 0
【分享】前端线上紧急排查工具