滚动更新时大文件上传中断本质是pod生命周期切换中流量路由与应用就绪状态不同步;需通过业务级就绪探针、prestop优雅终止、分片上传及监控告警等组合策略保障。

滚动更新时大文件上传中断,本质是连接被意外切断——不是网络丢包,而是 Kubernetes 在 Pod 生命周期切换过程中,流量路由与应用实际就绪状态不同步导致的。关键不在“传多大”,而在“传多久”:一个 500MB 文件按 2MB/s 上传需约 4 分钟,而默认滚动更新的就绪探测、preStop 延迟、SLB 同步窗口往往只有几秒,远不足以覆盖长连接生命周期。
确保新 Pod 真正可服务再接入流量
仅靠 containerPort 开放或 Pod 状态为 Running 不代表能处理上传请求。必须让业务层明确反馈“已初始化完成、缓冲区就绪、临时存储挂载正常”。
- 就绪探针(readinessProbe)必须调用业务真实健康端点,例如
GET /healthz?ready=upload,该接口需校验:上传目录可写、对象存储凭证有效、数据库连接池 warmup 完成 - 避免使用简单
httpGet到/或/health,这类响应可能在应用主进程启动后立即返回,但上传模块尚未加载 -
initialDelaySeconds建议设为 15–30 秒(视冷启动耗时),periodSeconds设为 3–5 秒,失败阈值failureThreshold≥3,防止偶发抖动误判
优雅终止旧 Pod,守住正在上传的连接
旧 Pod 被标记 Terminating 后,若立即关闭监听或拒绝新连接,正在传输的 TCP 流会被 RST 中断;若未等待已有连接自然结束,客户端会收到 Connection reset 或超时。
- 配置 preStop Hook 执行
sleep+ 主动 drain:例如先调用curl -X POST http://localhost:8080/upload/drain关闭新连接入口,再 sleep 至少等于最大单次上传预期时长(如 300 秒) - terminationGracePeriodSeconds 必须 ≥ preStop 总耗时(含 HTTP 调用延迟),建议设为 360(6 分钟),留出安全余量
- 应用代码内需捕获
SIGTERM,停止接受新上传请求,但不中断已有 socket 连接,允许正在进行的上传走完
绕过 Service 层直连与连接保持优化
LoadBalancer 或 Ingress 的连接同步存在延迟(尤其云厂商 SLB),且默认复用连接池策略可能将新请求打到刚终止的 Pod。对大文件场景,应减少中间转发跳数和状态同步依赖。
- 前端上传 SDK 启用分片上传(如 tus、AWS S3 multipart),每片独立 HTTP 请求,失败可重试单片而非整文件
- 若使用 Nginx Ingress,启用
proxy-next-upstream-tries 3和proxy-next-upstream-timeout 60s,自动重试失败上传请求 - 关键业务可考虑客户端直连 NodePort + 客户端负载均衡(如轮询 + 主动健康检查),跳过 kube-proxy 和云 SLB 的异步 Endpoint 同步环节
补充保障:监控与兜底机制
即使配置完备,仍需可观测性验证效果并快速响应异常。
- 在 Prometheus 中采集
kube_pod_status_phase{phase="Terminating"}和nginx_ingress_controller_requests{status=~"5.."},设置告警:滚动更新期间 5xx 率突增 >0.5% 持续 2 分钟 - 日志中统一标记上传请求 ID(如 X-Request-ID),关联 Pod 名称与时间戳,便于排查中断发生在哪个生命周期阶段
- 上线前用
hey -z 5m -c 10 -D upload-file.bin http://svc/upload模拟长连接压测,观察是否出现connection refused或broken pipe











