📢 注意,该文本非最终版本,正在更新中,版权所有,请勿转载!!
pod 是 k8s 调度的最小单位,也就是整个 k8s 的基础之一,那么如何创建 pod 就是我们今天的关键了。这也是为什么我将它放在第一章的原因。
想看 k8s 源码,我不知如何下手,肯定是挑最熟悉最基础的部分,pod 肯定就是其中之一。而且日常的使用也让我们更熟悉 pod 的生命周期,所以我准备从 pod 入手。那么我知道 作为操作 pod 的关键,那肯定就是代码的重点。于是我直接在代码中搜 ,找到对应文件名称为 的文件,应该就是我们今天的目标了。
然后开始聚焦,由于源码很多,不可能面面俱到,所以一开始我们就要设定范围,看什么,不看什么。而我们今天的目标就是 pod 的创建 其他都和我们没有关系。所以, 本身的初始化等其他细节我们看到就略过。
看源码之前都自己先提出一些问题,这些问题能帮助我们更快的进入状态,以便能快速定位到所需的关键。
寻码过程
由于是第一篇,我就把详细的寻找过程也写进来,给小白提供思路。可略过。
HandlePodAdditions
我第一眼发下的三个方法:
显然这些方法是用于操作 pod 的,再看了一眼注释没错,那我们先看 。
向上的引用链路
通过 IDE command+点击方法名称可以看到哪里调用了这个方法
我习惯先看向上的链路,也就是是谁调用的这个方法,整个链路很清晰:
然后简单查看一下 ,从这里我们就可以理解到,kubelet 本质处理模式就是事件循环处理。启动之后通过一个 来不断循环处理过来的事件,在 中根据不同的事件类型通过不同的方法处理事件,从而完成对 pod 的操作。下面的代码就描述了对于不同事件的处理:
方法内部的操作
然后再看方法的内部,精简后,主要逻辑就是下面这样:
在 中添加,在 中更新。也就是 有两个帮手: 和 。
那么接下来的 就“有你好看”了,通常第一次看源码容易迷失的大多数原因就来源于大量的代码被吓怕了。还是那句话,我是来看 pod 如何创建的。所以其他的什么 if 判断全部都可以扔掉,因为它们都是在处理 pod 的其他状态,对于创建无关。
根据这样的流程,你可以按照下面的路径开始理解和寻觅:
的注释写的很清楚,步骤 123… ,这就是我们所说的 pod 的创建过程,有关 sandbox 我们稍后文章再说,你可以简单理解为这里在创建 pod 所需要的环境。其中我们关注到两个步骤:
而创建容器的方法是 :
同样的,注释步骤很清晰,就是拉取镜像、创建镜像、启动,而这些最终的操作都落到了 具体会在 也就是我们常说的 了。
下面这些,这些就是不看源码所很难了解到的内部细节了,虽然不影响整体理解,但可以作为额外扩展来学习一下。
MirrorPod
在 创建的过程中出现了一个方法是: ,那么什么是 呢?
会为每个 静态 pod 创建一个 ,而静态 pod 直接由 管理,而不交给 。如果 静态 pod 出现 crashes 那么 会直接重启。而通过 看到的就是 。其主要功能还是为了k8s 内部一些实现和操作方便,所以我们平常不需要知道它,也就是为什么看源码才知道,平常不知道的原因。
如果还是不理解,我总结的不一定完整,建议看原文的参考文档:
设计上
事件循环,这是一个非常常见的设计,就是如同 一样,通过 来不断循环来读取事件,通过不同类型的事件来执行对应操作。这样的优点就是解耦,并且职责清晰,还能通过事件类型来不断地扩展相对应的功能。当然其中配合 go 中 channel 和 select 写起来更加舒适。
编码上
小细节,我觉得缺少函数式编程的耳濡目染很难写出这样的代码:在 方法中,启动容器被封装成了一个内置函数 通过这样来共享了 pod 的相关配置,如果抽离成一个新的函数,参数会很多,又要封装新的对象,不划算。故,这样的写法,值得学习和感染一下。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/141580.html