##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"
}