Kubernetes集群零停机滚动更新SRE实践:从PDB策略到灰度发布完整手册

滚动更新的停机风险根源

Kubernetes的Deployment控制器默认采用RollingUpdate策略更新Pod,配置项maxSurgemaxUnavailable控制更新节奏。但默认值(25%/25%)在多种场景下仍可能引发请求失败——新Pod未就绪就被投入流量、旧Pod被过早终止、就绪探针配置不当导致假阳性。SRE团队需要从PDB、就绪探针、流量切换三个层面加固发布流程。

PDB防护:保护最小可用副本数

PodDisruptionBudget(PDB)是防止滚动更新期间过多Pod同时被驱逐的关键策略。生产环境必须为每个关键服务配置PDB:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: api-server-pdb
spec:
  minAvailable: 2    # 或使用 maxUnavailable: 1
  selector:
    matchLabels:
      app: api-server

PDB约束的是”自愿中断”(Voluntary Disruption),包括滚动更新、节点维护等主动操作。当可用Pod数会跌破minAvailable时,更新操作会被暂停等待。

PDB配置要点:

  • minAvailable设为绝对数值而非百分比,在副本数少的服务上更可控
  • 对于单副本服务,PDB无法完全保护——应将副本数提升到至少2
  • PDB不会阻止非自愿中断(节点崩溃),仅约束主动操作

就绪探针精确配置:防止流量打到未就绪Pod

滚动更新期间最常见的问题是新Pod尚未完成初始化就被Service端点加入,导致5xx错误。就绪探针是第一道防线:

readinessProbe:
  httpGet:
    path: /health/ready
    port: 8080
  initialDelaySeconds: 5      # 容器启动后首次探测延迟
  periodSeconds: 3             # 探测间隔
  failureThreshold: 3          # 连续失败次数后标记未就绪
  successThreshold: 2          # 连续成功次数后标记就绪
  timeoutSeconds: 2            # 单次探测超时

livenessProbe:
  httpGet:
    path: /health/live
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10
  failureThreshold: 5
  timeoutSeconds: 5

startupProbe:
  httpGet:
    path: /health/startup
    port: 8080
  initialDelaySeconds: 0
  periodSeconds: 2
  failureThreshold: 30         # 最多等待60秒启动

三层探针的分工:

  • startupProbe:应用启动阶段专用,启动成功前liveness/readiness不生效
  • readinessProbe:控制Service端点,失败时从后端池移除
  • livenessProbe:控制Pod生命周期,失败时容器重启

常见配置失误:readinessProbe的successThreshold设为1(默认值),但应用预热期间偶尔返回200后又短暂不可用。设为2-3可确保应用真正稳定后再接收流量。

preStop钩子与优雅关闭

Pod终止时,Kubernetes发送SIGTERM,等待terminationGracePeriodSeconds(默认30s)后SIGKILL。但问题是SIGTERM到达后,Pod可能在Service端点移除之前仍在接收新请求。preStop钩子可以插入一个等待期:

spec:
  terminationGracePeriodSeconds: 60
  containers:
  - name: api-server
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sleep 15"]
    # 信号流程:
    # 1. K8s标记Pod为Terminating
    # 2. preStop sleep 15s (等待Service端点同步移除)
    # 3. 发送SIGTERM
    # 4. 应用优雅关闭(完成存量请求)
    # 5. 等待剩余时间后SIGKILL

15秒的sleep给iptables/IPVS规则同步留出时间。如果你的集群规模较大(iptables模式下上万条规则),可能需要20-25秒。

灰度发布:Canary + Argo Rollouts

对于高风险变更,简单的RollingUpdate不够用。Argo Rollouts提供了精细化的灰度发布能力:

apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: api-server
spec:
  replicas: 10
  strategy:
    canary:
      steps:
      - setWeight: 5           # 5%流量到新版本
      - pause: {duration: 5m}  # 观察5分钟
      - setWeight: 20
      - pause: {duration: 5m}
      - setWeight: 50
      - pause: {duration: 10m}
      # 自动分析指标决定是否继续
      analysis:
        templates:
        - templateName: error-rate-check
        args:
        - name: service-name
          value: api-server-canary

Analysis Template定义了自动化指标检查:

apiVersion: argoproj.io/v1alpha1
kind: AnalysisTemplate
metadata:
  name: error-rate-check
spec:
  metrics:
  - name: error-rate
    interval: 60s
    count: 5
    provider:
      prometheus:
        query: |
          sum(rate(http_requests_total{status=~"5..",service="{{args.service-name}}"}[1m]))
          /
          sum(rate(http_requests_total{service="{{args.service-name}}"}[1m]))
    successCondition: result[0] < 0.01  # 错误率低于1%

回滚策略与故障应急

发布异常时的回滚操作:

# Argo Rollouts回滚
kubectl argo rollouts undo api-server

# 原生Deployment回滚
kubectl rollout undo deployment/api-server

# 回滚到指定版本
kubectl rollout undo deployment/api-server --to-revision=3

# 紧急场景:直接缩容新版本
kubectl scale deployment api-server --replicas=0 --selector=version=canary

应急响应流程:

  • 告警触发(5xx率突增/P99延迟翻倍)→ 自动暂停灰度发布
  • SRE确认异常 → 30秒内执行回滚
  • 回滚后验证 → 恢复正常流量
  • 事后复盘 → 补充Analysis Template指标

零停机滚动更新不是一个配置项,而是PDB保护、探针精确配置、preStop优雅关闭、灰度发布和自动化指标分析的组合方案。每个环节的遗漏都可能成为线上事故的根因。SRE团队应将这套流程固化为发布检查清单,任何部署必须逐项确认后再执行。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/kubernetes-ji-qun-ling-ting-ji-gun-dong-geng-xin-sre-shi/

(0)
小编小编
上一篇 3小时前
下一篇 3小时前

相关推荐