自定义存储插件-FlexvolumevsCsi介绍
从1.8版开始,Kubernetes Storage SIG停止接受树内卷插件,并建议所有存储提供商实施树外插件。目前有两种推荐的实现方式:容器存储接口(CSI)和Flexvolume。
Flexvolume
介绍
lexvolume使用户能够编写自己的驱动程序并在Kubernetes中添加对卷的支持。如果–enable-controller-attach-detach启用Kubelet选项,则供应商驱动程序应安装在每个Kubelet节点和主节点上的卷插件路径中。
Flexvolume是Kubernetes 1.8版本以后的GA特性。
先决条件
在插件路径中的所有节点上安装供应商驱动程序,–enable-controller-attach-detach设置为true,
安装插件的路径:\
动态插件发现
Flexvolume从v1.8开始支持动态检测驱动程序的能力。
系统初始化时不需要存在驱动程序,或者需要重新启动kubelet或控制器管理器,
则可以在系统运行时安装,升级/降级和卸载驱动程序。
自动插件安装/升级
安装和升级Flexvolume驱动程序的一种可能方式是使用DaemonSet。
插件详细信息
该插件希望为后端驱动程序实现以下调用。有些标注是可选的。
调用是从Kubelet和Controller管理器节点调用的。
只有当启用了“–enable-controller-attach-detach”Kubelet选项时,
才会从Controller-manager调用调用。
驱动程序调用模型
init
初始化驱动程序。在Kubelet&Controller manager初始化期间调用。
成功时,该函数返回一个功能映射,显示驱动程序是否支持每个Flexvolume功能。当前功能:
该字段是必需的,但为了向后兼容,默认值设置为true,即需要附加和分离。
init
attach
在给定主机上附加给定规范指定的卷。成功时,返回设备连接到节点的设备路径。
如果启用了“–enable-controller-attach-detach”Kubelet选项,
则Nodename参数才是有效/相关的。来自Kubelet&Controllermanager。
此调出不会传递Flexvolume规范中指定的“secrets”。如果您的驱动程序需要secrets,
请不要执行此调出,而是使用“mount”调出并在该调出中执行attach和调用。
attach
Detach
从Kubelet节点分离卷。只有在启用启用了“–enable-controller-attach-detach”Kubelet选项时
Nodename参数才是有效/相关的。Kubelet & Controller manager进行调用
detach
Wait for attach
等待卷连接到远程节点上。成功后,返回设备的路径。从Kubelet & Controller manager进行调用,超时时间为10毫秒
waitforattach
Volume is Attached
检查节点上是否连接了卷。从Kubelet & Controller manager进行调用.
isattached
Mount device
挂载设备将设备挂载到全局路径,然后各个容器可以动态绑定,只能从kubelet调用。
此调出不会传递Flexvolume规范中指定的“secrets”。如果您的驱动程序需要secrets,
请不要执行此调出,而是使用“mount”调出并在该调出中执行attach和调用。
mountdevice
Unmount device
取消所有挂载,一旦所有绑定挂载已被卸载,就会调用它。只能从Kubelet中调用。
unmountdevice
Mount
将卷挂载到挂载目录。此调出默认为绑定挂载实现attach和mount-device调出的驱动程序。只能从Kubelet中调用。
mount
Unmount
卸载卷,此调出默认为绑定挂载实现附加和挂载设备调出的驱动程序。只能从Kubelet中调用。
unmount
有关如何编写简单的flexvolume驱动程序的简单示例
驱动输出
Flexvolume希望驱动程序以下列格式返回操作状态。
{ "status": "", "message": "", "device": "" "volumeName": "" "attached": "capabilities": { "attach": } }
默认json选项
除了用户在FlexVolumeSource的Options字段中指定的标志之外,还将以下标志传递给可执行文件。注意:秘密只传递给“mount/umount”调出
Flexvolume的示例
CSI
介绍
CSI提供了一个单一的界面,存储供应商可以实现它们的存储解决方案,以跨多个不同的容器编排器工作,并且卷插件被设计为out-of-tree。这是一项巨大的努力,CSI的全面实施需要几个季度的时间,并且需要立即为存储供应商提供解决方案,以继续添加卷插件。
它使许多不同类型的存储系统能够:
- 在需要时自动创建存储。
- 使存储在任何计划的地方都可用。
- 不再需要时自动删除存储。
创建csi的原因
Kubernetes卷插件目前是“in-tree”,意味着它们与核心kubernetes二进制文件进行链接,编译,构建和发布。
为Kubernetes(卷插件)添加对新存储系统的支持需要将代码检入核心Kubernetes存储库。
但是与Kubernetes发布流程对许多插件开发者来说是痛苦的。
现有的Flex Volume插件试图通过暴露外部卷插件的基于exec的API来解决这个问题。
尽管它使第三方存储供应商能够在树外编写驱动程序,但为了部署第三方驱动程序文件,
它需要访问节点和主机的根文件系统。
除了难以部署之外,Flex并没有解决插件依赖的痛苦:插件往往有很多外部需求(例如,在挂载和文件系统工具上)。
假定这些依赖关系在底层主机操作系统上可用,而这往往不是这种情况(并且安装它们需要访问节点机器的根文件系统)。
CSI解决了所有这些问题,使存储插件能够通过标准的Kubernetes基元进行树外,容器化,部署,
并通过用户所熟悉并喜爱的Kubernetes存储原语(PersistentVolumeClaims,PersistentVolumes,StorageClasses)进行使用。
用法
启用csi
csi在1.9是alpha版本,要想使用它,设置以下参数:
API server binary:
–feature-gates=CSIPersistentVolume=true –runtime-config=storage.k8s.io/v1alpha1=trueAPI server binary and kubelet binaries:
–feature-gates=MountPropagation=true –allow-privileged=true预配置volume
预先配置的驱动程序的工作方式与之前一样,管理员将创建一个PersistentVolume规范,该规范将描述要使用的卷。PersistentVolume规范需要根据你的驱动程序进行设置,这里的区别在于有一个叫做csi的新部分需要相应地设置。请参阅Kubernetes关于CSI卷的文档(LINK TBD)。
以下是由CSI驱动程序管理的预配置卷的PersistentVolume规范示例:
apiVersion: v1 kind: PersistentVolume metadata: name: manually-created-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain csi: driver: com.example.team/csi-driver volumeHandle: existingVolumeName readOnly: false
动态预配
为了设置系统进行动态配置,管理员需要设置StorageClass指向CSI驱动程序的外部配置器并指定驱动程序所需的任何参数。这是一个StorageClass的例子:
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: fast-storage provisioner: com.example.team/csi-driver parameters: type: pd-ssd
提供者:必须设置为CSI驱动程序的名称
参数:必须包含特定于CSI驱动程序的任何参数。
然后用户可以使用这个StorageClass 创建一个PersistentVolumeClaim,如下所示:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: request-for-storage spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi storageClassName: fast-storage
在k8s中使用
本节介绍如何部署csi驱动程序到k8s 1.9集群
在Kubernetes 1.9中,有三个新的组件加上kubelet使CSI驱动为Kubernetes提供存储。
新组件是边车容器,负责与Kubernetes和CSI驱动沟通,监控events从而适时调用csi接口。
external-attacher
external-attacher是一个边车容器,用于监视Kubernetes VolumeAttachment对象并触发针对驱动程序端点的CSI ControllerPublish和ControllerUnpublish操作。在撰写本文时,外部助理不支持领导者选举,因此每个CSI车手只能运行一次。欲了解更多信息,请阅读附加和分离。
请注意,即使这称为外部附件,它的功能是调用CSI API调用ControllerPublish和ControllerUnpublish。这些调用很可能发生在不是将要安装卷的节点中。因此,许多CSI驱动程序不支持这些调用,而是在要安装的节点上的kubelet所完成的CSI NodePublish和NodeUnpublish调用中执行attach / detach和mount / unmount 。
external-provisioner
external-provisioner是一个Sidecar容器,用于监视Kubernetes PersistentVolumeClaim对象并触发针对驱动程序端点的CSI CreateVolume和DeleteVolume操作。有关更多信息,请阅读供应和删除。
driver-registrar
driver-registrar是一个边车容器,它用kubelet注册CSI驱动程序,并将驱动程序自定义NodeId添加到Kubernetes Node API对象上的标签。它通过与CSI驱动程序上的身份服务进行通信并调用CSI GetNodeId操作来完成此操作。驱动程序注册器必须具有通过环境变量设置的节点的Kubernetes名称,KUBE_NODE_NAME如下所示:
- name: csi-driver-registrar imagePullPolicy: Always image: docker.io/k8scsi/driver-registrar args: - "--v=5" - "--csi-address=$(ADDRESS)" env: - name: ADDRESS value: /csi/csi.sock - name: KUBE_NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: socket-dir mountPath: /csi
pod配置
volumeMounts: - name: socket-dir mountPath: /csi - name: mountpoint-dir mountPath: /var/lib/kubelet/pods mountPropagation: "Bidirectional" volumes: - name: socket-dir hostPath: path: /var/lib/kubelet/plugins/csi-hostpath type: DirectoryOrCreate - name: mountpoint-dir hostPath: path: /var/lib/kubelet/pods type: Directory
rbac配置
kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: csi-hostpath-role rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["create", "delete", "get", "list", "watch", "update"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: [""] resources: ["nodes"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: ["storage.k8s.io"] resources: ["volumeattachments"] verbs: ["get", "list", "watch", "update"]