Pod
概述
1、Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元
2、Pod 是一组(一个或多个) 容器
(1)这些容器共享存储、网络、以及怎样运行这些容器的声明
(2)Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行
(3)Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器相对紧密地耦合在一起
(4)在非云环境中,在相同的物理机或虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用
3、除了应用容器,Pod 还可以包含在 Pod 启动期间运行的 Init 容器,也可以在集群支持临时性容器的情况下,为调试的目的注入临时性容器
什么是 Pod
1、说明: 除了 Docker 之外,Kubernetes 支持很多其他容器运行时,Docker 是最有名的运行时,使用 Docker 的术语来描述 Pod 会很有帮助
2、Pod 的共享上下文包括一组 Linux 命名空间、控制组(cgroup)和可能一些其他的隔离方面, 即用来隔离容器的技术。 在 Pod 的上下文中,每个独立的应用可能会进一步实施隔离
3、Pod 类似于共享命名空间并共享文件系统卷的一组容器
Pod 定义
1、Pod 是可以在主机上运行的容器的集合。此资源由客户端创建并调度到主机上
2、一级属性
(1)apiVersion: v1
(2)kind: Pod
(3)metadata(ObjectMeta):标准的对象元数据
(4)spec(PodSpec):对 Pod 预期行为的规约
(5)status(PodStatus):最近观察到的 Pod 状态。这些数据可能不是最新的。由系统填充。只读
Pod 生命期
1、和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体
(1)Pod 会被创建、赋予一个唯一的 ID(UID),并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点
(2)如果一个节点死掉了,调度到该节点的 Pod 也被计划在给定超时期限结束后删除
2、Pod 自身不具有自愈能力
(1)如果 Pod 被调度到某节点而该节点之后失效, Pod 会被删除
(2)类似地,Pod 无法在因节点资源耗尽或者节点维护而被驱逐期间继续存活
(3)Kubernetes 使用一种高级抽象来管理这些相对而言可随时丢弃的 Pod 实例,称作控制器
(4)任何给定的 Pod (由 UID 定义)从不会被“重新调度(rescheduled)”到不同的节点;相反,这一 Pod 可以被一个新的、几乎完全相同的 Pod 替换掉。如果需要,新 Pod 的名字可以不变,但是其 UID 会不同
(5)如果某物声称其生命期与某 Pod 相同,例如存储卷, 这就意味着该对象在此 Pod (UID 亦相同)存在期间也一直存在。如果 Pod 因为任何原因被删除,甚至某完全相同的替代 Pod 被创建时,这个相关的对象(例如这里的卷)也会被删除并重建
Pod 阶段
1、Pod 的 status 字段是一个 PodStatus 对象,其中包含一个 phase 字段
(1)Pod 的阶段(Phase)是 Pod 在其生命周期中所处位置的简单宏观概述。 该阶段并不是对容器或 Pod 状态的综合汇总,也不是为了成为完整的状态机
(2)Pod 阶段的数量和含义是严格定义的,不应该再假定 Pod 有其他的 phase 值
取值 | 描述 |
---|---|
Pending(悬决) | Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。 |
Running(运行中) | Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。 |
Succeeded(成功) | Pod 中的所有容器都已成功终止,并且不会再重启。 |
Failed(失败) | Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。 |
Unknown(未知) | 因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。 |
2、说明:当一个 Pod 被删除时,执行一些 kubectl 命令会展示这个 Pod 的状态为 Terminating(终止)
(1)这个 Terminating 状态并不是 Pod 阶段之一,Pod 被赋予一个可以体面终止的期限,默认为 30 秒
(2)可以使用 --force 参数来强制终止 Pod
3、如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的 phase 设置为 Failed
容器状态
1、Kubernetes 会跟踪 Pod 中每个容器的状态,就像它跟踪 Pod 总体上的阶段一样
2、可以使用容器生命周期回调,来在容器生命周期中的特定时间点触发事件
3、一旦调度器将 Pod 分派给某个节点,kubelet 就通过容器运行时开始为 Pod 创建容器
4、要检查 Pod 中容器的状态,可以使用 kubectl describe pod <pod 名称>,其输出中包含 Pod 中每个容器的状态
5、Waiting(等待)
(1)如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态
(2)处于 Waiting 状态的容器仍在运行它完成启动所需要的操作,例如:从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等
(3)当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因
6、Running(运行中)
(1)Running 状态表明容器正在执行状态并且没有问题发生
(2)如果配置了 postStart 回调,那么该回调已经执行且已完成
(3)如果使用 kubectl 来查询包含 Running 状态的容器的 Pod 时,也会看到关于容器进入 Running 状态的信息
7、Terminated(已终止)
(1)处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败
(2)如果使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时,会看到容器进入此状态的原因、退出代码、容器执行期间的起止时间
(3)如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行
容器重启策略
1、重启策略适用于 Pod 对象中的所有容器
2、Pod 的 spec 中包含一个 restartPolicy 字段
(1)restartPolicy 适用于 Pod 中的所有容器
(2)restartPolicy 仅针对同一节点上 kubelet 的容器重启动作
3、取值
(1)Always:容器失效时,自动重启该容器,默认值
(2)OnFailure:容器终止运行且退出码不为 0 时重启
(3)Never:不论状态为何,都不重启该容器
4、当 Pod 中的容器退出时,kubelet 会按指数回退方式计算重启的延迟
(1)首次需要重启的容器,将在其需要时立即进行重启
(2)随后再次需要重启的操作将由 kubelet 延迟一段时间后进行,且反复的重启操作的延迟时长为 10s、20s、40s、80s、160s、300s,300s 是最大延迟时长
(3)一旦某容器执行了 10 分钟并且没有出现问题,kubelet 对该容器的重启回退计时器执行重置操作
容器回调
1、PostStart
(1)这个回调在容器被创建之后立即被执行,但是,不能保证回调会在容器入口点(ENTRYPOINT)之前执行
(2)没有参数传递给处理程序
2、PreStop
(1)在容器因 API 请求或者管理事件(诸如存活态探针、启动探针失败、资源抢占、资源竞争等) 而被终止之前,此回调会被调用
(2)如果容器已经处于已终止或者已完成状态,则对 preStop 回调的调用将失败
(3)在用来停止容器的 TERM 信号被发出之前,回调必须执行结束
(4)Pod 的终止宽限周期在 PreStop 回调被执行之前即开始计数,所以无论回调函数的执行结果如何,容器最终都会在 Pod 的终止宽限期内被终止
(5)没有参数会被传递给处理程序
Pod 创建过程
1、用户通过 kubectl 或其他 api 客户端,提交需要创建的 Pod 信息到 apiServer
2、apiServer 开始生成 Pod 对象的信息,并将信息存入 etcd,然后返回确认信息至客户端
3、apiServer 开始反映 etcd 中的 Pod 对象的变化,其它组件使用 watch 机制来跟踪检查 apiServer 上的变动
4、scheduler 发现有新的 Pod 对象要创建,开始为 Pod 分配主机并将结果信息更新至 apiServer
5、node 上的 kubelet 发现有 Pod 调度,尝试调用 docker 启动容器,并将结果回送至 apiServer
6、apiServer 将接收到的 pod 状态信息存入 etcd 中
Pod 的终止
1、由于 Pod 所代表的是在集群中节点上运行的进程,当不再需要这些进程时允许其体面地终止是很重要的,一般不应武断地使用 KILL 信号终止它们,导致这些进程没有机会完成清理操作
(1)设计的目标是能够请求删除进程,并且知道进程何时被终止,同时也能够确保删除操作终将完成
(2)当请求删除某个 Pod 时,集群会记录并跟踪 Pod 的体面终止周期,而不是直接强制地杀死 Pod
(3)在存在强制关闭设施的前提下, kubelet 会尝试体面地终止 Pod
2、通常情况下,容器运行时会发送一个 TERM 信号到每个容器中的主进程
(1)很多容器运行时都能够注意到容器镜像中 STOPSIGNAL 的值,并发送该信号而不是 TERM
(2)一旦超出了体面终止限期,容器运行时会向所有剩余进程发送 KILL 信号,之后 Pod 就会被从 API 服务器上移除
(3)如果 kubelet 或者容器运行时的管理服务在等待进程终止期间被重启,集群会从头开始重试,赋予 Pod 完整的体面终止限期
3、过程
(1)使用 kubectl 工具手动删除某个特定的 Pod,而该 Pod 的体面终止限期是默认值(30 秒)
(2)API 服务器中的 Pod 对象被更新,记录涵盖体面终止限期在内 Pod 的最终死期,超出所计算时间点则认为 Pod 已死(dead)
(3)如果使用 kubectl describe 来查验正在删除的 Pod,该 Pod 会显示为 Terminating(正在终止)
(4)在 Pod 运行所在的节点上:kubelet 一旦看到 Pod 被标记为正在终止(已经设置了体面终止限期),kubelet 即开始本地的 Pod 关闭过程
如果 Pod 中的容器之一定义了 preStop 回调, kubelet 开始在容器内运行该回调逻辑
如果超出体面终止限期时,preStop 回调逻辑仍在运行,kubelet 会请求给予该 Pod 的宽限期一次性增加 2 秒钟
如果 preStop 回调所需要的时间长于默认的体面终止限期,必须修改 terminationGracePeriodSeconds 属性值来使其正常工作
(5)kubelet 接下来触发容器运行时发送 TERM 信号给每个容器中的进程 1
Pod 中的容器会在不同时刻收到 TERM 信号,接收顺序也是不确定的,如果关闭的顺序很重要,可以考虑使用 preStop 回调逻辑来协调
(6)在 kubelet 启动体面关闭逻辑的同时,控制面会将关闭的 Pod 从对应的 EndpointSlice(和 Endpoints)对象中移除,过滤条件是 Pod 被对应的服务以某选择算符选定,ReplicaSet 和其他工作负载资源不再将关闭进程中的 Pod 视为合法的、能够提供服务的副本,关闭动作很慢的 Pod 也无法继续处理请求数据,因为负载均衡器(例如服务代理)已经在终止宽限期开始的时候将其从端点列表中移除
(7)超出终止宽限期限时,kubelet 会触发强制关闭过程,容器运行时会向 Pod 中所有容器内仍在运行的进程发送 SIGKILL 信号,如果容器运行时使用了这种容器的话,kubelet 也会清理隐藏的 pause 容器
(8)kubelet 触发强制从 API 服务器上删除 Pod 对象的逻辑,并将体面终止限期设置为 0 (这意味着马上删除)
(9)API 服务器删除 Pod 的 API 对象,从任何客户端都无法再看到该对象
容器探针
1、probe 是由 kubelet 对容器执行的定期诊断,要执行诊断,kubelet 既可以在容器内执行代码,也可以发出一个网络请求
2、探针的检查机制
(1)exec:在容器内执行指定命令,如果命令退出时返回码为 0 则认为诊断成功
(2)grpc:使用 gRPC 执行一个远程过程调用,目标应该实现 gRPC健康检查,如果响应的状态是 SERVING,则认为诊断成功,gRPC 探针是一个 Alpha 特性,只有在启用 GRPCContainerProbe 特性门控时才能使用
(3)httpGet:对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求,如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的
(4)tcpSocket:对容器的 IP 地址上的指定端口执行 TCP 检查,如果端口打开,则诊断被认为是成功的,如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的
3、探测结果
(1)Success(成功):容器通过了诊断
(2)Failure(失败):容器未通过诊断
(3)Unknown(未知):诊断失败,因此不会采取任何行动
4、探针类型
(1)livenessProbe(存活态探针):指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器,并且容器将根据其重启策略决定未来,如果容器不提供存活探针,则默认状态为 Success
(2)readinessProbe(就绪态探针):指示容器是否准备好为请求提供服务。如果就绪态探测失败,端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。初始延迟之前的就绪态的状态值默认为 Failure。如果容器不提供就绪态探针,则默认状态为 Success
(3)startupProbe(启动探针):指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success
5、何时该使用存活态探针
(1)如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活态探针;kubelet 将根据 Pod 的 restartPolicy 自动执行修复操作
(2)如果希望容器在探测失败时被杀死并重新启动,那么请指定一个存活态探针,并指定 restartPolicy 为 Always 或 OnFailure
6、何时该使用就绪态探针
(1)如果要仅在探测成功时才开始向 Pod 发送请求流量,请指定就绪态探针.在这种情况下,就绪态探针可能与存活态探针相同,但是规约中的就绪态探针的存在意味着 Pod 将在启动阶段不接收任何数据,并且只有在探针探测成功后才开始接收数据
(2)如果希望容器能够自行进入维护状态,也可以指定一个就绪态探针,检查某个特定于就绪态的因此不同于存活态探测的端点
(3)如果应用程序对后端服务有严格的依赖性,可以同时实现存活态和就绪态探针。当应用程序本身是健康的,存活态探针检测通过后,就绪态探针会额外检查每个所需的后端服务是否可用。这可以帮助避免将流量导向只能返回错误信息的 Pod
(4)如果容器需要在启动期间加载大型数据、配置文件或执行迁移,可以使用启动探针。然而,如果想区分已经失败的应用和仍在处理其启动数据的应用,可能更倾向于使用就绪探针
(5)请注意,如果只是想在 Pod 被删除时能够排空请求,则不一定需要使用就绪态探针;在删除 Pod 时,Pod 会自动将自身置于未就绪状态,无论就绪态探针是否存在。等待 Pod 中的容器停止期间,Pod 会一直处于未就绪状态
7、何时该使用启动探针
(1)对于所包含的容器需要较长时间才能启动就绪的 Pod 而言,启动探针是有用的,不再需要配置一个较长的存活态探测时间间隔,只需要设置另一个独立的配置选定,对启动期间的容器执行探测,从而允许使用远远超出存活态时间间隔所允许的时长
(2)如果容器启动时间通常超出 initialDelaySeconds + failureThreshold × periodSeconds 总值,应该设置一个启动探测,对存活态探针所使用的同一端点执行检查,periodSeconds 的默认值是 10 秒,应该将其 failureThreshold 设置得足够高, 以便容器有充足的时间完成启动,并且避免更改存活态探针所使用的默认值,这一设置有助于减少死锁状况的发生
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战