k8s pod重启顺序说明

发布于:2025-04-04 ⋅ 阅读:(13) ⋅ 点赞:(0)

在 Kubernetes 中,Pod 的重启顺序由 控制器类型 和 Pod 管理策略 共同决定。以下是不同场景下的详细规则和底层逻辑:

一、Pod 重启的触发场景

场景类型 触发原因 控制方
容器崩溃重启 容器进程退出(如异常、OOM) kubelet(节点)
节点故障重启 节点宕机或不可达 控制器
手动删除重启 kubectl delete pod 控制器
滚动更新重启 镜像/配置更新、kubectl rollout 控制器
资源驱逐重启 节点资源不足(如内存、磁盘) kubelet

二、不同控制器的 Pod 重启顺序规则

1. 裸 Pod(无控制器管理)

无重启逻辑:直接删除后不会自动重建

特殊场景

  • 如果配置了 restartPolicy: Always,kubelet 会原地重启容器(非 Pod 级别重启,而是container级别重启)

2. Deployment

默认行为

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 25%
    maxSurge: 25%

滚动更新顺序

  • 新 Pod 启动:并行创建新版本 Pod(数量由 maxSurge 控制)

  • 旧 Pod 终止:随机选择删除旧 Pod

  • 关键特征:无强顺序保证,注重可用性

  • 故障恢复顺序:完全并行创建,无顺序约束

3. StatefulSet

参考:StatefulSet 基础 | Kubernetes (K8s) 中文

默认策略 (podManagementPolicy: OrderedReady):

  • 创建顺序:web-0 → web-1 → web-2
  • 删除顺序:web-2 → web-1 → web-0
  • 故障恢复:严格按索引顺序重建

并行模式 (podManagementPolicy: Parallel):

  • 所有 Pod 并行操作

  • 示例:同时删除 web-0、web-1、web-2

4. DaemonSet

重启逻辑

  • 每个节点始终运行 1 个 Pod

  • 节点故障时:当节点恢复后,原地重启 Pod

  • 滚动更新:默认随机顺序,可通过 updateStrategy 配置

5. Job/CronJob

重启策略

  • restartPolicy: Never/OnFailure

  • Pod 完全终止后才会创建新实例

  • 严格串行:前一个 Pod 成功结束后才会启动下一个(completions: N 时)

三、底层机制解析

1. 控制器协调循环
// 伪代码示例:Deployment 控制器逻辑
for {
    currentPods := listPods(deploymentLabel)
    desiredPods := calculateDesiredReplicas()

    // 计算需要创建/删除的 Pod
    diff := desiredPods - len(currentPods)
    if diff > 0 {
        createPodsParallel(diff) // 并行创建
    } else if diff < 0 {
        deletePodsRandomly(-diff) // 随机删除
    }
}
2. 关键 API 字段控制
apiVersion: apps/v1
kind: StatefulSet
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 2 # 仅更新索引 ≥2 的 Pod(web-2, web-3...)
  podManagementPolicy: OrderedReady # 或 Parallel

四、实战验证方法

1. 观察滚动更新过程
# 终端1:实时监控 Pod
kubectl get pods -l app=nginx -w

# 终端2:触发更新
kubectl set image deployment/nginx nginx=nginx:1.25
2. 模拟节点故障
# 随机选择一个节点
node=$(kubectl get nodes -o jsonpath='{.items[?(@.status.conditions[?(@.type=="Ready")].status=="True")].metadata.name}' | tr ' ' '\n' | shuf -n 1)

# 封锁节点
kubectl cordon $node

# 删除该节点上的 Pod
kubectl delete pods --field-selector spec.nodeName=$node

五、最佳实践建议

有状态服务

  • 使用 StatefulSet + OrderedReady 策略

  • 配合 ReadinessProbe 确保顺序依赖

readinessProbe:
  exec:
    command: ["/bin/sh", "-c", "check_dependency web-$(hostname | cut -d'-' -f2)"]

无状态服务

affinity:
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
        matchExpressions:
        - key: app
          operator: In
          values: [nginx]
      topologyKey: kubernetes.io/hostname
  • 使用 Deployment + MaxSurge=30% 加速恢复

  • 配置反亲和性避免集中重启

关键监控指标

# Pod 重启次数
kube_pod_container_status_restarts_total{namespace="production"}

# 滚动更新进度
kube_deployment_status_replicas_updated{deployment="nginx"}

六、特殊场景处理

场景:需要自定义重启顺序

解决方案

  1. 使用 Operator 自定义控制器逻辑

  2. 通过 Finalizers 控制删除顺序

    // 在控制器中设置删除顺序
    func (c *Controller) handlePodDeletion(pod *v1.Pod) {
        if pod.DeletionTimestamp == nil {
            return
        }
        // 检查前置 Pod 是否已删除
        if !isPredecessorDeleted(pod) {
            c.requeuePod(pod) // 重新入队等待
        }
    }
场景:需要零停机重启

解决方案

# Deployment 配置
strategy:
  rollingUpdate:
    maxSurge: 100%  # 先启动所有新 Pod
    maxUnavailable: 0%

网站公告

今日签到

点亮在社区的每一天
去签到