在删除pod 的过程中,有两条平行的时间线。一是改变网络规则的时间线,另一个是 pod 的删除。

网络规则生效删除 pod注意:这个优雅退出的等待计时spec.terminationGracePeriodSeconds是与 preStop 同步开始的,而且它也不会等待 preStop 结束
502应用程序在收到 SIGTERM 信号后直接终止了运行,导致部分还没有被处理完的请求直接中断,代理层返回 502
504Service Endpoints 移除不够及时,在 Pod 已经被终止后,仍然有个别请求被路由到了该 Pod,得不到响应导致 504
为容器内的进程设置正常关闭以 SpringBoot 为例,启用优雅关闭可以 Spring Boot 配置文件中添加下面设置
server:
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
可以解决502的问题
添加 preStopHook当kube-apiserver 接收到 pod 删除请求后,必须要预留一段时间,来等待网络规则的更新,避免新的流量路由到一个不可用的pod上 。
因此,应该让 Kubelet 在收到删除 pod 事件时“sleep 一下”,并在给Pod发送SIGTERM之前留出足够的时间来更新网络规则。
containers:
- name: my-app
# 添加下面这部分
lifecycle:
preStop:
exec:
command:
- /bin/sh
- -c
- "sleep 10"
可以解决504的问题
修改终止 GracePeriodSecondsKubernetes 为容器删除留下了 30 秒的最大时间尺度。如果 Spring 的优雅关闭超时时间和 Kubernetes 的 preStopHooks 之和超过 30 秒,可能会导致 Kubernetes 在 Spring Boot 处理完请求之前强行删除容器。因此,如果过程超过 30 秒,则应将 timerminationGracePeriodSeconds 调整为大于30秒
下图显示了设置后的时间线:

参考文章:docker制作java镜像

K8s里Spring 微服务项目,Pod 关闭对用户的影响比较大!
在 Kubernetes 容器集群,微服务项目最佳实践