kubelet启动容器之存储挂载(三)

来源:互联网 发布:淘宝按销量排名规则 编辑:程序博客网 时间:2024/06/08 05:59

之前的两篇blog介绍了kubelet启动pod的过程,但没有介绍存储挂载的过程,这里还是补充说一下,
首先看kubelet启动时候

// Start volume managergo kl.volumeManager.Run(kl.sourcesReady, wait.NeverStop)

看Run启动方法,如下:

func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan struct{}) {    defer runtime.HandleCrash()    go vm.desiredStateOfWorldPopulator.Run(sourcesReady, stopCh)    glog.V(2).Infof("The desired_state_of_world populator starts")    glog.Infof("Starting Kubelet Volume Manager")    go vm.reconciler.Run(stopCh)    <-stopCh    glog.Infof("Shutting down Kubelet Volume Manager")}

这个里面最总要的是reconciler.Run,这个是个方法pkg/kubelet/volumemanager/reconciler/reconciler.go

func (rc *reconciler) Run(stopCh <-chan struct{}) {    // Wait for the populator to indicate that it has actually populated the desired state of world, meaning it has    // completed a populate loop that started after sources are all ready. After, there's no need to keep checking.    wait.PollUntil(rc.loopSleepDuration, func() (bool, error) {        rc.reconciliationLoopFunc(rc.populatorHasAddedPods())()        return rc.populatorHasAddedPods(), nil    }, stopCh)    wait.Until(rc.reconciliationLoopFunc(true), rc.loopSleepDuration, stopCh)}

通过定时任务定期同步,reconcile就是一致性函数,保存desired和actual状态一致。

func (rc *reconciler) reconcile() {//先确保应该解挂先解挂(unmounted),这个放在第一是因为这个存储可能将要被本主机上面其它的容器所使用,这里先释放挂载,如果实际上是挂载的,但理想状态不是挂载,则执行解挂操作。    for _, mountedVolume := range rc.actualStateOfWorld.GetMountedVolumes() {        if !rc.desiredStateOfWorld.PodExistsInVolume(mountedVolume.PodName, mountedVolume.VolumeName) {err := rc.operationExecutor.UnmountVolume(mountedVolume.MountedVolume, rc.actualStateOfWorld)...//确保存储是attached和mounted的状态,如果没有挂载主机则执行AttachVolume挂载操作,如果没有mount怎执行MountVolume操作。for _, volumeToMount := range rc.desiredStateOfWorld.GetVolumesToMount() {        volMounted, devicePath, err := rc.actualStateOfWorld.PodExistsInVolume(volumeToMount.PodName, volumeToMount.VolumeName)err := rc.operationExecutor.AttachVolume(volumeToAttach, rc.actualStateOfWorld)err := rc.operationExecutor.MountVolume(                rc.waitForAttachTimeout,                volumeToMount.VolumeToMount,                rc.actualStateOfWorld,                isRemount)}//最后确保应当解挂的存储解挂(detached 和unmounted),这个上面第一个的区别是,上面只是解挂unmounted,下面则是包括了存储detach和unmount两个步骤。for _, attachedVolume := range rc.actualStateOfWorld.GetUnmountedVolumes() {    if !rc.desiredStateOfWorld.VolumeExists(attachedVolume.VolumeName) &&

这样存储就可以加载到主机attach,并挂载到容器目录mount。
我觉得我这里还是严格区分一下这两个词,不然大家可能混淆,我称attach是加载,是把磁盘加载到主机,mount叫做挂载,包括格式化磁盘和mount到本地plugin目录下面。
那么上面的MountVolume、UnmountVolume这些operator是啥呢?是接口,这不是废话,kubernetes为了能兼容各种存储,每个存储都自己去实现这个方法,一个通用的flex pkg/volume/flexvolume/attacher.go。

func (a *flexVolumeAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {    // Mount only once.    alreadyMounted, err := prepareForMount(a.plugin.host.GetMounter(), deviceMountPath)    if err != nil {        return err    }    if alreadyMounted {        return nil    }    call := a.plugin.NewDriverCall(mountDeviceCmd)    call.Append(deviceMountPath)    call.Append(devicePath)    call.AppendSpec(spec, a.plugin.host, nil)    _, err = call.Run()    if isCmdNotSupportedErr(err) {        // Devicepath is empty if the plugin does not support attach calls. Ignore mountDevice calls if the        // plugin does not implement attach interface.        if devicePath != "" {            return (*attacherDefaults)(a).MountDevice(spec, devicePath, deviceMountPath, a.plugin.host.GetMounter())        } else {            return nil        }    }    return err}

这个里面就可以通过自己定义挂载解挂的二进制文件可执行文件去具体挂载或者解挂了。在kubelet启动地方加入参数–volume-plugin-dir=/usr/libexec/kubernetes/kubelet-plugins/volume/exec/就可以引入第三方存储插件了。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 袋装白糖成坨了怎么办 一袋子白糖硬了怎么办 粉饼上有一层油怎么办 葡萄后期氮肥施用过多怎么办 没洗的菜吃了怎么办 闻了汽油味头晕怎么办 碰到绿萝的汁液怎么办 吃了带农药水果怎么办 开槽模切一体机模切时开槽怎么办 柔版印刷走纸歪斜怎么办 美团外卖一天8单怎么办 单位显示器丢了怎么办员工赔 纸板板门起泡了怎么办 卖家要我开出质量问题证明怎么办 闲鱼买到的商品不符合描述怎么办 寄出去的东西碎了怎么办 闲鱼快递损坏了怎么办 寄快递东西坏了怎么办 快递邮寄东西坏了怎么办 快递被别人拆了怎么办 淘宝买的东西包装破损怎么办 寄血液被退回来怎么办 快递被安检扣了怎么办 淘宝原单退回运费怎么办 运输过程中包裹破损怎么办 天猫没收到货签收怎么办 收到的快递坏了怎么办 自寄的快递少了怎么办 邮的东西弄坏了怎么办 物流签收后发现货物损坏怎么办 发现客人损坏了酒店物品怎么办 东西坏了签收了怎么办 朋友圈贩卖三无产品你怎么办 付钱给微商没有保障怎么办 电镀锌钢带生锈怎么办 电机机油从空气滤芯里流出怎么办 把塑料皮套吃了怎么办 塑料框眼镜有点小了怎么办 出口纸箱打了钉怎么办 买房子交款单据丢了怎么办 买房子所有单据丢失怎么办