引言

今天给大家介绍的内容,主要围绕一个命令进行:kubectl describe pod podName。对于pod的描述信息,在平时的使用中经常会用到,尤其是在排查异常的时候。在描述信息中,记录了Pod生命周期中的各个状态,需要多多理解...

Pod生命周期

Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。

可以概括为下图所示:


kubectl describe pod_程序人生

说明: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 创建容器。容器的状态有如下三种:

  1. 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
...
  1. 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
...
  1. 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 ~]#

扩展

  1. 强制终止 Pod

有时会遇到一直处于Terminated状态的Pod,需要手动删除。命令示例如下:

kubectl delete pod podName --force --grace-period=0

说明:默认情况下,所有的删除操作都会附有 30 秒钟的宽限期限。 kubectl delete 命令支持 --grace-period=<seconds> 选项,允许你重载默认值,设定自己希望的期限值。另外必须在设置 --grace-period=0 的同时额外设置 --force 参数才能发起强制删除请求。

  1. CrashLoopBackOff状态

CrashLoopBackOff表明Kubernetes试图启动该Pod,但是过程中出现错误,导致容器启动失败。

排查思路

查看描述信息:

kubectl describe pod podName

查看日志:

kubectl logs -f podName

查看前一个容器的日志:

kubectl logs <pod-name> --previous

说明:启动过程中出现问题的原因可能有很多,一般此状态查看容器的日志就可以解决。

本文由 mdnice 多平台发布