概述
删除pod或者namesapce时,有可能一直删不掉,查看状态处于Terminating,下面总结一下可能的几种原因。
pod
磁盘满了
如果容器运行时 (docker或containerd等) 的数据目录所在磁盘被满了,运行时就无法正常无法创建和销毁容器,kubelet 调用运行时去删除容器时就没有反应,看 event 会有如下输出:
Normal Killing 39s (x735 over 15h) kubelet, 10.96.81.52 Killing container with id docker://apigateway:Need to kill Pod
解决
定期清理磁盘空间
pod的目录或文件有“i”属性
如果容器的镜像本身或者容器启动后写入的文件存在 “i” 文件属性,此文件就无法被修改删除,而删除 Pod 时会清理容器目录,但里面包含有不可删除的文件,就一直删不了,Pod 状态也将一直保持 Terminating,kubelet 报错:
Jul 6 15:00:00 VM_0_7_centos kubelet[14109]: E0706 15:00:00 12345 remote_runtime.go:250] RemoveContainer "xxx" from runtime service failed: rpc error: code = Unknown desc = failed to remove container "xxx": Error response from daemon: container xxx: driver "overlay2" failed to remove root filesystem: remove /data/docker/overlay2/abcd/diff/usr/bin/bash: operation not permitted
解决
复制 kubelet 日志报错提示的文件路径,然后执行
chattr -i <file>
存在 Finalizers
Finalizers的介绍:https://wghdr.top/archives/1539
解决
kubectl edit 手动编辑资源定义,删掉 finalizers。
mount 的目录被其它进程占用
查看docker日志有:device or resource busy的报错。
解决
查看是被哪个进程占用:
grep app /proc/*/mountinfo
然后再根据pid,来查看为什么占用。
dockerd 与 containerd 的状态不同步
判断同步同步的方法:
- 查询container id
k get po -o wide k describe po npd-node-problem-detector-t7wd6 | grep -i container # 或者 crictl ps | grep npd-node-problem-detector
- 查询containerd中的状态
ctr -n k8s.io task ls | grep fb7d9d041ae75
- 查询dockerd中的状态
docker ps
如果磁盘爆满过,可能会发生状态不同步。
解决
临时恢复: 执行 docker container prune 或重启 dockerd
永久解决:直接使用 containerd。
附:强制删除pod命令
kubectl delete pod xxx --force --grace-period=0
namespace
Namespace 上存在 Finalizers 且对应软件已卸载
删除 ns 后,一直卡在 Terminating 状态。通常是存在 finalizers,使用下面的命令可以看到是否有 finalizers:
kubectl get ns xxx -o yaml
解决
kubectl edit ns xx 删除 spec.finalizers
cat <<EOF | curl -X PUT \
localhost:8080/api/v1/namespaces/test/finalize \
-H "Content-Type: application/json" \
--data-binary @-
{
"kind": "Namespace",
"apiVersion": "v1",
"metadata": {
"name": "test"
},
"spec": {
"finalizers": null
}
}
EOF
Namespace 中残留的资源存在 Finalizers 且相应软件已卸载
可以在status.conditions中观察到SomeResourcesRemain 和 SomeFinalizersRemain。
kubectl get ns xxx -o yaml
...
status:
conditions:
- message: 'Some resources are remaining: xxx has 1 resource instances'
lastTransitionTime: "2022-06-15T07:11:11Z"
reason: SomeResourcesRemain
status: "True"
type: NamespaceContentRemaining
- message: 'Some content in the namespace has finalizers remaining: xxx/finalizer
in 1 resource instances'
lastTransitionTime: "2022-06-15T07:11:11Z"
reason: SomeFinalizersRemain
status: "True"
type: NamespaceFinalizersRemaining
phase: Terminating
解决
由于应用已经卸载,残留资源在等待应用来删除,所以无法删除,需要手动删除ns下的finalizer。
kubectl -n xxx edit xxxx
注意
如果ns被删除了,但是仍然有残留的孤儿对象,可以再创建同名ns,再手动删除对象。
apiservice存在但应用已删除
kubectl get apiservice
...
v1beta1.metrics.k8s.io monitoring/prometheus-adapter False (ServiceNotFound) 75d
...
解决
删除对应的apiservice