当创建一个Pod后,kubernetes会发生什么?
一、Pod简介
-
Pod是kubernetes集群管理的最小调度单位,是一个逻辑概念,物理上不存在。
-
一个pod中可以包含一个或多个容器,且同一个pod中的所有容器共享网络、存储、进程等。
二、Pod创建调度流程图
Pod创建流程图说明:
-
用户使用通过kubectl客户端发起创建Pod资源对象请求至api-server。
-
api-server对请求用户鉴权、准入控制操作,然后将该请求资源事件写入到etcd存储中。
-
schduler组件采用非阻塞式长连接watch机制实时获取集群待调度Pod资源对象信息(包括用户新建、各控制器为补足工作负载期望副本实例数而创建的Pod)和当前集群Node节点状态信息,一旦获悉集群中有新Pod资源资源需要被调度,则通过api-server获取etcd中相关Pod资源对象信息。
-
api-server将相关待调度的Pod资源信息返回给Scheduler的watch接口长连接
-
scheduler根据自身算法,计算出Pod与最终生产Pod的node节点的绑定关系,将该Pod绑定结果事件通过api-server存储在Etcd中。
-
api-server更新etcd中Pod的绑定信息。
-
各Node节点上Kubelet组件采用非阻塞式长连接watch机制实时获取集群待调度Pod资源对象信息,一旦获悉集群中有新Pod资源调度到本节点,则通过apiserver获取etcd中相关Pod资源对象。
-
api-server将与本节点相关的调度Pod资源信息返回给Kubelet的watch接口长连接。
-
Kubelet在本节点运行新Pod中的容器进程。然后将Pod最终运行状态上报给api-server
-
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日志。
四、容器运行时启动/运行容器流程图
-
当kubelet完成创建容器前的准备工作后,就通过RPC调用CRI接口创建容器
-
容器运行时创建沙箱(sandbox),可以理解为pause容器。pause容器是Pod中所有容器的根容器,在linux系统上承担着父进程责任,为容器提供方更多资源(IPC、Network、PID等)。通过namespace的资源隔离,允许同一Pod内的容器之间可以共享和互访
-
创建pause容器时,会调用容器网络插件CRI接口,为容器分配IP地址资源。CNI插件从本节点预定IP地址池中按序分配一个IP地址给容器
-
将分配后的相关信息保存到文件系统,确保主机上每个容器的IP地址的唯一性
-
一旦Pause容器完成初始化并处于active状态,则开始运行init容器
-
且如果有多个init容器,则严格按需启动。只有当前一个init容器正常退出了以后,才开始启动下一个init容器
-
拉取主业务容器运行需要的镜像,根据PodSpec中定义的镜像拉取
-
通过CRI创建主业务容器。kubelet使用PodSpec中定义的信息填充一个ContainerConifg数据结构(包括启动运行命令、业务镜像、标签资源、卷挂载、环境变量等),发送给CRI
-
Docker反序列化数据结构,用于填充自身的配置信息
-
发送给Docker守护进程,在这个过程中,将一些元数据(容器类型、日志路径等)添加到容器中
-
kubelet注册容器资源到CPU管理器,为容器分配CPU运行资源
-
使用容器启动命令运行主业务容器进程
-
待容器运行正常后执行容器预置Lifecycle Hooks函数
- 点赞
- 收藏
- 关注作者
评论(0)