如何配置Kubernetes实现Worker节点宕机时Pod的自动故障转移——解决Pod持续处于Terminating状态无法重建问题
我们运行一套由kubespray部署的Kubernetes集群,近期因硬件故障出现Worker节点宕机的情况。经排查发现,运行在故障节点上的Pod会无限期处于Terminating状态,即使经过数小时也不会自动在健康节点上重新部署,导致整个应用服务异常,用户长时间受影响。现需咨询如何配置Kubernetes,使其在这类节点故障场景下自动执行Pod的故障转移?
以下是使用的StatefulSet清单:
apiVersion: apps/v1 kind: StatefulSet metadata: namespace: project-stock name: ps-ra spec: selector: matchLabels: infrastructure: ps application: report-api environment: staging serviceName: hl-ps-report-api replicas: 1 template: metadata: namespace: project-stock labels: infrastructure: ps application: report-api environment: staging spec: terminationGracePeriodSeconds: 10 containers: - name: ps-report-api image: localhost:5000/ps/nodejs-chrome-application:latest ports: - containerPort: 3000 protocol: TCP name: nodejs-rest-api volumeMounts: resources: limits: cpu: 1000m memory: 8192Mi requests: cpu: 333m memory: 8192Mi livenessProbe: httpGet: path: /health/ port: 3000 initialDelaySeconds: 180 periodSeconds: 10 failureThreshold: 12 timeoutSeconds: 10
针对你遇到的StatefulSet Pod在节点宕机后卡Terminating、无法自动转移的问题,核心是让Kubernetes快速识别节点故障并触发Pod的驱逐重建,下面是具体的配置调整步骤,贴合你的场景:
1. 调整kube-controller-manager的节点故障检测与驱逐参数
Kubernetes的kube-controller-manager负责监控节点状态和触发Pod驱逐,kubespray部署的集群中,这个组件的配置通常在/etc/kubernetes/manifests/kube-controller-manager.yaml文件里,需要修改两个关键参数:
--node-status-update-frequency: 控制控制器获取节点状态的间隔,默认10秒,集群规模不大的话可以缩短到5秒,确保快速发现节点异常--pod-eviction-timeout: 节点被标记为NotReady/Unreachable后,等待多久开始驱逐其上的Pod,默认5分钟,建议缩短到1-2分钟,避免长时间等待
修改后的配置片段示例:
containers: - command: - kube-controller-manager - --node-status-update-frequency=5s - --pod-eviction-timeout=1m0s # 保留其他原有配置参数...
修改后Kubelet会自动重启静态Pod形式的kube-controller-manager,无需手动重启。
2. 配置节点自动打污点与Pod容忍度(推荐)
Kubernetes 1.20+默认支持自动给故障节点打污点,配合Pod的容忍度能更灵活控制Pod转移:
- 确保
kube-controller-manager开启了--enable-taint-manager(默认已开启),并缩短unreachable-taint-timeout参数:
- --unreachable-taint-timeout=1m0s
- 在你的StatefulSet Pod模板中添加容忍度,允许控制器在节点故障时驱逐Pod:
在template.spec下新增:
tolerations: - key: "node.kubernetes.io/unreachable" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300 - key: "node.kubernetes.io/not-ready" operator: "Exists" effect: "NoExecute" tolerationSeconds: 300
这里的tolerationSeconds设置为300秒,和你调整的pod-eviction-timeout匹配即可。
3. 针对StatefulSet的额外优化
因为StatefulSet有特殊的Pod管理逻辑,需要注意两点:
- 确认
podManagementPolicy为OrderedReady(默认值):这个模式下StatefulSet会等旧Pod被确认删除后再创建新Pod,保证有状态服务的一致性;如果你的场景不需要严格顺序,可临时改为Parallel加速转移,但要评估业务是否允许。 - 检查存储可迁移性:如果后续给Pod添加了存储,要确保使用网络存储(而非本地存储),否则绑定到故障节点的PersistentVolume无法被新Pod挂载,会导致启动失败。目前你的清单中
volumeMounts为空,暂时无需担心。
4. 验证配置生效
修改完成后,模拟节点故障(比如断开节点网络),观察以下指标确认效果:
- 节点是否在预期时间内被标记为
NotReady/Unreachable - 故障节点上的Pod是否在设置的
pod-eviction-timeout时间后开始被驱逐 - 新Pod是否在健康节点上正常启动
内容的提问来源于stack exchange,提问作者roman

