滚动更新期间旧副本连接如何处理,draining怎么配置?

让工作在滚动更新期间连接不断,关键步骤是正确配置Pod的preStop钩子和terminationGracePeriodSeconds,同时依赖Service的Endpoints机制配合就绪探针,确保新Pod就绪后才摘除旧Pod。

滚动更新已有连接为什么会断:先理解draining原理

很多人遇到滚动更新时连接闪断,第一反应是去调Service配置,其实问题通常出在Pod生命周期管理上,Kubernetes在滚动更新时对旧副本的处理不是直接“杀掉”,而是执行一系列有序操作这个流程就是draining,中文常译作“排空”或“优雅终止”。

你的电脑设备需要修复winload.efi无法加载应用程序所需文件丢失或错误引导配置数据文件不包含有效的操作系统信息#内容启发搜索 #电脑重装系统 #电脑
加载中
你的电脑设备需要修复winload.efi无法加载应用程序所需文件丢失或错误引导配置数据文件不包含有效的操作系统信息#内容启发搜索 #电脑重装系统 #电脑
群
群森电脑家电
7.8万--
原视频地址

官方文档对Pod终止流程有明确描述:当Deployment滚动更新发生时,旧Pod会被标记为Terminating,同时从Service的Endpoints列表中移除,但这里有个关键细节:从Endpoints移除和Pod真正停止之间有时间差,如果新连接刚好被转发到正在Terminating的Pod上,而Pod进程已经关闭了监听端口,连接就会立即失败,业内专家指出,大多数滚动更新连接中断问题,都源于没有给这个时间差留出足够缓冲。

draining状态到底是什么

draining不是Kubernetes中的正式API对象,而是对Pod终止过程的一种描述,具体到旧副本,它的生命周期是这样的:

  1. Deployment控制器将旧Pod的spec.template更新为新版本,同时将旧Pod的desired数量减1
  2. kubelet收到终止请求,Pod进入Terminating阶段
  3. kubelet并行执行两个动作:将Pod从Service的Endpoints中摘除(通过EndpointSlice控制器),同时执行preStop钩子(如果配置了)
  4. 等待preStop钩子执行完成,或者超过terminationGracePeriodSeconds(默认30秒)
  5. kubelet向Pod发送SIGTERM信号
  6. 如果进程在宽限期结束前未退出,kubelet发送SIGKILL强制终止

这里最容易被忽视的是第3步和第4步之间。Endpoints摘除是异步的,从kubelet发起终止到EndpointSlice控制器真正更新,可能需要数秒时间,在这期间,Service仍然可能把新连接转发到旧Pod上,如果旧Pod执行preStop时直接睡觉,不关闭监听,连接就能正常建立;但如果preStop里什么都没做,Pod进程收到SIGTERM后立刻关闭监听端口,那么在这几秒内到达的连接就会被拒。

滚动更新期间连接中断怎么办:先检查这三个位置

如果你已经遇到连接失败,排查顺序应该是:

  • 查看Pod事件:kubectl describe pod <pod-name>,确认是否有Killing或Unhealthy事件
  • 确认应用是否处理了SIGTERM信号:很多开发语言框架默认不处理,直接退出
  • 检查就绪探针的配置:readinessProbe的initialDelaySeconds是否过短,导致新Pod还没准备好就被打进Endpoints

多数情况下,问题不是Kubernetes配置错误,而是应用本身没有优雅退出能力,比如Nginx需要nginx -s quit而不是直接kill,Java应用需要关闭Spring Boot的优雅停机开关,Node.js需要监听SIGTERM并关闭HTTP server。

Kubernetes滚动更新旧副本连接断开怎么办:配置优雅停止

要解决连接断开,核心是拉长从“摘除Endpoints”到“进程关闭监听端口”之间的窗口,最常用的做法是配置preStop钩子,让Pod在收到SIGTERM之前先等几秒钟,给EndpointSlice控制器足够时间完成更新。

实操:给Deployment添加preStop和就绪探针

