前言
这是笔者发的一个stackoverflow,可以看采纳的答案,小哥讲的很详细,笔者也会在下面记录。
问题
Kubernetes 版本和Java Cient:
Kubernetes version: Kubernetes v1.27.3
java client maven:
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>18.0.1</version>
</dependency>
测试获取指定节点下面Pod信息列表出现了问题-------关闭此节点的kubelet后,pod开始重新到可用节点,此节点下面pod进入Terminating状态,但是后端代码获取到节点的状态居然是Running?
kubectl get po -n my-namespace -o wide
# 调度后新pod
nginx1-74499f547c-gbdzf 1/1 Running 0 1m 10.244.0.55 kylin-master <none> <none>
# 旧pod,因为kubelet关闭,无法删除该pod
# 在kubelet可用之前,会一直处于Terminating状态
nginx1-74499f547c-xndkm 1/1 Terminating 0 8h 10.244.2.24 kylin-worker02 <none> <none>
CoreV1Api coreV1Api = new CoreV1Api();
V1PodList v1PodList;
try{
v1PodList = coreV1Api.listNamespacedPod(tenxOpenApiConfig.getTeamSpace(), null, null, null, info, null, null, null, null, null, null);
for (V1Pod item : v1PodList.getItems()) {
// .....
}
}
// ......
debug一看, 什么,状态居然是Running
于是寻找解决办法,究其原因,还得看文档。
解决方案
首先, Terminating
不是Kubernetes Pods
和Containers
的状态,kubectl命令的展示状态基于Pod对象中的多个字段(而不仅仅是Pod.status.phase
,如Pod.metadata.deleteTimestamp
)。
当一个pod由于一些原因(例如节点故障或手动删除)被删除时,并不会立即删除,因为这样可能会破坏内部运行的应用程序,因此kubernetes首先向pod内的容器发出TERM
(又名SIGTERM
)信号,给它一些时间来让其正常终止。在一段时间后(在pod.spec.terminationGracePeriodSeconds
中定义,默认为30),如果容器尚未终止,则会直接杀死。在这期间,容器实际上正在运行,因此Pod.status.phase
显示pod状态是Running
。然而,当pod被删除时,kubernetes会将pod.metadata.deleteionTimestamp
设置为发出删除信号的时间。
Kuectl可以检测到这个属性,并在看到这一点时将Pod的状态显示为Terminating
。
官方文档有关于这个的介绍
当一个 Pod 被删除时,执行一些 kubectl 命令会展示这个 Pod 的状态为 Terminating(终止)。 这个 Terminating 状态并不是 Pod 阶段之一。 Pod 被赋予一个可以体面终止的期限,默认为 30 秒。 你可以使用 --force 参数来强制终止 Pod。
相关Api介绍