引言
今天给大家介绍的内容,主要围绕一个命令进行:kubectl describe pod podName
。对于pod的描述信息,在平时的使用中经常会用到,尤其是在排查异常的时候。在描述信息中,记录了Pod生命周期中的各个状态,需要多多理解...
Pod生命周期
Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。
可以概括为下图所示:
说明:Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者被终止。
Pod状态
通过Pod生命周期,我们已经得出了Pod状态,整理如下:
状态 | 描述 |
Pending(悬决) | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
Running(运行中) | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
Succeeded(成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 |
Failed(失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。 |
Unknown(未知) | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 |
说明:如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的状态设置为 Failed。
[root@k8s-master ~]# kubectl describe pod nginx-deploy-7ff6dd9bd-6tlt2
Name: nginx-deploy-7ff6dd9bd-6tlt2
Namespace: default
...
Status: Pending
IP: 192.168.79.104
IPs:
IP: 192.168.79.104
Controlled By: ReplicaSet/nginx-deploy-7ff6dd9bd
...
说明:Pod处于哪个状态(生命周期)通过Status
字段来定义。
容器状态
当Pod被调度器分配到某个节点,kubelet 就通过容器运行时 开始为 Pod 创建容器。容器的状态有如下三种:
- Waiting (等待)
处于 Waiting 状态的容器仍在运行它完成启动所需要的操作:例如,从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等。当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
[root@k8s-master ~]# kubectl describe pod nginx-deploy-7ff6dd9bd-6tlt2
Name: nginx-deploy-7ff6dd9bd-6tlt2
Namespace: default
...
Containers:
mynginx:
Container ID:
Image: nginx:1.23.222
Image ID:
Port: <none>
Host Port: <none>
State: Waiting
Reason: ImagePullBackOff
Ready: False
...
- Running(运行中)
Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。 如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时,你也会看到 关于容器进入 Running 状态的信息。
[root@k8s-master ~]# kubectl describe pod nginx-deploy-69c765d6d-hmtkj
Name: nginx-deploy-69c765d6d-hmtkj
Namespace: default
...
Containers:
mynginx:
Container ID: docker://e3962726018c97b3b3825941ed0416f2e25d3e28b4ddd08bc85ef881df4d5ec0
Image: nginx:1.23
Image ID: docker-pullable://nginx@sha256:790711e34858c9b0741edffef6ed3d8199d8faa33f2870dea5db70f16384df79
Port: <none>
Host Port: <none>
State: Running
Started: Mon, 15 Aug 2022 19:55:20 +0800
Ready: True
...
- Terminated(已终止)
处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时,你会看到 容器进入此状态的原因、退出代码以及容器执行期间的起止时间。
[root@k8s-master ~]# kubectl describe pod nginx-deploy-69c765d6d-7g89j
Name: nginx-deploy-69c765d6d-7g89j
Namespace: default
...
Containers:
mynginx:
Container ID: docker://aa9002c779143377889ad586e95483b1be6fcf7d10ddf01d76752392393e5419
Image: nginx:1.23
Image ID: docker-pullable://nginx@sha256:790711e34858c9b0741edffef6ed3d8199d8faa33f2870dea5db70f16384df79
Port: <none>
Host Port: <none>
State: Terminated
Reason: Completed
Exit Code: 0
Started: Mon, 15 Aug 2022 21:06:01 +0800
Finished: Mon, 15 Aug 2022 22:10:08 +0800
Ready: False
...
[root@k8s-master ~]#
说明:容器状态区别于Pod状态,是通过Containers.State
字段来定义的。
Pod 状况
Pod 有一个 PodStatus 对象,其中包含一个 PodConditions 数组。Pod 可能通过也可能未通过其中的一些状况测试。
- PodScheduled:Pod 已经被调度到某节点;
- ContainersReady:Pod 中所有容器都已就绪;
- Initialized:所有的 Init 容器 都已成功完成;
- Ready:Pod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。
[root@k8s-master ~]# kubectl describe pod nginx-deploy-69c765d6d-hmtkj
Name: nginx-deploy-69c765d6d-hmtkj
Namespace: default
...
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
...
说明:Pod 状况通过Conditions
字段来定义。
事件
在describe中,还有一个非常重要的信息需要关注——事件(Events),这里将记录Pod整个生命周期中的各个状态,排查问题也主要是看这个地方。如下:
[root@k8s-master ~]# kubectl describe pod nginx-deploy-69c765d6d-7g89j
Name: nginx-deploy-69c765d6d-7g89j
Namespace: default
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning NodeNotReady 5m8s node-controller Node is not ready
Normal SandboxChanged 112s (x2 over 2m36s) kubelet Pod sandbox changed, it will be killed and re-created.
Normal Pulled 112s kubelet Container image "nginx:1.23" already present on machine
Normal Created 112s kubelet Created container mynginx
Normal Started 111s kubelet Started container mynginx
[root@k8s-master ~]#
扩展
- 强制终止 Pod
有时会遇到一直处于Terminated状态的Pod,需要手动删除。命令示例如下:
kubectl delete pod podName --force --grace-period=0
说明:默认情况下,所有的删除操作都会附有 30 秒钟的宽限期限。 kubectl delete 命令支持 --grace-period=<seconds> 选项,允许你重载默认值,设定自己希望的期限值。另外必须在设置 --grace-period=0 的同时额外设置 --force 参数才能发起强制删除请求。
- CrashLoopBackOff状态
CrashLoopBackOff表明Kubernetes试图启动该Pod,但是过程中出现错误,导致容器启动失败。
排查思路:
查看描述信息:
kubectl describe pod podName
查看日志:
kubectl logs -f podName
查看前一个容器的日志:
kubectl logs <pod-name> --previous
说明:启动过程中出现问题的原因可能有很多,一般此状态查看容器的日志就可以解决。
本文由 mdnice 多平台发布