现在的位置: 首页 > 云计算 > 正文

Flexvolume是什么?如何使用

2020年02月19日 云计算 ⁄ 共 2712字 ⁄ 字号 评论关闭

  Flexvolume 是 Volume Plugins 的一个扩展,主要实现 Attach/Detach/Mount/Unmount 这些接口。我们知道这些功能本是由 Volume Plugins 实现的,但是对于某些存储类型,我们需要将其扩展到 Volume Plugins 以外,所以我们需要把接口的具体实现放到外面。

  我们可以看到,Volume Plugins 其实包含了一部分 Flexvolume 的实现代码,但这部分代码其实只有一个 “Proxy”的功能。

  比如当 AD Controller 调用插件的一个 Attach 时,它首先会调用 Volume Plugins 中 Flexvolume 的 Attach 接口,但这个接口只是把调用转到相应的 Flexvolume 的 Out-Of-Tree 实现上。

  Flexvolume 是可被 Kubelet 驱动的可执行文件,每一次调用相当于执行一次 shell 的 ls 这样的脚本,都是可执行文件的命令行调用,因此它不是一个常驻内存的守护进程。

  Flexvolume 的 Stdout 作为 Kubelet 调用的返回结果,这个结果需要是 JSON 格式。

  Flexvolume 默认的存放地址为 “/usr/libexec/kubernetes/kubelet-plugins/volume/exec/alicloud~disk/disk”。

  下面是一个命令格式和调用的实例。

  Flexvolume 的接口介绍

  Flexvolum 包含以下接口:

  init: 主要做一些初始化的操作,比如部署插件、更新插件的时候做 init 操作,返回的时候会返回刚才我们所说的 DriveCapabilities 类型的数据结构,用来说明我们的 Flexvolume 插件有哪些功能;

  GetVolumeName: 返回插件名 ;

  Attach: 挂载功能的实现。根据 --enable-controller-attach-detach 标签来决定是由 AD Controller 还是 Kubelet 来发起挂载操作 ;

  WaitforAttach: Attach 经常是异步操作,因此需要等待挂载完成,才能需要进行下面的操作 ;

  MountDevice:它是 mount 的一部分。这里我们将 mount 分为 MountDevice 和 SetUp 两部分,MountDevice 主要做一些简单的预处理工作,比如将设备格式化、挂载到 GlobalMount 目录中等;

  GetPath:获取每个 Pod 对应的本地挂载目录;

  Setup:使用 Bind 方式将 GlobalPath 中的设备挂载到 Pod 的本地目录;

  TearDown、 UnmountDevice 、 Detach 实现的是上面一些借口的逆过程;

  ExpandVolumeDevice:扩容存储卷,由 Expand Controller 发起调用;

  NodeExpand: 扩容文件系统,由 Kubelet 发起调用。

  上面这些接口不一定需要全部实现,如果某个接口没有实现的话,可以将返回结果定义成:

  {

  "status":"Not supported",

  "message":"error message"

  }

  告诉调用者没有实现这个接口。此外,Volume Plugins 中的 Flexvolume 接口除了作为一个 Proxy 外,它也提供了一些默认实现,比如 Mount 操作。所以如果你的 Flexvolume 中没有定义该接口,该默认实现就会被调用。

  在定义 PV 时可以通过 secretRef 字段来定义一些 secret 的功能。比如挂载时所需的用户名和密码,就可以通过 secretRef 传入。

  Flexvolume 的挂载分析

  从挂载流程和卸载流程两个方向来分析 Flexvolume 的挂载过程。

  我们首先看 Attach 操作,它调用了一个远端的 API 把我们的 Storage 挂载到目标节点中的某个设备上去。然后通过 MountDevice 将本地设备挂载到 GlobalPath 中,同时也会做一些格式化这样的操作。Mount 操作(SetUp),它会把 GlobalPath 挂载 PodPath 中,PodPath 就是 Pod 启动时所映射的一个目录。

  下图给出了一个例子,比如我们一个云盘,其 Volume ID 为 d-8vb4fflsonz21h31cmss,在执行完 Attach 和 WaitForAttach 操作之后,就会将其挂载到目标节点上的 /dec/vdc 设备中。执行 MountDevice 之后,就会把上述设备格式化,挂载到一个本地的 GlobalPath 中。而执行完 Mount 之后,就会将 GlobalPath 映射到 Pod 相关的一个子目录中。最后执行 Bind 操作,将我们的本地目录映射到容器中。这样完成一次挂载过程。

  卸载流程就是一个逆过程。上述过程描述的是一个块设备的挂载过程,对于文件存储类型,就无需 Attach、MountDevice 操作,只需要 Mount 操作,因此文件系统的 Flexvolume 实现较为简单,只需要 Mount 和 Unmount 过程即可。

  Flexvolume 的代码示例

  其中主要实现的是 init()、doMount()、doUnmount() 方法。在执行该脚本的时候对传入的参数进行判断来决定执行哪一个命令。

  在 Github 上还有很多 Flexvolume 的示例,大家可以自行参考查阅。阿里云提供了一个 Flexvolume 的实现 ,有兴趣的可以参考一下。

  Flexvolume 的使用

  下图给出了一个 Flexvolume 类型的 PV 模板。它和其它模板实际上没有什么区别,只不过类型被定义为 flexVolume 类型。flexVolume 中定义了 driver、fsType、options。

  driver 定义的是我们实现的某种驱动,比如图中的是 aliclound/disk,也可以是 aliclound/nas 等;

  fsType 定义的是文件系统类型,比如 “ext4”;

  options 包含了一些具体的参数,比如定义云盘的 id 等。

  我们也可以像其它类型一样,通过 selector 中的 matchLabels 定义一些筛选条件。同样也可以定义一些相应的调度信息,比如定义 zone 为 cn-shenzhen-a。

  下面是一个具体的运行结果。在 Pod 内部我们挂载了一个云盘,其所在本地设备为 /dev/vdb。通过 mount | grep disk 我们可以看到相应的挂载目录,首先它会将 /dev/vdb 挂载到 GlobalPath 中;其次会将 GlobalPath 通过 mount 命令挂载到一个 Pod 所定义的本地子目录中去;最后会把该本地子目录映射到 /data 上。

抱歉!评论已关闭.