##k8s pod 状态分析

pod从创建到最后的创建成功会分别处于不同的阶段,在源码中用PodPhase来表示不同的阶段:

PodPending PodPhase = "Pending"
PodRunning PodPhase = "Running"
PodSucceeded PodPhase = "Succeeded"
PodFailed PodPhase = "Failed"
PodUnknown PodPhase = "Unknown"

一个pod的完整创建,通常会伴随着各种事件的产生,k8s种事件的种类总共只有4种:

Added    EventType = "ADDED"
Modified EventType = "MODIFIED"
Deleted  EventType = "DELETED"
Error    EventType = "ERROR"
  • Pending 创建pod的请求已经被k8s接受,但是容器并没有启动成功,可能处在:写数据到etcd,调度,pull镜像,启动容器这四个阶段中的任何一个阶段,pending伴随的事件通常会有:ADDED, Modified这两个事件的产生。
  • Running pod已经绑定到node节点,并且所有的容器已经启动成功,或者至少有一个容器在运行,或者在重启中。
  • Succeeded pod中的所有的容器已经正常的自行退出,并且k8s永远不会自动重启这些容器,一般会是在部署job的时候会出现。
  • Failed pod中的所有容器已经终止,并且至少有一个容器已经终止于失败(退出非零退出代码或被系统停止)。
  • Unknown 由于某种原因,无法获得pod的状态,通常是由于与pod的主机通信错误。

以上说到的pod的状态是粗略的状态,还有更佳详细的状态信息,在源码中表示如下:

PodScheduled PodConditionType = "PodScheduled"
PodReady PodConditionType = "Ready"
PodInitialized PodConditionType = "Initialized"
PodReasonUnschedulable = "Unschedulable"
type PodCondition struct {
  Type PodConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=PodConditionType"`
  Status ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=ConditionStatus"`
  LastProbeTime metav1.Time `json:"lastProbeTime,omitempty" protobuf:"bytes,3,opt,name=lastProbeTime"`
  LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,4,opt,name=lastTransitionTime"`
  Reason string `json:"reason,omitempty" protobuf:"bytes,5,opt,name=reason"`
  Message string `json:"message,omitempty" protobuf:"bytes,6,opt,name=message"`
}
  • PodScheduled pod正处于调度中,刚开始调度的时候,hostip还没绑定上,持续调度之后,有合适的节点就会绑定hostip,然后更新etcd数据
  • Initialized pod中的所有初始化容器已经初启动完毕
  • Ready pod中的容器可以提供服务了
  • Unschedulable 不能调度,没有合适的节点

PodCondition中的ConditionStatus,它代表了当前pod是否处于某一个阶段(PodScheduled,Ready,Initialized,Unschedulable),“true” 表示处于,“false”表示不处于

以下通过创建一个pod来具体的看看从pod创建到成功所触发的事件,以及pod相关状态的改变

kubectl apply -f busybox.yaml

第一步:写入数据到etcd

event type: ADDED 
event object: 
{
	"phase": "Pending",
	"qosClass": "BestEffort"
}

第二步:开始被调度,但是还未调度到具体node上,请注意:PodScheduled的status=“true”

event type: MODIFIED
{
  "phase": "Pending",
  "conditions": [
    {
      "type": "PodScheduled",
      "status": "True",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:06Z"
    }
  ],
  "qosClass": "BestEffort"
}

第三步:被调度到了具体的node上hostip绑定了,并且被所有初始化容器已经启动完毕(注意我的busybox.yaml中pod没有指定init container,所以这里很快就被设置成true),被调度到的节点watch到并开始创建容器(此阶段是在拉去镜像)然后创建容器 ,而此时Ready的status是false,仔细看会发现,containerStatus的状态未waiting

event type: MODIFIED
{
  "phase": "Pending",
  "conditions": [
    {
      "type": "Initialized",
      "status": "True",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:06Z"
    },
    {
      "type": "Ready",
      "status": "False",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:06Z",
      "reason": "ContainersNotReady",
      "message": "containers with unready status: [busybox]"
    },
    {
      "type": "PodScheduled",
      "status": "True",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:06Z"
    }
  ],
  "hostIP": "10.39.1.35",
  "startTime": "2017-06-06T07:57:06Z",
  "containerStatuses": [
    {
      "name": "busybox",
      "state": {
        "waiting": {
          "reason": "ContainerCreating"
        }
      },
      "lastState": {},
      "ready": false,
      "restartCount": 0,
      "image": "busybox",
      "imageID": ""
    }
  ],
  "qosClass": "BestEffort"
}

第四步:容器创建成功,Ready的status=“true”,此时容器的status也为running,这个时候,对应的pod的PodPhase也应该为running

event type: MODIFIED
{
  "phase": "Running",
  "conditions": [
    {
      "type": "Initialized",
      "status": "True",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:06Z"
    },
    {
      "type": "Ready",
      "status": "True",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:08Z"
    },
    {
      "type": "PodScheduled",
      "status": "True",
      "lastProbeTime": null,
      "lastTransitionTime": "2017-06-06T07:57:06Z"
    }
  ],
  "hostIP": "10.39.1.35",
  "podIP": "192.168.107.204",
  "startTime": "2017-06-06T07:57:06Z",
  "containerStatuses": [
    {
      "name": "busybox",
      "state": {
        "running": {
          "startedAt": "2017-06-06T07:57:08Z"
        }
      },
      "lastState": {},
      "ready": true,
      "restartCount": 0,
      "image": "busybox:latest",
      "imageID": "docker-pullable://busybox@sha256:c79345819a6882c31b41bc771d9a94fc52872fa651b36771fbe0c8461d7ee558",
      "containerID": "docker://a6af9d58c7dabf55fdfe8d4222b2c16349e3b49b3d0eca4bc761fdb571f3cf44"
    }
  ],
  "qosClass": "BestEffort"
}