k8s 笔记(二) Pod 基础介绍

2020/03/12 k8s

1. Pod 介绍

Pod 是 kubernetes 系统的基础的基础单元, 是由用户创建或部署的最小组件,也是kubernetes系统上运行容器化应用的资源对象。

kubernetes 集群中其他资源对象都是为Pod这个资源对象做支撑来实现kubernetes管理应用服务的目的。k8s 集群组件主要包括节点组建API ServerController ManagerScheduler 以及子节点组件 kubeletcontainer Runtime(如Docker)、kube-proxy等。

从集群各组件交互角度讲述 Pod的创建、运行、销毁等生命周期,Pod生命周期中的几种不同状态包括 PendingRunningSucceededfailedUnknow

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 specAPI Server作为pod创建的起始。

PodAPI Server交互的主要流程如下:

  1. API Server 在接收到创建pod的请求后,会根据用户提交的参数值来创建一个运行时的pod对象
  2. 根据API Server请求的上下文的元数据来验证两者的namespace是否相匹配,如果不匹配则创建失败
  3. Namespace匹配成功之后,会向pod对象注入一些系统数据,如果pod未提供pod的名字,则API Server会将poduid作为pod的名字
  4. API Server接下来会检查pod对象的必须字段是否为空,如果为空则创建失败
  5. 上述准备工作完成后会将在etcd中持久化这个对象,将异步调用返回结果封装成restful.response,完成结果反馈
  6. 至此,API Server创建过程完成,剩下的由schedulerkubelet来完成,此时pod处于pending状态

3. 与Scheduler交互

当提交创建pod的请求与API Server交互完成后,接下来由Scheduler进行工作,该组件主要是完成pod的调度来决定pod具体运行在集群的哪个节点上。

注意,API Server完成工作后,将数据写入到etcd中,Scheduler通过watch机制监听到写入etcd中的信息然后再进行工作。Scheduler读取到写入etcd中的pod信息,然后由一些列规则从集群中挑选一个合适的节点来运行它,调度时主要通过下面3步来确定运行pod的节点:

  1. 节点预选:基于一些列规则(如PodFitsResourceMatchNode-Selector等)对每个节点进行检查,将不符合的节点过滤掉从而完成节点预选
  2. 节点优选:对预选出的节点进行优先级排序,以选择出最适合运行的节点
  3. 从优先级结果中挑选出优先级最高的节点来运行Pod对象,当此类节点多个时,则随机挑选出一个

注:如果有特殊 pod 资源需要运行在特殊节点上,此时可以通过组合节点标签以及 pod 标签和标签选择器等来实现高级调度,如 MatchInterPodAffinityMatchNodeSelectorPodToleratesNodeTaints 等预选策略,他们为用户提供自定义 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 的任务,则做如下处理:

  1. 为该 pod 创建一个数据目录
  2. 从 API Server 读取该 pod 清单
  3. 为该 pod 挂载外部卷
  4. 下载 pod 所需的 Secret
  5. 检查已经运行在节点中 pod,如果该 pod 没有容器或者 Pause 容器没有启动,则先停止pod里所有的容器进程。
  6. 使用 pause 镜像为每个pod创建一个容器,该容器用于接管 Pod 中所有其他容器的网络。
  7. 为 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状态类型,可以为TrueFalseUnknown
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 将在别处重建。

Search

    Table of Contents