暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

为什么我的Pod一直是Terminating状态?怎么一键清理与某个应用相关的残留资源

55


当我们执行了kubectl delete pod...
,但是Pod一直卡在Terminating状态,删不掉。遇到这种情况,我们应该如何系统地排查和解决呢。


Pod删不掉的常见原因

1.Finalizer阻塞

首先什么是Finalizer?

Finalizer是K8s中的一种“延迟删除机制”,它允许控制器(比如Operator)在对象被删除之前执行清理逻辑,换句话说,在资源被真正删除之前,K8s必须先等待控制器执行一段清理逻辑。

我们通过执行`kubectl get podo yaml |grep finalizer 应该会看到Pod中finalizers相关的信息:

  finalizers:
  - xxxx/finalizer

资源删除时的完成过程如下:

a.用户执行kubectl delete pod

b.K8s不会立即删除对象,而是先检查对象是否有finalilzers
,如果有,则通知相关的Controller执行相应的删除逻辑。
c.Controller执行清理动作,完成后,从对象中移除finalizer信息:

metadata:
  finalizers: []

d. Kubernetes 看到 finalizers
 为空,才真正从 etcd 删除该对象。

Finalizer引发的”删除卡死问题“

假设Controller异常或被删除,这时清除逻辑没人执行,那资源的finalizer
信息就会永远留在对象中,就会导致K8s一直等待,我们就会看到对象处于”Termiinating“状态,而无法继续的现象。

如何解决?

我们可以手动移除对象的Finalizer,再执行删除逻辑。

kubectl patch pod <pod-name> -p '{"metadata":{"finalizers":null}}' --type=merge
kubectl delete pod <pod-name> --force --grace-period=0

--grace-peroid=0
: 默认K8s会发送SIGTERM给Pod内的容器,等待grace-period秒让容器完成清理和退出。那么0就表示立即杀掉容器,不等待。

2.Node节点通信异常

Pod 所在节点已经宕机 NotReady 无法访问 apiserver。

我们可以通过如下命令查看Node信息:

kubectl get pod <pod-name> -n polardbx-operator-system -o wide
kubectl get nodes

重点看:

  • NODE
     → 是否是NONE。
  • 查看node的状态是否是NotReady 或已下线。

如何解决

kubectl delete pod <pod> --grace-period=0 --force

查看Pod的事件日志

我们可以通过查看Pod的日志,查看它的EVENT事件,查看是否包含有效消息。

kubectl describe pod <pod-name> -n polardbx-operator-system

如果Pod删除后一直重建如何解决?

如果我们想彻底删除Pod,并且防止它不断重建。甚至进一步扩展,想删除某个应用关联的所有资源,应该怎么去做?

Pod删除后重建,根本原因是Pod是由ReplicaSet/StatefulSet/Deployment/Operator 控制,我们需要删除上层控制器或缩容。

这种情况,我们可以采用如下操作去处理:

1.首先查找 Pod 的 ownerReferences(确定它属于哪个控制器)
2.缩容控制器至 0(或直接删除控制器)
3.手动强制删除卡死 Pod(如移除 Finalizer)
4.最后验证 Pod 不再重建

一键清理脚本

我们可以写一个一键清理以某个应用为前缀的K8s残留资源的脚本:

#!/bin/bash
set -e

NS="polardbx-operator-system"
PREFIXES=("pxc-product-gphz""heartbeat-pxc-product")

echo"🔍 当前命名空间: $NS"
echo"⚙️  开始清理所有 PolarDBX 相关 Pod..."
read -p "是否继续执行?(y/N): " confirm
"$confirm" != "y" ] && echo"已取消操作。" && exit 0

# 缩容或删除 Deployment StatefulSet
echo"📉 缩容或删除控制器 ..."
for prefix in"${PREFIXES[@]}"do
# Deployment
for deploy in $(kubectl -n $NS get deploy -o name | grep $prefix || true); do
    echo"  → 缩容 Deployment $deploy 至 0"
    kubectl -n $NS scale $deploy --replicas=0 || true
done

# StatefulSet
for sts in $(kubectl -n $NS get sts -o name | grep $prefix || true); do
    echo"  → 缩容 StatefulSet $sts 至 0"
    kubectl -n $NS scale $sts --replicas=0 || true
done

# ReplicaSet
for rs in $(kubectl -n $NS get rs -o name | grep $prefix || true); do
    echo"  → 删除 ReplicaSet $rs"
    kubectl -n $NS delete $rs --force --grace-period=0 || true
done
done

# 删除残留 Pod
echo"🧹 强制删除残留 Pod ..."
for prefix in"${PREFIXES[@]}"do
for pod in $(kubectl -n $NS get pod -o name | grep $prefix || true); do
    echo"  → 强删 $pod"
    if kubectl -n $NS get $pod >/dev/null 2>&1; then
      kubectl -n $NS patch $pod -p '{"metadata":{"finalizers":null}}' --type=merge || true
      kubectl -n $NS delete $pod --force --grace-period=0
    fi
done
done

# 剩余资源检查
echo"🧾 剩余资源检查:"
kubectl -n $NS get deploy,sts,rs,pod | grep -E "$(IFS='|'; echo "${PREFIXES[*]}")" || echo"✅ 所有 PolarDBX 相关资源已清理完成。"

echo"🎉 清理完毕。"


脚本的核心逻辑如下:
1.确认操作
2.缩容Deployment/StatefulSet、删除ReplicaSet
3.强制删除Pod(patch finalizers、force delete)
4.清理验证

这个脚本可以用来清理 PolarDB-X 某个集群残留的 Kubernetes 资源。 用于一些可能出现的情况:

  • 删除 PolarDBXCluster 失败;
  • Pod 卡在 Terminating
  • Operator 清理不完全;
  • Pod 没有绑定 Node(Zombie Pod)。

脚本能强制移除这些卡住的资源,让环境恢复干净状态,便于重新部署或调试。

推荐阅读:

Sealos x Kubernetes:让集群部署更简单

谈谈对数据库K8S Operator的理解

如何理解K8S中的CRD

如何查看k8s Pod的CPU&内存限制—从Pod Spec到宿主机cgroup

通过k8s快速部署一个PolarDB-X分布式集群

Prometheus 在 Kubernetes 中的 Target 管理实践

#运维 #K8s 

✪ ~本文是小编的第181篇文章,目标是累计输出 1000 篇优质内容,也始终提醒自己:保持学习、保持记录、保持分享,希望以上内容能给你带来一点帮助~


 or  


👇👇👇 

文章转载自PostgreSQL运维技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论