内容简介:在kubernetes中,与存储相关的controller主要由三种:1、AttachDetachController,简称AD Controller,主要处理真实的与volume相关的操作;2、PersistentVolumeBinderController,其实就是PV Controller,主要负责pv和pvc的生命周期以及状态的切换;
在kubernetes中,与存储相关的controller主要由三种:
1、AttachDetachController,简称AD Controller,主要处理真实的与volume相关的操作;
2、PersistentVolumeBinderController,其实就是PV Controller,主要负责pv和pvc的生命周期以及状态的切换;
3、VolumeExpandController,主要负责volume的扩容操作。
PersistentVolumeBinderController
首先追踪PersistentVolumeBinderController方法,直接进入其Run方法。
很直观,依赖于三个goroutine:
1、resync;
2、volumeWorker;
3、claimWorker。
resync
进入resync,代码很简单,如下:
resync的主要作用就是不停获取pvc和pv的信息,传入到相应的缓存队列中去。这两个队列就是在volumeWorker和claimWorker用到的数据源的信息。
volumeWorker
volumeWorker通过for循环,不停获取resync缓冲的队列信息,对pv,即volume做相应的更新操作。主要实现方法 updateVolume
进入 updateVolume
方法,主要调用 syncVolume
方法,这个方法是整个volumeWorker的核心。工作流程如下:
1、如果volume没有被使用,更新PV的状态为 Available
;
2、volume已经被pvc持有:
- 如果volume还没有被绑定到pvc上,更新PV状态为
Available
; - 如果pvc信息为空,pv的状态不为
Released
且不为Failed
,更新PV状态为Released
,按照配置的回收策略执行pv的回收(调用reclaimVolume
方法); - pvc中指定volume的字段和当前volume一致,更新PV状态为
Bound
; - 如果都不满足,根据状态判断是执行回收策略还是解绑(unbindVolume)操作。
claimWorker
claimWorker的工作流程和volumeWorker类似,核心调用方法为 updateClaim-->syncClaim
,主要处理的是pvc生命周期中的各种状态:Pending、Bound以及Lost。不做过多赘述。
总结
PersistentVolumeBinderController的执行流程很清晰,依赖三个goroutine的协作,分别处理数据的获取、pv的生命周期的状态更新和pvc的生命周期的状态更新。整个逻辑中,没有对具体的volume做操作,更新的仅仅是kubernetes中定义的pv和pvc资源的信息,说白了就是etcd中的数据。具体干活的主要还是AttachDetachController,即AD Controller。
AttachDetachController
首先由 Run
方法进入AD Controller的启动方法,如下:
主要有以下几个步骤构成启动步骤:
1、同步各资源的信息,包括Pod、Node、PV、PVC;
2、调用 populateActualStateOfWorld
方法获取Node上Volume的信息;
3、调用 populateDesiredStateOfWorld
方法获取Pod需要对应的Volume信息;
4、 reconciler.Run
负责检查挂载状态,判断是否需要挂载或卸载(真正干活的);
5、 desiredStateOfWorldPopulator.Run
同步Pod与Volume的挂载信息,相应信息输送给 reconciler.Run
使用;
6、 pvcWorker
控制pvc的流控;
7、相应的信息注册到 metrics
中,供Prometheus采集数据使用。
populateActualStateOfWorld
populateActualStateOfWorld
方法主要处理的是Node与Volume之间的关系,主要作用是将Node Volume当前的状态存入到 actualStateOfWorld
中。主要方法如下:
主要步骤如下:
1、获取所有的Node信息;
2、一一遍历获取到的所有的Node,针对Node上已经attached
的Volume,分别置于已经attached状态和
in-user
状态,将Volume信息添加到
actualStateOfWorld
中,并将Node添加到
desiredStateOfWorld
中。
actualStateOfWorld
和
desiredStateOfWorld
的数据会在
reconciler.Run
使用。
populateDesiredStateOfWorld
populateDesiredStateOfWorld
方法主要处理的是Pod与Volume之间的关系,主要作用是将Pod Volume期望的状态添加到 desiredStateOfWorld
中去。和 populateActualStateOfWorld
类似,主要就是针对Volume做标记操作,并将相应的Pod信息缓存到 desiredStateOfWorld
中或者从 desiredStateOfWorld
中剔除不匹配的Pod信息。
desiredStateOfWorldPopulator.Run
desiredStateOfWorldPopulator.Run
方法通过不停的循环,调用 findAndAddActivePods
方法,通过获取所有的Pod,判断是否需要添加到 desiredStateOfWorld
中去。
reconciler.Run
前面几步主要的目的是为了获取Node Volume和Pod Volume的状态。其中,Node上的Volume是已经存在的,故称作为 actualStateOfWorld
,而Pod Volume是最终需要生效的资源,故称之为 desiredStateOfWorld
。 reconciler.Run
的作用就是通过不停获取 actualStateOfWorld
和 desiredStateOfWorld
状态,将Pod与Volume置于相对应的状态,保证磁盘的最终挂载成功或者卸载成功。主要方法如下:
不停循环调用 reconciliationLoopFunc
方法。
首先进入 reconcile
方法,这是真正干活的地方。
reconcile
使用了三个大的for循环,处理三类事件:
1、首先剔除需要解绑的Volume,调用 UnmountVolume
方法最终调用后台存储的解绑接口;
2、将需要Attach或者Mount的volumes调用后台存储接口执行Attach或者Mount操作;
3、将需要Detach或者Unmount的devices调用后台存储接口执行Detach或者Unmount操作。
其中,Attach操作指的是将Volume在Node上生成卷标,如常见的 /dev/xx
等。Mount操作包含了MountDevice和Mount两部分,其中,MountDevice将生成的卷标挂载成Node的路径,一般在 /var/lib/kubelet/xx/kubernetes.io/xx
下,依赖于不同的存储,Mount最终将MountDevice生成的路径和Pod需要使用的路径Mount起来,一般路径为 /var/lib/kubelet/pods/xx/volumes/xx
。
sync
方法主要完成Volume的后续操作。如果Volume未被成功绑定,将Volume进行重建或者解绑操作。
ExpandController
Kubernetes在1.8开始支持卷的扩容操作,1.11功能已经处于Beta阶段。主要代码如下:
pvcPopulator.Run
监听PVC的变化,只要PVC中Request字段的Storage值比Status中的大,即表示PVC容量发生了变化,需要扩容。此时,将相应的PV和PVC的信息缓存到
resizeMap
中去。如下:
syncResize
则是不停获取
resizeMap
中的数据,如果有变化,则调用
ExpandVolume
方法生成扩展动作,完成磁盘的扩容和PV、PVC的状态更新操作。代码如下:
总结
Kubernetes的存储主要针对Node、Pod、PV以及PVC四类资源。通过获取Node上Volume状态,将其与Pod中的Volume进行绑定,完成卷的加载。最终的绑定或者解绑等操作依赖的是后台的存储,包括内置的开源存储插件或者自己实现的插件(FlexVolume或者CSI)。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- Kafka 源码解析:日志数据存储机制
- 源码分析 RocketMQ DLedger 多副本存储实现
- SkyWalking 源码分析 —— JVM 指标的收集与存储
- 分布式消息队列 RocketMQ源码解析:Message存储
- 【提供源码包】高性能存储对象缓存 之【Memcached】
- Libra 源码分析:Libra 中数据存储的 Schema
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。