Pod状态及生命周期
Pod分为两类:
- 自主式Pod:这种Pod本身是不能自我修复的。当Pod被创建后(不论是由你直接创建还是被其它COntroller),都会被K8s调度到集群的Node上。直到pod的进程终止、被删掉。因为缺少资源而被驱逐、或者Node故障之前这个Pod都会一直保持在八个Node上。Pod不会自愈。如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。
- 控制器管理的Pod:K8s使用更高级的称为Controller的抽象层,来管理Pod实例。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如。如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上,虽然可以直接使用Pod,但是在K8s中通常是使用Controller来管理Pod的。
注:每个Pod都有一个特殊的被称为“根容器”的Pause容器。Pause容器对应的景象属于K8s平台的一部分,除了Pause容器,每个Pod还包含一个或者多个紧密相关的用户业务容器。
K8s涉及这样的Pod概念和特殊组成结构有什么含义?
- 在一组容器作为一个单元的情况下,难以对整体的容器简单地进行判断及有效地进行行动。比如,一个容器死亡了,此时是算整体挂了么?那么引入与业务无关的Pause容器作为Pod的根容器,以它的状态代表着整个容器组的状态。
- Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂载的Volume,这样简化了业务容器之间的通信问题。也解决了容器之间的文件共享问题。
Pod的持久性和终止
Pod的持久性:
Pod在设计支持就不是作为持久化设计的。在调度失败、节点故障缺少资源或者节点维护的状态下都会死掉会被驱逐。
通常,用户不需要手动直接创建Pod,而是应该使用Controller(例如Deployment),即使是在创建单个Pod的情况下。Controller可以提供集群级别的资源功能、复制和升级管理。
Pod的终止
因为Pod作为集群的节点上运行的进程,所以在不再需要的时候能够优雅的终止是十分必要的(相比Kill这种方式)。用户需要能够放松删除请求,并且知道他们何时会被终止,是否被正确的删除,用户想终止程序是发生删除Pod请求,在Pod可以被强制删除前会有一个宽限期,会发送一个TERM请求到每个容器的主进程,一旦超市,将向主进程发送KILL信号并从API server中删除,如果Kubelet或者container manager在等待进程终止的过程中重启,在重启后仍然会重试完整的宽限期。
示例过程如下:
用户发送删除Pod的命令,默认宽限期是30秒;
在Pod超过该宽限期后API server就会更新Pod的状态为dead;
在客户端命令行上显示Pod状态为“terminating”;
跟第三步同时,当kubelet发送pod被标记为“terminating”状态时,开始停止pod进程;
a.如果在pod中定义了preStop hook,在停止pod前会被调用。如果在宽限期过后,preStop hook依然在运行,第二步会在增加2秒的宽限期;
b.向Pod中的进程发送TERM信号。跟第三步同时,该Pod将从该server的端点列表中删除,不再是replication
controller的一部分,关闭的慢的pod将继续处理load balance转发的流量过了宽限期后,将向Pod中依然运行的进程发送SIGKILL信号来杀掉进程。
Kubelet会在API
server中完成Pod的删除,通过将优雅周期设置为0(立即删除),Pod在API中消失,并且在客户端也不可见。
小扩展:term信号,终止信号,但是程序需捕捉到信号才可以,然后退出进程。
SIGQUIT:
在POSIX兼容的平台,SIGQUIT是其控制终端发送到进程,当用户请求的过程中执行核心转储的信号。 SIGQUIT通常可以ctrl+ \。在Linux上,人们还可以使用Ctrl-4或虚拟控制台,SysRq yek。SIGTERM:
SIGTERM是杀或的killall命令发送到进程默认的信号。它会导致一过程的终止,但是SIGKILL信号不同,它可以被捕获和解释(或忽略)的过程。因此,SIGTERM类似于问一个进程终止可好,让清理文件和关闭。因为这个原因,许多Unix系统关机期间,初始化问题SIGTERM到所有非必要的断电过程中,等待几秒钟,然后发出SIGKILL强行终止仍然存在任何这样的过程。SIGINT:
符合POSIX平台,信号情报是由它的控制终端,当用户希望中断该过程发送到处理的信号。通常ctrl-C,但在某些系统上,“删除”字符或“break”键 - 当进程的控制终端的用户按下中断正在运行的进程的关键SIGINT被发送。SIGKILL:
上符合POSIX平台上,SIGKILL是发送到处理的信号以使其立即终止。当发送到程序,SIGKILL使其立即终止。在对比SIGTERM和SIGINT,这个信号不能被捕获或忽略,并且在接收过程中不能执行任何清理在接收到该信号。
扩展2
preStop hook
容器生命周期钩子(Container Lifecycle Hooks),监控容器生命周期的特定事件,并在事件发生时执行已注册的回调函数。支持两种钩子:
- postStart:容器启动后执行,注意由于是异步执行,它无法保证一定在ENTRYPOINT之后执行,如果失败,容器会被杀死,并根据RestartPolicy决定是否重启
- preStop:容器停止前执行,常用于资源清理,如果失败,容器同样也会被杀死
而钩子的回调函数支持两种方式:
exec:在容器内执行命令
httpGet:向指定URL发起GET请求
Pause容器
pause容器,又叫infra(鹰fai)容器,我们检查node节点的时候会发现每个node上都运行了很多的pause容器
docker ps | grep pause
K8s中的pause容器主要为每个业务容器提供以下功能:
- 在Pod中担任linux命名空间共享的基础
- 启动Pid命名空间,开启init进程
init容器介绍
Pod能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的init容器。
init容器与普通容器的不同:
- init容器总是运行到成功完成为止
- 每个init容器都必须在下一个init容器启动之前成功完成
如果pod的init容器失败,k8s会不断重启该pod,直到init容器成功为止。然后,如果Pod对应的restartPolicy为Never,它不会重新启动
Pod的生命周期
Pod phase(Pod的相位)
Pod的status信息保存在Podstatus中定义,其中有一个phase字段。Pod的相位phase是Pod在其生命周期的加到宏观概述。
Pod相位的数量和含义是严格指定的。phase可能的值:
- Pending(挂起):API
server创建了Pod资源对象并存入了etcd中,但是它并未被调度完成,或者仍然处于仓库下载镜像的过程中/ - Running:pod已经被调度到某节点上,并且所有容器都已经被kubelet创建完成。
- Succeeded:Pod中的所有容器都被成功终止,并且不会再重启
- Failed:Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止,也就是说,容器以非0状态推出或者被系统终止
- Unknown:因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败。
Pod创建的过程
- 用户通过kubectl或其它API客户端提交Pod Spec给API server
- API Server尝试将Pod对象的相关信息存储到etcd中,等待写入操作完成。API server返回确认信息到客户端
- API Server开始反映etcd中状态变化
- 所有的K8s组件通过watch集中跟踪检查API Server上的相关信息变动
- kube-scheduler(调度器)通过其"watcher"检测到API Server创建了新的Pod对象但是没有绑定到任何工作节点。
- kube-scheduler为Pod对象挑选一个工作节点并将结果信息更新到API Server。
- 调度结果新消息由API server更新到etcd,并且API server也开始反馈该Pod对象的调度结果
- Pod被调度到目标工作节点上的kubelet尝试在当前节点上调用docker engine进行启动容器,并将容器的状态结果返回到API
Server。 - API Server将Pod信息存储到etcd系统中。
- 在etcd确认写入操作完成,API Server将确认信息发送到相关的kubelet
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状态
与scheduler交互:
当提交创建pod的请求与API Server的交互完成之后,接下来由scheduler进行工作,该组件主要是完成pod的调度来决定pod具体运行在集群的哪个节点上。声明:API Server完成任务之后,将信息写入到etcd中,此时scheduler通过watch机制监听到写入到etcd的信息然后再进行工作,Scheduler读取到写入到etcd中的pod信息,然后基于一系列规则从集群中挑选一个合适的节点来运行它,调度时主要通过三步来确定pod运行节点:
- 节点预选:基于一系列预选规则对每个节点进行检查,将不符合的节点过滤掉
- 节点优选:对预选出的节点进行优先级排序,以便选出最适合运行pod对象的节点
- 从优先级结果中挑选出优先级最高的节点来运行pod对象,当此类节点多个时则随机选择一个
注:如果有特殊pod资源需要运行在特殊节点上,此时可以通过组合节点标签以及pod标签和标签选择器等来实现高级调度。如MatchInterPodAffinity、MatchNodeSelector 和 PodToleratesNodeTaints 等预选策略,他们为用户提供自定义 Pod 亲和性或反亲和性、节点亲和性以及基于污点及容忍度的调度机制
预选策略
预选策略就是节点过滤器,例如 MathNodeSelector 实现的规则,以及 PodFitsResources 实现的规则等。执行预选操作时,如果不存在适合的节点,此时 pod 会一直处于 pending 状态,直到至少有一个可用节点。
简单介绍几种:
- CheckNodeCondition:检查是否可以在节点报告磁盘、网络不可用或未准备好的情况下将 pod 对象调度其上。
- NoDiskConflict:检查 pod 对象请求的存储卷在此节点上是否可用,若不存在冲突则通过检查。
- MathNodeSelector:若 pod 对象定义了 spec.NodeSelector 属性,则检查节点标签是否能匹配此属性值。
优选函数
此外调度器支持为每个优选函数指定一个简单的整数值表示权重,进行节点优先级分值的计算
列举说明几个优选函数:
- TaintToleraionPriority:基于Pod资源对节点的污点容忍调度偏好进行其优先级的评估,它将 Pod 对象的
tolerations 列表与节点的污点进行匹配度检查,成功匹配的条目越多,则节点得分越低。 - NodeAffinityPriority:基于节点亲和性调度偏好进行优先级评估,它将根据 Pod 资源中的 nodeSelector
对给定节点进行匹配度计算,成功匹配到的条目越多则节点得分越高。
Kubelet组件启动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
下载容器镜像,并启动容器。
内容来源于网络
Pod状态及生命周期相关推荐
- k8s的Pod状态和生命周期管理
Pod状态和生命周期管理 一.什么是Pod? 二.Pod中如何管理多个容器? 三.使用Pod 四.Pod的持久性和终止 五.Pause容器 六.init容器 七.Pod的生命周期 (1)Pod pha ...
- k8s教程(pod篇)-生命周期、重启策略及健康检查
文章目录 01 引言 02 pod生命周期 03 pod重启策略 04 pod健康检查和服务可用性检查 4.1 方式一:ExecAction 4.2 方式二:TCPSocketAction 4.3 方 ...
- 一张图弄懂java线程的状态和生命周期
转载自 一张图弄懂java线程的状态和生命周期 上图是一个线程的生命周期状态流转图,很清楚的描绘了一个线程从创建到终止的过程. 这些状态的枚举值都定义在java.lang.Thread.State下 ...
- 线程知识点(一)—— 程序、进程、线程之间的区别与联系、Java的线程状态和生命周期
1 程序.进程.线程之间的区别与联系 三者之间的形象化理解: * 程序:代码实现了功能,就是程序,是静态的: * 进程:执行中的程序就是进程,是动态的: * 线程:进程内的一个执行单元,也是进程内的可 ...
- [转]Java 对象锁-synchronized()与线程的状态与生命周期
线程的状态与生命周期 Java 对象锁-synchronized() ? 1 2 3 4 synchronized(someObject){ //对象锁 } 对象锁的使用说明: 1.对象锁的返还. 当 ...
- Hibernate→HQL、query.list()返回数据类型、查询相关语句、分页、原生SQL、@注解、持久化对象状态及生命周期、一多关系、继承映射关系、逆向工程
HQL Query实例与表 session通用工具类 Query对象 from 类→List<类>接收 映射类 仅查询商品 查询商品及所在商家 别名 返回数据类型定义 Iterator接收 ...
- 电商中订单的状态有哪几种,请依次说明各个状态的生命周期
当用户点击"一键购买"或者是从购物车里点击 "去结算" ,会跳转到 "核实订单信息" 页面,当全部核实以后点击"提交订单按钮&q ...
- android生命周期方法,Android零基础入门|Activity状态和生命周期方法
原标题:Android零基础入门|Activity状态和生命周期方法 前面两期我们学习了Activity的创建和注册.以及启动和关闭,也学会了重写onCraete方法,这些知识在实际开发中远远不够,还 ...
- Pod详解-生命周期-概述
我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期,它主要包含下面的过程: pod创建过程 运行初始化容器(init container)过程 运行主容器(main container) ...
最新文章
- javascript读取xml文件读取节点数据的例子
- boost的chrono模块周期计数延迟的测试程序
- Linux中的基础IO(一)
- mysql集群搭建_mysql高可用集群搭建
- 不拦截指定路径_控制层访问拦截
- CF611F. New Year and Cleaning
- 不满足于汽车制造,丰田展示仿钢铁侠机器支撑腿架
- fgui的ui管理框架_DCET: Unity3D客户端和.Net Core服务器双端框架,支持代码全热更(包括FGUI和双端行为树)...
- Oracle项目管理系统的BIM应用
- 聊天ai机器人_适用于您网站的14种最佳AI聊天机器人软件(已比较)
- 太阳高度角/方位角计算公式
- Kafka工具--雅虎CMAK
- Linux下使用Netfilter框架编写内核模块(统计协议层ping特定地址丢包数)
- F - 郭鑫的难题(三)
- Unity 基础开发-WebGL发布无法运行问题
- 京东金融java面试题_互联网金融西部联盟
- 大数据之Spark:Spark Core(1)
- (附源码)基于springboot微信小程序的长沙县图书馆图书导览系统 毕业设计 170900
- 一步一步教你反向传播,求梯度(A Step by Step Backpropagation Example)
- 篇韵文 便识天下汉字(转载)
热门文章
- WPS软件里面怎么打勾?知道这个小技巧的人早就用起来了
- 生产制造业网络运维监控方案
- python程序设置_Windows系统中设置Python程序定时运行方法
- 绝地求生服务器维护6.17,绝地求生6月17日维护到几点 绝地求生6月17日更新维护时间详情...
- 6.7绝地求生服务器维护,绝地求生6月5日更新维护全内容及官方更新时间
- log4j使用回顾整理
- 什么是产融结合?什么是普惠金融
- 电脑故障/品牌(如惠普)主机分多块屏幕显示,插上显卡后屏幕无反应
- 汽车 Automotive > T-BOX GNSS高精定位测试相关知识
- ADS127L11采集板系统噪声评估