下面是一个经过验证的Deployment配置片段,演示了如何正确处理滚动更新期间的连接:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      terminationGracePeriodSeconds: 60
      containers:
      - name: app
        image: nginx:1.25
        ports:
        - containerPort: 80
        lifecycle:
          preStop:
            exec:
              command: ["sh", "-c", "sleep 10"]
        readinessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 5
          periodSeconds: 5
        startupProbe:
          httpGet:
            path: /healthz
            port: 80
          failureThreshold: 30
          periodSeconds: 5

关键点说明:

  • preStop中的sleep 10不是无意义的延时,它让Pod在收到SIGTERM之前保持运行,等待Service Endpoints完成更新,行业共识认为,10秒是绝大多数集群中Endpoints更新最坏情况的安全值,如果集群节点数较多或网络延迟大,可以适当增加到15秒。
  • terminationGracePeriodSeconds: 60必须大于preStop时长加应用自身优雅退出的时间,如果这里设置为30,而preStop睡眠20秒,应用只剩10秒处理收尾,可能不够。
  • readinessProbe确保新副本在真正就绪后才被加入Service的Endpoints列表,注意initialDelaySeconds要评估应用启动耗时,不能设得太短。
  • startupProbe是给启动很慢的应用准备的,它允许应用在启动期间不触发readiness探针的失败记录,避免滚动更新卡死。

已有连接如何处理:应用层必须做好这两件事

Kubernetes侧的配置只能保证连接不被重置,但已经建立的连接怎么办,取决于应用自身的行为,正确流程是:

  1. preStop执行期间,Pod仍运行,已有的TCP连接不受影响
  2. kubelet发送SIGTERM后,应用收到信号,停止接收新请求,同时开始处理完当前正在进行的请求
  3. 应用主动关闭空闲连接和Keep-Alive连接,让客户端感知到连接关闭
  4. 全部请求处理完毕后,进程退出,kubelet回收Pod

如果你的应用是HTTP服务,建议在收到SIGTERM后禁用Keep-Alive,并设置一个最大等待时间,比如Nginx可在preStop里发送nginx -s quit,但更稳妥的方式是在preStop中先sleep,再执行quit。

滚动更新优雅停止超时设置:terminationGracePeriodSeconds到底填多少

这个参数很多人直接留默认30秒,但遇到大请求或长轮询就会出问题,给出一个计算参考:

  • (总宽限期 \ge preStop时长 + 应用处理存量请求的最大时间 + 安全余量)
  • 如果业务接口平均响应时间2秒,最慢请求10秒,preStop设5秒,那么总宽限期建议为5 + 10 + 5 = 20秒以上,保守设为40秒更稳
  • 注意:总宽限期不是越大越好,如果设置成600秒,而应用不响应SIGTERM,Pod会被卡在Terminating状态很久,滚动更新会卡住,建议同时配置terminationGracePeriodSeconds和应用进程内的最大退出等待时间,两者取较小值。

滚动更新时的连接排空:两种常见场景处理方案

不同业务对连接处理的要求差异很大,这里拆成两个典型场景说明。

无状态HTTP服务(如Web API、前端Nginx)

这类服务最怕的是请求被转发到正在关闭的Pod上,操作路径:

  1. 确保Deployment配置了preStop和readinessProbe
  2. 在Service中使用sessionAffinity: None(默认),让新请求均匀分布到新Pod
  3. 如果使用Ingress,确认Ingress Controller与Service的externalTrafficPolicy设置,需要保留客户端真实IP时,设externalTrafficPolicy: Local,但这会导致流量转发到无本地副本的节点时被丢弃,滚动更新期间可能出现少量请求失败,更推荐用Cluster模式配合nginx.ingress.kubernetes.io/service-upstream注解

有状态长连接服务(如WebSocket、gRPC Stream)

