当伸缩触发时如何保证长连接不中断

解读

在国内云原生落地场景里,Docker 容器往往作为 Kubernetes Pod 运行,伸缩动作由 HPA 或 Cluster-Autoscaler 触发。面试官真正关心的是:

  1. 你是否意识到 长连接(TCP、WebSocket、gRPC 等)生命周期与 Pod 生命周期不一致
  2. 能否在 Docker 镜像层、编排层、流量层 给出可落地的“零中断”方案;
  3. 是否熟悉 阿里 ACK、腾讯 TKE、华为 CCE 等国内发行版 的特有机制(如 SLB 优雅下线、CLB 连接复用、Service 级 Graceful Termination)。
    回答必须体现“Docker 视角”,即镜像怎么配合、容器怎么退出、Registry 如何加速回滚,而不是泛泛地只讲 K8s。

知识点

  1. Dockerfile 信号处理STOPSIGNAL SIGTERMENTRYPOINT ["tini", "-g", "--", "yourServer"] 保证容器收到 SIGTERM 后 立刻进入优雅关闭流程
  2. 镜像内健康检查HEALTHCHECK --interval=5s --timeout=3s --retries=3 CMD /health.shkubelet 精准感知 Pod Ready 状态,避免过早摘除。
  3. PreStop Hook 与 Docker 生命周期钩子:在 docker-compose.yml 或 K8s lifecycle.preStop.exec.command 里执行 sleep 15 && curl -X POST http://localhost:8080/gracefulShutdown给长连接 15 s 缓冲
  4. 连接迁移技术
    • SO_REUSEPORT + 无状态设计:镜像里打开 reuseport 选项,使新建流量可瞬间漂到新副本;
    • MSE/ASM 服务网格(阿里)或 Istio优雅下线接口:Sidecar 收到 SIGTERM 后通知 Envoy 把该 Pod 置为 “排空” 状态,持续 30 s 不再分配新连接,老连接自然结束。
  5. 国内云厂商 SLB 特性
    • 阿里 SLB “优雅中断” 开关:控制台设置 “连接优雅中断时长”=300 s,与容器优雅时间对齐;
    • 腾讯 CLB “连接复用保持” 需关闭,否则 FIN_WAIT2 堆积。
  6. Registry 加速回滚:把 旧版本镜像 保留 至少两个版本标签,当新版本因长连接异常导致大量 5xx 时,HPA 回滚事件可在 30 s 内 完成 docker pull <旧镜像> 并重新扩容。

答案

“我分四层保证长连接不中断:

  1. 镜像层:Dockerfile 里用 tini 做 init,设置 STOPSIGNAL SIGTERM,并把 优雅关闭脚本 写进镜像 /graceful.sh,确保容器收到终止信号后 先关闭监听端口,再等待已有连接处理完
  2. 容器层:在 Compose 或 K8s YAML 中增加 preStop: exec: command: ["/bin/sh", "-c", "sleep 20"]把 Pod 置为 Terminating 后继续服务 20 s,同时把 readinessProbe 的 successThreshold=1 改为 2防止 kubelet 过早把 Pod 从 EndpointSlice 摘除
  3. 流量层:使用 阿里云 ACK 的 Terway 网络插件,配合 SLB 的 “优雅中断” 功能,设置 deregistration_delay=300 s;如果走 Ingress-Nginx,再打开 worker-shutdown-timeout: 300s让 SLB 与 Ingress 同时感知 Pod 下线,保证 四层和七层长连接 都有 300 s 的排空窗口。
  4. 运维层:在 Harbor 私有仓库 里给镜像打 双标签v1.2.3stable),HPA 扩容时优先拉 stable,当发现新版本长连接异常升高,Argo Rollout 立即触发回滚30 s 内 完成旧镜像重新部署,连接中断率控制在 0.01% 以下
    通过这四层,我们线上 WebSocket 在线课堂 业务在 晚高峰 5 倍弹性伸缩 时,长连接零中断,用户无感知。”

拓展思考

  1. 如果业务是 MQTT over TLS,如何在 Docker 镜像里嵌入 OCSP Stapling 减少 TLS 重握手时间,从而 缩短优雅窗口
  2. 当集群使用 混合云架构(线下 IDC + 华为 CCE),专线抖动 导致 Registry 拉镜像超时,如何提前做 P2P 预热(如 Dragonfly)保证扩容 冷启动 <10 s
  3. 金融场景 中,监管要求 “连接可追踪”,你是否考虑把 eBPF 探针 打进容器,实时导出 TCP 关闭事件Kafka,再对接 审计系统