terminating的pod、pv、pvc无法删除解决方法
# 一、pod删除
- 当删除
namespace或pod等一些Kubernetes资源时,有时资源状态会卡在terminating,很长时间无法删除,甚至有时增加--force flag(强制删除)之后还是无法正常删除.这时就需要edit该资源,将字段finalizers设置为null,之后Kubernetes资源就正常删除了. - 当删除
pod时有时会卡住,pod状态变为terminating,无法删除pod
强制删除
kubectl delete pod pod_name -n namespace_name --force --grace-period=0
如果强制删除还不行,设置finalizers为空
- 如果一个容器已经在运行,这时需要对一些容器属性进行修改,又不想删除容器,或不方便通过
replace的方式进行更新.kubernetes还提供了一种在容器运行时,直接对容器进行修改的方式,就是patch命令.
kubectl patch pod pod_name -n namespace_name -p '{"metadata":{"finalizers":null}}'
# 从ETCD中删除源数据
- 不推荐
# 删除default namespace下的pod名为pod-to-be-deleted-0
ETCDCTL_API=3 etcdctl del /registry/pods/default/pod-to-be-deleted-0
# 删除需要删除的NAMESPACE
etcdctl del /registry/namespaces/NAMESPACENAME</pre>
2
3
4
5
# 二、删除pv/pvc
# 强制删除
kubectl delete pv pv_name --force --grace-period=0
kubectl delete pvc pvc_name -n namespace_name --force --grace-period=0
# finalizers
kubectl patch pv pv-nfs-gysl -p '{"metadata":{"finalizers":null}}'
kubectl patch pvc minio-pvc -p '{"metadata":{"finalizers": []}}' --type=merge -n minio
2
3
4
5
6
7
8
# 三、k8s删除流程
基本的delete命令状态图

尽管此操作很简单,但其他因素可能会干扰删除,包括finalizers和owner references.
K8s中对象删除基本流程如下:
- 1.客户端提交删除请求到
API Server(可选传递GracePeriodSeconds参数) - 2.
API Server做Graceful Deletion检查(若对象实现了RESTGracefulDeleteStrategy接口,会调用对应的实现并返回是否需要进行Graceful删除) - 3.
API Server检查Finalizers并结合是否需要进行graceful删除,来决定是否立即删除对象(若对象需要进行graceful删除,更新metadata.DeletionGracePeriodSecond和metadata.DeletionTimestamp字段,不从存储中删除对象;若对象不需要进行Graceful删除时:metadata.Finalizers为空,直接删除.metadata.Finalizers不为空,不删除,只更新metadata.DeletionTimestamp.
# finalizers介绍
Finalizers字段属于Kubernetes GC垃圾收集器,是一种删除拦截机制,能够让控制器实现异步的删除前(Pre-delete)回调.其存在于任何一个资源对象的Meta中,在k8s源码中声明为[]string,该Slice的内容为需要执行的拦截器名称.
常见用途:
- 1.控制器在对象刚创建时,在
metadata.finalizers写入一个自定义字符串 - 2.
APIServer在metadata.finalizers数组不为空时,不会删除对象.此逻辑是硬性,对所有对象生效. - 3.当有客户端删除对象时,控制器可以发现对象出于删除状态,然后执行相应的
pre-delete逻辑.执行完成后,将之前写入的自定义字符串移除. - 4.当所有控制器都将各自写入到
metadata.finalizers的字符串移除后.API Server就自动将对象删除.
**注:**若对象同时实现了graceful删除策略,删除请求需要满足GracefulPeriodSeconds = 0条件
# Graceful Deletion
APIServer在处理Pod删除请求时,会根据pod的pod.Spec.TerminationGracePeriodSeconds和deleteOptions.GracefulPeriodSeconds综合判断,是否进行Graceful删除.若是,并判断最终的GracefulPeriodSeconds该设置为多少.
- 1.当删除请求选项中有设置
GracefulPeriodSeconds,以选项中为准.若没有,使用pod.Spec.TerminationGracePeriodSeconds.若pod.Spec.TerminationGracePeriodSeconds也没有设置,使用默认值0. - 2.当
Pod没有调度,或者已经结束(无论成功还是失败).GracePeriodSeconds都重置为0.
GracePeriodSeconds为0表示不进行优雅删除.非0表示进行优雅删除.Pod的默认优雅删除时间为30s,在对象创建时配置在pod.Spec.TerminationGracePeriodSeconds字段.
优雅删除的目的是给予Kubelet一定时间对Pod实行优雅退出.在用户对Pod执行Delete操作时,Pod对象不会立即从API Server删除,而只是进入Termination阶段.Kubelet会对运行中的Pod的容器发送TERM信号,通知其退出.并执行用户配置的preStop hooks逻辑.当优雅时间过了之后,再开始使用KILL信号尝试强制杀容器.
当kubelet将Pod清理干净后,就会使用GracefulPeriodSeconds==0的参数执行删除操作.
因为Pod实现优雅删除目的是为了给予Kubelet时间做资源清理操作,所以这也是为什么在设置GracePeriodSeconds阶段,若Pod没有被调度或者已经退出,也就可以直接允许立即删除(GracePeriodSeconds = 0).
注:
- 理解该流程可以结合
Kubernetes官网的Pod Termination说明:https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods - 对象第一次执行优雅删除操作时,会将当时
GracefulPeriodSeconds配置在metadata.DeletionGracefulPeriodSeconds字段. Deletion操作在API Server是不可回退的操作.metadata.DeletionTimestamp设置后不可更改,metadata.DeletionGracefulPeriodSeconds只能减小,不能增加.
# 对象无法删除的原因
了解以上机制后,对象无法删除无外乎以下两个原因:
- 对象存在
finalizers,关联的控制器故障未能执行或执行finalizer函数卡住- 比如
namespace控制器无法删除完空间内所有的对象,特别是在使用aggregated apiserver时,第三方apiserver服务故障导致无法删除其对象.此时,需要会恢复第三方apiserver服务或移除该apiserver的聚合,具体选择哪种方案需根据实际情况而定. - 集群内安装的控制器给一些对象增加了自定义
finalizers,未删除完fianlizers就下线了该控制器,导致这些fianlizers没有控制器来移除他们.此时,需要恢复该控制器会手动移除finalizers,具体选择哪种方案根据实际情况而定.
- 比如
- 对象需要优雅删除,但执行者不能完成删除.比如
Pod因为kubelet无法下线节点上node容器、存储卷而无法删除.比较常见有以下原因:kubelet无法通过container runtime杀死进程.比如进程进入D(Uninterruptible)状态,container runtime或操作内核遇到bug等.对于进程进入D状态,若能恢复照成D的故障,比如恢复关联的外设访问等,能解决问题.若不能,或者是因为后者内核bug,一般并不能走正常流程让kubelet杀死进程.一般需要重启操作系统才能解决.kubelet进程停止或者node失去联系. 该情况下,并没有kubelet运行或者运行中的kubelet与apiserver已经断开,无法收到pod需要删除下线的消息.所以,没有执行者来进行优雅删除.该情况下,需要恢复节点以及kubelet的运行即可.
两种机制都有强制跳过的方案:
- 删除
finalizers,让关联的逻辑不需要执行 kubelet delete --force --grace-period 0直接删除
- 01
- kubernetes部署minio对象存储01-18
- 02
- Jenkins-Argocd CICD-下01-17
- 03
- Jenkins-Argocd CICD Rollouts金丝雀发布优化01-17