这些连接无法通过HTTP探针感知,需要更精细的排空策略:

  • 在readinessProbe中增加一个“排空状态”端点,当Pod开始准备终止时,应用内部设置一个标志位,让/healthz返回失败,这样Kubernetes会提前将Pod从Endpoints摘除,即使还在等preStop结束
  • preStop里除了sleep,还应主动向已连接的客户端发送关闭通知,比如WebSocket服务可以广播一个{"type":"shutdown"}消息,让客户端主动重连
  • 对于gRPC Stream,可以在SIGTERM时调用Server.GracefulStop(),并在preStop中留出足够时间让客户端感知连接关闭

滚动更新期间旧副本连接处理的Q&A

Q1:为什么我配置了preStop,滚动更新时还是有连接中断?

最常见原因是preStop中只执行了sleep,但应用在收到SIGTERM后立即关闭了监听端口。preStop只是延迟发送信号,并不能阻止应用崩溃,请检查应用是否正确捕获了SIGTERM并执行优雅退出代码,另一个可能原因是Service的Endpoints更新比preStop执行更慢这个可以用kubectl get endpoints -w观察更新延迟,如果延迟超过preStop时长,就需要加长sleep时间或改用上述“排空状态端点”方案。

Q2:滚动更新时新Pod一直处于ContainerCreating,卡住了怎么办?

通常是因为readinessProbe失败导致新Pod永远不算就绪,旧Pod无法被替换,检查探针路径和端口是否正确,确认应用在启动期间是否能够响应探针,如果应用需要读取配置或连接数据库,确保这些依赖在探针超时时间内可用。terminationGracePeriodSeconds过长而旧Pod进程不退出,也会让滚动更新停滞,可以用kubectl rollout status deployment/web-app观察详细状态。

Q3:distributed system中draining和cluster autoscaler的节点排空有什么区别?

Kubernetes中的节点排空(kubectl drain)针对的是整台节点上的所有Pod,用于节点维护或缩容,它会先把节点标记为不可调度,然后对每个Pod执行与滚动更新相同的终止流程即preStop、SIGTERM、宽限期强制终止,如果你的Pod有PVC,drain还会检查PodDisruptionBudget,而滚动更新的draining是Deployment控制器内部的行为,只针对被替换的旧副本,两者在技术底层的Pod终止机制完全一致,但触发条件和调度策略不同,节点排空需要你手动设置--ignore-daemonsets等参数,而滚动更新不需要额外操作。

滚动更新期间的连接处理,本质上是对“Pod终止”这个事件的充分准备,记住一条主线:先摘除流量,再优雅退出,最后强杀兜底,配置好preStop和探针,让你的应用对SIGTERM保持敬意,连接中断就能从“必然”变成“偶然”。

首发原创文章,作者:王坚‌,如若转载,请注明出处:https://idctop.com/article/776083.html

赞 (0)
上一篇 2026年10月29日 21:09
下一篇 2026年10月29日 21:11

