PHP,DDD,CQRS,Event Sourcing,Kubernetes,Docker,Golang

0%

Pod长时间处于Terminating状态的问题

问题描述

当一个Pod被执行删除操作后,却长时间的处于Terminating状态,发生这样的情况可能是因为:

  • Pod有一个与其关联的finalizer,这个finalizer的任务没有完成。
  • Pod对中断信号没有响应

当我们执行kubectl get pods命令时,你将会看到这样的信息:

1
2
NAME                     READY     STATUS             RESTARTS   AGE
nginx-7ef9efa7cd-qasd2 1/1 Terminating 0 1h

排查和处理步骤

1. 收集一些信息

1
kubectl get pod -n [NAMESPACE] -p [POD_NAME] -o yaml

2. 检查finalizer

首先我们需要先查看pod有没有关联的finalizer,如果有关联的finalizer,那么很可能就是finalizer的问题。

获取并查看pod的配置信息:

1
kubectl get pod -n [NAMESPACE] -p [POD_NAME] -o yaml > /tmp.txt

然后在/tmp.txt内容中查找metadata配置块下是否有finalizer字段,如果有,则采用解决方案A

3. 检查node的状态

也可能是pod所在的node节点因为一些原因而导致的问题。

如果你从/tmp.txt内容中发现某个node节点上的所有pod都处于Terminating状态,那么就是该node节点的问题。

4. 尝试删除pod

pod没有被终止可能是进程对信号没有响应,具体的原因需要结合具体的应用和上下文来看。通常可能包括:

  • 在执行的用户空间代码中存在对中断信号无响应tight loop循环

  • 在应用运行时(runtime)的一个维护过程(例如垃圾回收)

在这种情况下,采用解决方案B可能行的通

5. 重启kubelet

如果其他方法都不起作用,则尝试在pod运行的node节点上重启kubelet。见解决方案C

解决方案

方案A:移除finalizer

从对应的pod上移除其所有的finalizer:

1
kubectl patch pod [POD_NAME] -p '{"metadata":{"finalizers":null}}'

方案B:强行删除Pod

请注意,这是一个变通的方法,而不是一个有效的解决方案,目前网上大多数文章都优先推荐了该方法。在执行该方法时应该谨慎小心,注意确保不会产生额外的其他问题。关于强行删除StatefulSet的Pod的信息请见这里

1
kubectl delete pod --grace-period=0 --force --namespace [NAMESPACE] [POD_NAME]

方案C:重启kubelet

如果你可以通过ssh连接登录到node节点,则可以将节点上的kubelet进程重启,如果你没有这权限,那么就需要相关有权限的人来操作。

在你重启kubelet之前,最好检查一下kubelet日志来确认一下是否有异常问题。

验证结果

如果当执行kubectl get pods再也没显示刚才处于Terminating的Pod,则说明该问题处理完成了。

1
2
$ kubectl get pod -n mynamespace -p nginx-7ef9efa7cd-qasd2
NAME READY STATUS RESTARTS AGE

进一步处理和探究

1. 检查确认finalizer的工作任务是否需要被执行完成才会好

这需要看finalizer都做些哪些工作任务来判断,通常finalizer的任务未完成可能是因为与Volume有关的任务。

2. 确定根本原因

这也是需要看finalizer都做些什么任务来判断的,并且还需要一些特定上下文的信息。如果你有访问node节点的权限,检查一下kubelet的日志,控制器会在里面记录一些有用的信息供你排查。

相关参考信息