k8s pod重启顺序说明

在 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%
相关推荐
回忆是昨天里的海5 小时前
k8s部署容器化应用-tomcat
云原生·容器·kubernetes·1024程序员节
Shannon Law6 小时前
Docker连接超时的解决方法
docker·容器
helloworddm10 小时前
Orleans + Kubernetes + Istio 服务网格集成深度解析
容器·kubernetes·istio
小彭律师11 小时前
Docker/K8s部署MySQL的创新实践与优化技巧大纲
mysql·docker·kubernetes
lastHertz11 小时前
Docker 占用导致 C 盘空间不足的排查与解决
运维·docker·容器
专家大圣11 小时前
Docker+Redis监控新方案:cpolar让远程管理“零配置”
网络·redis·docker·容器·内网穿透
旦沐已成舟12 小时前
K8S搭建轻量级日志收集系统(EFK)
elk·kubernetes
chen_note14 小时前
Dockerfile及其部署镜像步骤
docker·容器·镜像·dockerfile
thinktik15 小时前
AWS EKS安装S3 CSI插件[AWS 海外区]
后端·kubernetes·aws
Jy_062215 小时前
K8s中,deployment 是如何从 yaml 文件最终部署成功 pod 的
云原生·容器·kubernetes