相关推荐

  • 服务器域名加入白名单,这一举措背后的原因和意义是什么?

    要将服务器域名加入白名单,通常指在防火墙、安全组、邮件系统、CDN服务或应用程序中,通过配置允许特定域名或IP地址访问资源,以提升安全性和控制访问权限,这一操作对于防止未授权访问、减少恶意流量至关重要,以下是具体步骤和注意事项,帮助您高效完成配置,理解白名单的作用与适用场景白名单是一种安全机制,仅允许列表中的域……

    2026年2月4日
    18100
  • 6家大模型牌照发放意味着什么?大模型牌照有什么用?

    国内大模型牌照的发放,本质上是监管层在技术爆发期划定的一道“安全红线”与“市场准入门槛”,首批仅6家获批,这不仅是对企业技术实力的认可,更是对数据安全与合规能力的最高级背书, 在这6张牌照背后,折射出的是行业从“野蛮生长”转向“规范发展”的根本性逻辑变化,对于行业观察者和从业者而言,关于6家大模型牌照,说点大实……

    2026年3月6日
    20900
  • 高防CDN防御哪家好?高防CDN防御怎么选?

    对于2026年企业级网络安全防御,高防CDN防御已成为抵御大规模DDoS攻击和CC攻击的最有效手段,其通过分布式节点清洗恶意流量,保障业务连续性与访问速度,高防CDN防御原理与核心架构基于边缘节点的流量清洗机制高防CDN防御原理在于将攻击流量分散至全球边缘节点,通过智能DNS调度和负载均衡技术,将正常请求转发至……

    2026年7月20日
    8500
  • 选七层负载均衡前要确认证书管理成本吗,有哪些坑

    在选七层负载均衡之前,如果没提前把证书管理成本算清楚,上线后大概率会被证书过期、配置混乱和续期加班反复折腾,很多团队选型时盯着转发性能、会话保持和健康检查,等真正把域名切到七层负载均衡上,才发现证书这件事远比想象中麻烦,本文把证书管理成本的构成、常见坑点和选型考察项一次说透,为什么证书管理成本被严重低估七层负载……

    2026年9月8日
    600
  • 韩国免费cdn能用吗?韩国免费cdn哪个稳定

    2026年韩国免费CDN虽能缓解基础带宽压力,但因节点稳定性差、SSL证书缺失及合规风险,仅建议用于非核心静态资源测试,企业级业务务必选择付费方案以保障访问速度与数据安全,韩国免费CDN的技术局限与真实体验在2026年的网络基础设施环境下,虽然部分服务商提供“免费”层级服务,但其底层逻辑与付费CDN存在本质差异……

    2026年6月15日
    3100
  • 大模型训练推理区别怎么样?消费者真实评价如何?

    大模型训练与推理在技术路径、资源需求、性能表现上存在本质差异,消费者真实评价普遍反映:训练是“幕后硬仗”,推理是“台前体验”,二者协同决定模型落地效果,以下从五个维度拆解核心区别,并结合真实用户反馈,为行业实践提供可落地的参考依据,技术本质差异:训练是“学知识”,推理是“用知识”训练阶段目标:通过海量数据拟合参……

    云计算 2026年4月16日
    5100
  • CDN和OSS之间有什么区别?CDN和OSS如何选择搭配使用

    协同效应与关键指标回源优化:CDN缓存命中率可达95%以上,OSS回源请求减少,源站压力骤降,成本降低:CDN流量费用通常低于OSS的外网流量,配合使用可使总带宽成本下降40%~50%,性能提升:据2026年《中国CDN市场研究报告》,采用CDN+OSS的网站首屏时间平均缩短至1.2秒内,远优于纯OSS的3.5……

    2026年7月22日
    2000
  • cdn路由器设置教程,cdn路由器设置方法

    CDN路由器设置的核心在于优化DNS解析优先级、配置QoS流量整形及开启硬件加速,2026年行业共识表明,正确配置可将视频加载延迟降低40%以上,显著提升用户体验,在2026年的网络环境中,随着4K/8K流媒体、云游戏及VR应用的普及,传统的宽带路由已无法满足低延迟、高并发的需求,CDN(内容分发网络)路由器的……

    2026年5月19日
    5900
  • 北京cdn服务的公司哪家好?北京cdn服务商哪家强

    2026年北京CDN服务首选具备国家级骨干网节点布局、支持HTTP/3协议及具备金融级安全防护能力的头部云厂商,如阿里云、腾讯云及网宿科技,其核心优势在于低延迟与高并发稳定性,2026年北京CDN市场核心格局解析随着北京作为全国数字经济高地的地位进一步巩固,企业对内容分发网络(CDN)的需求已从单纯的“加速”转……

    2026年5月13日
    5800
  • jquery sina cdn,jquery sina cdn地址

    在2026年的Web开发环境中,使用jQuery Sina CDN不仅是降低服务器负载的高效方案,更是保障国内用户访问速度与稳定性的最佳实践,其核心优势在于极高的国内节点覆盖率与零维护成本,随着前端技术栈的迭代,虽然原生JavaScript和现代框架(如Vue、React)已占据主流,但jQuery凭借其庞大的……

    2026年7月10日
    9000

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注