1. Pod 介绍
Pod
是 kubernetes 系统的基础的基础单元, 是由用户创建或部署的最小组件,也是kubernetes
系统上运行容器化应用的资源对象。
kubernetes
集群中其他资源对象都是为Pod
这个资源对象做支撑来实现kubernetes
管理应用服务的目的。k8s
集群组件主要包括节点组建API Server
、Controller Manager
、Scheduler
以及子节点组件 kubelet
、container Runtime
(如Docker
)、kube-proxy
等。
从集群各组件交互角度讲述 Pod
的创建、运行、销毁等生命周期,Pod
生命周期中的几种不同状态包括 Pending
、Running
、Succeeded
、failed
、Unknow
。
1.1. Pod 状态描述
状态值 | 描述 | |
---|---|---|
Pending | Pod 已被Kubernetes 接受,但尚未创建一个或多个容器镜像。这包括被调度之前的时间以及通过网络下载镜像的时间 |
|
Running | Pod 以及被绑定到一个节点,所有容器已经被创建,至少一个容器正在运行,或者正在启动或重新启动 |
|
Succeeded | 所有容器成功终止,也不会重启 | |
Failed | 所有容器终止,至少有一个以上的容器以失败方式终止。也就是说,这个容器要么以非0状态终止,要么被系统终止 | |
Unknown | 由于一些原因,Pod的状态无法获取,通常是与Pod通信时出错导致的 |
查看Pod
状态:
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 4h2m
2. 与API Server交互
API Server
提供了集群与外部交互的接口,通过kubectl
命令或其他API
客户端提交pod spec
给API Server
作为pod
创建的起始。
Pod
与API Server
交互的主要流程如下:
API Server
在接收到创建pod
的请求后,会根据用户提交的参数值来创建一个运行时的pod
对象- 根据
API Server
请求的上下文的元数据来验证两者的namespace
是否相匹配,如果不匹配则创建失败 Namespace
匹配成功之后,会向pod
对象注入一些系统数据,如果pod未提供pod
的名字,则API Server
会将pod
的uid
作为pod
的名字API Server
接下来会检查pod
对象的必须字段是否为空,如果为空则创建失败- 上述准备工作完成后会将在
etcd
中持久化这个对象,将异步调用返回结果封装成restful.response
,完成结果反馈 - 至此,
API Server
创建过程完成,剩下的由scheduler
和kubelet
来完成,此时pod
处于pending
状态
3. 与Scheduler交互
当提交创建pod
的请求与API Server
交互完成后,接下来由Scheduler
进行工作,该组件主要是完成pod
的调度来决定pod
具体运行在集群的哪个节点上。
注意,API Server
完成工作后,将数据写入到etcd
中,Scheduler
通过watch
机制监听到写入etcd
中的信息然后再进行工作。Scheduler
读取到写入etcd
中的pod
信息,然后由一些列规则从集群中挑选一个合适的节点来运行它,调度时主要通过下面3步来确定运行pod
的节点:
- 节点预选:基于一些列规则(如
PodFitsResource
、MatchNode-Selector
等)对每个节点进行检查,将不符合的节点过滤掉从而完成节点预选 - 节点优选:对预选出的节点进行优先级排序,以选择出最适合运行的节点
- 从优先级结果中挑选出优先级最高的节点来运行Pod对象,当此类节点多个时,则随机挑选出一个
注:如果有特殊 pod
资源需要运行在特殊节点上,此时可以通过组合节点标签以及 pod
标签和标签选择器等来实现高级调度,如 MatchInterPodAffinity
、MatchNodeSelector
和 PodToleratesNodeTaints
等预选策略,他们为用户提供自定义 Pod
亲和性或反亲和性、节点亲和性以及基于污点及容忍度的调度机制。
对于 预选策略 与 优选策略 可查看 scheduler
基础介绍
当scheduler
通过一系列策略选定pod
运行节点之后将结果发送到API Server
,由API Server
更新至etcd
中,并由API Server
反映调度结果,接下来由kubelet
在所选定点节点上启动pod
4. Kubelet组件启动pod
kubelet 组件的作用不单单是创建 pod,另外还包括节点管理、cAdvisor 资源监控管理、容器健康检查等功能。
启动pod流程分析
kubelet 通过 API Server 监听 etcd 目录,同步 pod 列表。如果发现有新的 pod 绑定到本节点,则按照 pod 清单要求创建 pod,如果是发现 pod 被更新,则做出相应更改。读取到 pod 的信息之后,如果是创建和修改 pod 的任务,则做如下处理:
- 为该 pod 创建一个数据目录
- 从 API Server 读取该 pod 清单
- 为该 pod 挂载外部卷
- 下载 pod 所需的 Secret
- 检查已经运行在节点中 pod,如果该 pod 没有容器或者 Pause 容器没有启动,则先停止pod里所有的容器进程。
- 使用 pause 镜像为每个pod创建一个容器,该容器用于接管 Pod 中所有其他容器的网络。
- 为 pod 中的每个容器做如下处理:1.为容器计算一个 hash 值,然后用容器的名字去查询对于 docker 容器的 hash 值。若查找到容器,且两者的 hash 值不同,则停止 docker 中容器中进程,并停止与之关联的 pause 容器,若相同,则不做处理。若容器被终止了,且容器没有指定的重启策略,则不做任何处理调用 docker client 下载容器镜像,并启动容器。
5. Pod conditions
每个Pod都拥有一个PodStatus
,里面包含PodConditions
,代表Condition
是否通过。
PodCondition
属性描述:
字段 | 描述 |
---|---|
lastProbeTime | 最后一次探测 Pod Condition 的时间戳 |
lastTransitionTime | 上次Condition从一种状态转换到另一种状态的时间 |
message | 上次Condition状态转换的详细描述 |
reason | Condition最后一次转换的原因 |
status | Codition状态类型,可以为True False Unknown |
type | Condition类型 |
关于Condition Type的描述:
Type | 描述 |
---|---|
PodScheduled Pod | 已被调度到一个节点 |
Ready Pod | 能够提供请求,应该被添加到负载均衡池中以提供服务 |
Initialized | 所有 init containers 成功启动 |
Unschedulable | 调度器不能正常调度容器,例如缺乏资源或其他限制 |
ContainersReady Pod | 中所有容器全部就绪 |
6. Pod 状态示例
- Pod 中只有一个容器并且正在运行。容器成功退出。
- 记录完成事件。
- 如果 restartPolicy 为:
- Always:重启容器;Pod phase 仍为 Running。
- OnFailure:Pod phase 变成 Succeeded。
- Never:Pod phase 变成 Succeeded。
- Pod 中只有一个容器并且正在运行。容器退出失败。
- 记录失败事件。
- 如果 restartPolicy 为:
- Always:重启容器;Pod phase 仍为 Running。
- OnFailure:重启容器;Pod phase 仍为 Running。
- Never:Pod phase 变成 Failed。
- Pod 中有两个容器并且正在运行。有一个容器退出失败。
- 记录失败事件。
- 如果 restartPolicy 为:
- Always:重启容器;Pod phase 仍为 Running。
- OnFailure:重启容器;Pod phase 仍为 Running。
- Never:不重启容器;Pod phase 仍为 Running。
- 如果有一个容器没有处于运行状态,并且两个容器退出:
- 记录失败事件。
- 如果 restartPolicy 为:
- Always:重启容器;Pod phase 仍为 Running。
- OnFailure:重启容器;Pod phase 仍为 Running。
- Never:Pod phase 变成 Failed。
- Pod 中只有一个容器并处于运行状态。容器运行时内存超出限制:
- 容器以失败状态终止。
- 记录 OOM 事件。
- 如果 restartPolicy 为:
- Always:重启容器;Pod phase 仍为 Running。
- OnFailure:重启容器;Pod phase 仍为 Running。
- Never: 记录失败事件;Pod phase 仍为 Failed。
- Pod 正在运行,磁盘故障:
- 杀掉所有容器。
- 记录适当事件。
- Pod phase 变成 Failed。
- 如果使用控制器来运行,Pod 将在别处重建。
- Pod 正在运行,其节点被分段。
- 节点控制器等待直到超时。
- 节点控制器将 Pod phase 设置为 Failed。
- 如果是用控制器来运行,Pod 将在别处重建。