首页 新闻 会员 周边

Kubernetes 真的是无缝吗,停掉的pod会被负载到这台吗

0
[已关闭问题] 关闭于 2026-06-26 08:03

实现“零停机”的滚动更新 即使只有几千访问量,你的应用也需要经常发版修复 Bug 或上线新功能。如果只有 1 个副本,每次发版重启的那几十秒甚至几分钟内,用户访问就会直接报错。而有了多个副本,Kubernetes 可以采用滚动更新策略(比如先停掉 1 个旧副本,启动 1 个新副本),在更新期间始终有实例提供服务,实现真正的“无缝发布”。 真的是无缝吗,停掉的pod会被负载到这台吗

*Tesla*的主页 *Tesla* | 小虾三级 | 园豆:1850
提问于:2026-06-26 08:02
< >
分享
所有回答(1)
0

1. K8s 底层机制:它是怎么做到“无缝”的?

在默认的滚动更新策略中,K8s 并不是“先停旧的,再启新的”,而是“先启新的,确认新的没问题了,再停旧的”。
具体流程是这样的:
  1. K8s 启动一个新 Pod。
  2. K8s 会检查新 Pod 的 Readiness Probe(就绪探针)。只有当探针连续返回成功,K8s 才会认为这个新 Pod 真的可以接客了。
  3. K8s 将这个新 Pod 加入 Service 的 Endpoints(也就是负载均衡器的后端列表)。
  4. 最关键的一步:K8s 才会向旧 Pod 发送停止信号(SIGTERM)。
所以,从 K8s 的视角来看,它绝对不会把流量路由到一个正在被停掉的 Pod 上。

2. 为什么实际中还是可能报错?(应用代码的坑)

虽然 K8s 的机制很完美,但如果你的应用代码没有处理好“优雅停机(Graceful Shutdown)”,依然会出问题。
当 K8s 给旧 Pod 发送 SIGTERM 信号时,Pod 不会瞬间死亡,而是进入 Terminating 状态(默认有 30 秒的宽限期)。问题就出在这几秒的时间差上:
  • 坑点 1:负载均衡器的延迟
    当 K8s 把旧 Pod 从 Endpoints 中摘除时,如果你使用的是 Nginx Ingress 等负载均衡器,它需要时间去同步这个列表(通常有几秒的延迟)。在这几秒内,如果有新请求进来,负载均衡器可能不知道旧 Pod 已经要死了,依然把请求转发给了它,导致连接被拒绝。
  • 坑点 2:应用没有处理 SIGTERM 信号
    如果应用收到 SIGTERM 后,直接粗暴地关闭了监听端口,但此时还有几个正在处理中的请求没执行完,这些请求就会直接断开,用户就会看到报错。

3. 如何做到真正的“无缝”?

要做到真正的零停机,K8s 和应用代码必须打配合:
  1. 应用必须支持优雅停机:代码里要监听 SIGTERM 信号。收到信号后,立刻停止接收新请求(从负载均衡中摘除自己),但继续处理完手里正在执行的旧请求,处理完后再彻底退出。
  2. 配置 preStop 钩子:在 K8s 中配置 preStop 钩子,让 Pod 在真正收到 SIGTERM 之前,先强制睡眠几秒钟(比如 5 秒)。这 5 秒就是留给负载均衡器去同步 Endpoints 列表的时间。等列表同步完了,再让应用真正开始停机。
  3. 合理配置就绪探针:确保新 Pod 真的把数据库连接池、缓存等全部初始化完毕后,再对外提供服务。
总结一下:K8s 的滚动更新机制在调度层面确实是无缝的,它绝不会把流量分给一个正在死去的 Pod。但在网络同步和应用退出层面,如果应用代码没写好“优雅停机”,或者负载均衡器同步太慢,依然会有短暂的报错。所以,“无缝”不仅靠 K8s,更靠应用架构的严谨设计。
*Tesla* | 园豆:1850 (小虾三级) | 2026-06-26 08:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册