当创建一个Pod后,kubernetes会发生什么?

举报
可以交个朋友 发表于 2023/12/04 20:01:02 2023/12/04
【摘要】 pod创建后各个组件协作流程

一、Pod简介

  • Pod是kubernetes集群管理的最小调度单位,是一个逻辑概念,物理上不存在。

  • 一个pod中可以包含一个或多个容器,且同一个pod中的所有容器共享网络、存储、进程等。

二、Pod创建调度流程图

Pod创建流程图说明:

  1. 用户使用通过kubectl客户端发起创建Pod资源对象请求至api-server。

  2. api-server对请求用户鉴权、准入控制操作,然后将该请求资源事件写入到etcd存储中。

  3. schduler组件采用非阻塞式长连接watch机制实时获取集群待调度Pod资源对象信息(包括用户新建、各控制器为补足工作负载期望副本实例数而创建的Pod)和当前集群Node节点状态信息,一旦获悉集群中有新Pod资源资源需要被调度,则通过api-server获取etcd中相关Pod资源对象信息。

  4. api-server将相关待调度的Pod资源信息返回给Scheduler的watch接口长连接

  5. scheduler根据自身算法,计算出Pod与最终生产Pod的node节点的绑定关系,将该Pod绑定结果事件通过api-server存储在Etcd中。

  6. api-server更新etcd中Pod的绑定信息。

  7. 各Node节点上Kubelet组件采用非阻塞式长连接watch机制实时获取集群待调度Pod资源对象信息,一旦获悉集群中有新Pod资源调度到本节点,则通过apiserver获取etcd中相关Pod资源对象。

  8. api-server将与本节点相关的调度Pod资源信息返回给Kubelet的watch接口长连接。

  9. Kubelet在本节点运行新Pod中的容器进程。然后将Pod最终运行状态上报给api-server

  10. api-server更新etcd中Pod的最终状态。

三、节点kubelet生产Pod流程图

kubelet核心工作原理:通过不同的事件来驱动循环控制(SyncLoop)运行,围绕不同子模块生产出不同的、有关Pod的消息传入通道,来供其他的子模块消费,完成不同的行为(创建、更新和删除等)。

SyncLoop:是 kubelet 的主要同步循环,它会定期检查 pod 是否需要同步,并执行一些维护任务。函数会创建两个定时器,一个用于同步检查(syncTicker),另一个用于执行一些周期性的维护任务(housekeepingTicker)。在循环中,函数会检查是否有运行时错误,如果有则会进行指数退避,等待一段时间后再进行下一次循环。如果没有错误,则会重置退避时间,并调用 syncLoopIteration 函数进行同步操作。函数还会检查 resolv.conf 文件的限制,并记录同步循环的运行时间。

syncLoopIteration:是 Kubelet 同步 Pod 状态的核心循环。该方法会从多个 channel 中读取事件,根据事件类型调用不同的处理函数,最终更新 Pod 的状态。其中,configCh 是 Pod 配置的更新事件,plegCh 是 Pod 生命周期事件,syncCh 是需要同步的 Pod 集合,housekeepingCh 是清理过期 Pod 的事件。根据不同的事件类型,会调用不同的处理函数来更新 Pod 状态。需要注意的是,Kubelet 会将所有的 Pod 都视为新的 Pod,并进行 admission 过程,这可能会导致 Pod 被拒绝。此外,Kubelet 还会定期清理过期的 Pod。如果 Pod 的状态更新过程中出现错误,会记录日志并继续执行循环。

canAdmitPod和canRunPod:用于判断一个Pod是否可以被接受和运行,通过遍历kubelet中注册的运行Pod 各类Handler函数,只要其中一个Handler返回false,则输出false、Reason和Message日志。

四、容器运行时启动/运行容器流程图

  1. 当kubelet完成创建容器前的准备工作后,就通过RPC调用CRI接口创建容器

  2. 容器运行时创建沙箱(sandbox),可以理解为pause容器。pause容器是Pod中所有容器的根容器,在linux系统上承担着父进程责任,为容器提供方更多资源(IPC、Network、PID等)。通过namespace的资源隔离,允许同一Pod内的容器之间可以共享和互访

  3. 创建pause容器时,会调用容器网络插件CRI接口,为容器分配IP地址资源。CNI插件从本节点预定IP地址池中按序分配一个IP地址给容器

  4. 将分配后的相关信息保存到文件系统,确保主机上每个容器的IP地址的唯一性

  5. 一旦Pause容器完成初始化并处于active状态,则开始运行init容器

  6. 且如果有多个init容器,则严格按需启动。只有当前一个init容器正常退出了以后,才开始启动下一个init容器

  7. 拉取主业务容器运行需要的镜像,根据PodSpec中定义的镜像拉取

  8. 通过CRI创建主业务容器。kubelet使用PodSpec中定义的信息填充一个ContainerConifg数据结构(包括启动运行命令、业务镜像、标签资源、卷挂载、环境变量等),发送给CRI

  9. Docker反序列化数据结构,用于填充自身的配置信息

  10. 发送给Docker守护进程,在这个过程中,将一些元数据(容器类型、日志路径等)添加到容器中

  11. kubelet注册容器资源到CPU管理器,为容器分配CPU运行资源

  12. 使用容器启动命令运行主业务容器进程

  13. 待容器运行正常后执行容器预置Lifecycle Hooks函数

qrcode_for_gh_0412fa5a12f4_344 (5).jpg

订阅本文作者或关注容器魔方

获取更多云原生技术资讯

本文评论区回复“云原生”,即可添加小助手微信k8s2222

领取应季云原生资料一份

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。