支持超过80个存储驱动器的多厂商CSI插件
项目描述
Ember CSI
支持超过80个存储驱动器的多厂商CSI插件驱动程序,通过单个插件提供块
和挂载
存储到容器编排系统。
- 自由软件:Apache软件许可证2.0
- 文档:待定
功能
此CSI驱动程序与最新的CSI规范保持同步,包括最近引入的新快照功能。
目前支持的功能包括
- 创建块卷
- 创建快照
- 从快照创建块卷
- 删除块卷
- 删除快照
- 分页列出卷
- 分页列出快照
- 附加卷
- 卸载卷
- 报告存储容量
- 探测节点
- 检索插件信息
运行时依赖
此驱动程序要求系统已安装Cinder v11.0(OSP-12/Pike),如何实现留由安装程序决定,因为有多种实现方式
- 从OSP仓库
- 从RDO仓库
- 从github
- 从其他仓库
任何其他基本要求在从PyPi安装时已被ember-csi
处理。
除了基本依赖项之外,还有一些驱动程序有额外的要求,必须满足这些要求才能正确运行驱动程序以及/或附件/卸载操作,就像在Cinder中一样。
一些用于Controller服务的Python依赖项包括
- DRBD:dbus和drbdmanage
- HPE 3PAR:python-3parclient
- Kaminario:krest
- Pure:purestorage
- Dell EMC VMAX, IBM DS8K:pyOpenSSL
- HPE LeftHand:python-lefthandclient
- Fujitsu Eternus DX:pywbem
- IBM XIV: pyxcli
- RBD: rados 和 rbd
- Dell EMC VNX: storops
- Violin: vmemclient
- INFINIDAT: infinisdk, capacity, infy.dtypes.wwn, infi.dtypes.iqn
其他后端可能也需要额外的包,例如 CentOS/RHEL 上的 LVM 需要 targetcli
包,因此请咨询您的硬件供应商。
除了控制器要求外,通常还需要节点服务器的需求,以便根据访问存储的连接来处理卷的附加和分离。例如
- iSCSI: iscsi-initiator-tools 和 device-mapper-multipath
- RBD/Ceph: ceph-common 包
安装
首先我们需要安装 Cinder Python 包,例如在 CentOS 上从 RDO 安装
$ sudo yum install -y centos-release-openstack-pike
$ sudo yum install -y openstack-cinder python-pip
然后我们只需要安装 ember-csi
包
$ sudo pip install ember-csi
现在我们应该安装后端所需的任何附加包。
对于 iSCSI 后端,我们需要安装
$ sudo yum install iscsi-initiator-utils
$ sudo yum install device-mapper-multipath
$ sudo mpathconf --enable --with_multipathd y --user_friendly_names n --find_multipaths y
对于 RBD,我们还需要一个特定的包
$ sudo yum install ceph-common
配置
CSI 驱动程序通过环境变量进行配置,任何没有默认值的值都是必需的。
名称 | 角色 | 描述 | 默认值 | 示例 |
---|---|---|---|---|
CSI_ENDPOINT |
all | 绑定服务的 IP 和端口 | [::]:50051 | 192.168.1.22:50050 |
CSI_MODE |
all | 服务应执行的角色:控制器、节点、全部 | all | 控制器 |
X_CSI_SPEC_VERSION |
all | 要运行的 CSI 规范版本。支持 v0.2 和 v1.0 | v0.2.0 | 0.2.0 |
X_CSI_STORAGE_NW_IP |
节点 | 连接到存储的节点中的 IP 地址 | 从节点的 fqdn 解析的 IP | 192.168.1.22 |
X_CSI_NODE_ID |
节点 | 节点用于向控制器标识自己的 ID | 节点的 fqdn | csi_test_node |
X_CSI_PERSISTENCE_CONFIG |
all | cinderlib 元数据持久化插件的配置。 |
{"storage": "crd", "namespace": "default"} | {"storage": "db", "connection": "mysql+pymysql://root:stackdb@192.168.1.1/cinder?charset=utf8"} |
X_CSI_EMBER_CONFIG |
all | 全局 Ember 和 cinderlib 配置 |
{"project_id": "ember-csi.io", "user_id": "ember-csi.io", "root_helper": "sudo", "request_multipath": false, "plugin_name": "", "file_locks_path": "/var/lib/ember-csi/locks", "name": "io.ember-csi", "grpc_workers": 30, "enable_probe": false, "slow_operations: true, "disabled": []} | {"project_id":"k8s project","user_id":"csi driver","root_helper":"sudo","plugin_name":"external-ceph","disabled":["snapshot","clone"]} |
X_CSI_BACKEND_CONFIG |
控制器 | 驱动程序配置 | {"name": "rbd", "driver": "RBD", "rbd_user": "cinder", "rbd_pool": "volumes", "rbd_ceph_conf": "/etc/ceph/ceph.conf", "rbd_keyring_conf": "/etc/ceph/ceph.client.cinder.keyring"} | |
X_CSI_DEFAULT_MOUNT_FS |
节点 | 在 publish 调用中缺少时的默认挂载文件系统 | ext4 | btrfs |
X_CSI_SYSTEM_FILES |
all | 所有必需的存储驱动程序特定文件归档为 tar、tar.gz 或 tar.bz2 格式 | /path/to/etc-ceph.tar.gz | |
X_CSI_DEBUG_MODE |
all | 要使用的调试模式(rpdb、pdb)。默认禁用。 | rpdb | |
X_CSI_ABORT_DUPLICATES |
all | 如果我们要取消或队列(默认)重复请求。 | false | true |
目前唯一经过测试的角色是默认角色,其中控制器和节点服务程序在同一服务中执行(CSI_MODE=all
),其他模式目前可能存在问题。
X_CSI_SYSTEM_FILES 变量应指向 Ember CSI 驱动程序文件系统中可访问的 tar/tar.gz/tar.bz2 文件。存档的内容将被提取到 '/'. 必须在启动驱动程序之前,由具有特权的操作员/管理员等可信用户创建存档。
例如
$ tar cvf ceph-files.tar /etc/ceph/ceph.conf /etc/ceph/ceph.client.cinder.keyring
tar: Removing leading `/' from member names
/etc/ceph/ceph.conf
/etc/ceph/ceph.client.cinder.keyring
$ export X_CSI_SYSTEM_FILES=`pwd`/ceph-files.tar
启动插件
一旦我们安装了 ember-csi
和所需的依赖项(对于后端和连接类型),我们只需以可以无密码 sudo 的用户运行 ember-csi
服务
$ ember-csi
测试插件
在 examples
目录中,有几个运行 Ember CSI 插件的例子,包括裸金属部署和驱动程序的容器化版本。
在所有情况下,我们都必须先运行插件才能测试它,为此,我们需要在启动插件之前检查提供的配置。默认情况下,所有示例都在端口 50051 上运行服务。
裸金属
例如,为了测试我们的开发环境中使用 LVM 驱动的功能,我们只需从 ember-csi
项目的根目录运行以下命令
注意:iscsi IP 地址在 lvm 环境文件中自动分配。如果需要,您可以更改这些 IP 地址
$ cd tmp
$ sudo dd if=/dev/zero of=ember-volumes bs=1048576 seek=22527 count=1
$ lodevice=`sudo losetup --show -f ./ember-volumes`
$ sudo pvcreate $lodevice
$ sudo vgcreate ember-volumes $lodevice
$ sudo vgscan --cache
$ cd ../examples/baremetal
$ ./run.sh lvm
py27 develop-inst-nodeps: /home/geguileo/code/ember-csi
py27 installed: ...
___ summary ___
py27: skipped tests
congratulations :)
Starting Ember CSI v0.0.2 (cinderlib: v0.2.1, cinder: v11.1.2.dev5, CSI spec: v0.2.0)
Supported filesystems are: fat, ext4dev, vfat, ext3, ext2, msdos, ext4, hfsplus, cramfs, xfs, ntfs, minix, btrfs
Running backend LVMVolumeDriver v3.0.0
Debugging is OFF
Now serving on [::]:50051...
还有一个使用名为 "cinder" 的用户和 "volumes" 存储池测试 Ceph 集群的例子。由于 Cinder 的限制,对于 Ceph/RBD 后端,我们需要在 /etc/ceph
中具有凭证和配置才能使其正常工作
$ cd examples/baremetal
$ ./run.sh rbd
Starting Ember CSI v0.0.2 (cinderlib: v0.2.1, cinder: v11.1.2.dev5, CSI spec: v0.2.0)
Supported filesystems are: fat, ext4dev, vfat, ext3, ext2, msdos, ext4, hfsplus, cramfs, xfs, ntfs, minix, btrfs
Running backend LVMVolumeDriver v3.0.0
Debugging is OFF
Now serving on [::]:50051...
还有一个 XtremIO 示例,它只需要 iSCSI 连接包。
容器化
项目包含一个 Dockerfile
示例,该文件已用于创建在 Docker Hub 中可用的 akrog/ember-csi
容器。
有两个 bash 脚本,每个示例一个,它们将在容器上运行 CSI 驱动程序。请注意,容器需要以特权模式运行以挂载卷。
对于 RBD 示例,我们需要将我们的 "ceph.conf" 和 "ceph.client.cinder.keyring" 文件复制到示例的 docker
目录中,假设我们使用的是 "cinder" 用户,并替换现有的文件
$ cd examples/docker
$ ./rbd.sh
Starting Ember CSI v0.0.2 (cinderlib: v0.2.1, cinder: v11.1.0, CSI spec: v0.2.0)
Supported filesystems are: cramfs, minix, ext3, ext2, ext4, xfs, btrfs
Running backend LVMVolumeDriver v3.0.0
Debugging is ON with rpdb
Now serving on [::]:50051...
CSC
现在,我们的服务已经运行,我们可以使用 CSC 工具 来运行模拟容器编排系统的命令。
由于最近 CSI 规范的变化,并非所有命令都可用,因此您将无法测试快照命令。
检查插件信息
$ csc identity plugin-info -e tcp://127.0.0.1:50051
"io.ember-csi" "0.0.2" "cinder-driver"="RBDDriver" "cinder-driver-supported"="True" "cinder-driver-version"="1.2.0" "cinder-version"="11.1.0" "cinderlib-version"="0.2.1" "persistence"="DBPersistence"
检查节点 ID
$ csc node get-id -e tcp://127.0.0.1:50051
localhost.localdomain
$ hostname -f
localhost.localdomain
检查当前后端容量
$ csc controller get-capacity -e tcp://127.0.0.1:50051
24202140712
创建卷
$ csc controller create-volume --cap SINGLE_NODE_WRITER,block --req-bytes 2147483648 disk -e tcp://127.0.0.1:50051
"5ee5fd7c-45cd-44cf-af7b-06081f680f2c" 2147483648
列出卷
$ csc controller list-volumes -e tcp://127.0.0.1:50051
"5ee5fd7c-45cd-44cf-af7b-06081f680f2c" 2147483648
存储所有后续调用中的卷 ID
$ vol_id=`csc controller list-volumes -e tcp://127.0.0.1:50051|awk '{ print gensub("\"","","g",$1)}'`
将卷附加到裸金属上的 tmp/mnt/publish
作为块设备
$ touch tmp/mnt/{staging,publish}
$ csc controller publish --cap SINGLE_NODE_WRITER,block --node-id `hostname -f` $vol_id -e tcp://127.0.0.1:50051
"5ee5fd7c-45cd-44cf-af7b-06081f680f2c" "connection_info"="{\"connector\": {\"initiator\": \"iqn.1994-05.com.redhat:aa532823bac9\", \"ip\": \"127.0.0.1\", \"platform\": \"x86_64\", \"host\": \"localhost.localdomain\", \"do_local_attach\": false, \"os_type\": \"linux2\", \"multipath\": false}, \"conn\": {\"driver_volume_type\": \"rbd\", \"data\": {\"secret_uuid\": null, \"volume_id\": \"5ee5fd7c-45cd-44cf-af7b-06081f680f2c\", \"auth_username\": \"cinder\", \"secret_type\": \"ceph\", \"name\": \"volumes/volume-5ee5fd7c-45cd-44cf-af7b-06081f680f2c\", \"discard\": true, \"keyring\": \"[client.cinder]\\n\\tkey = AQCQPetaof03IxAAoHZJD6kGxiMQfLdn3QzdlQ==\\n\", \"cluster_name\": \"ceph\", \"hosts\": [\"192.168.1.22\"], \"auth_enabled\": true, \"ports\": [\"6789\"]}}}"
$ csc node stage --pub-info connection_info="irrelevant" --cap SINGLE_NODE_WRITER,block --staging-target-path `realpath tmp/mnt/staging` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc node publish --cap SINGLE_NODE_WRITER,block --pub-info connection_info="irrelevant" --staging-target-path `realpath tmp/mnt/staging` --target-path `realpath tmp/mnt/publish` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
将卷附加到容器上的 tmp/mnt/publish
作为块设备
$ touch tmp/mnt/{staging,publish}
$ csc controller publish --cap SINGLE_NODE_WRITER,block --node-id `hostname -f` $vol_id -e tcp://127.0.0.1:50051
"5ee5fd7c-45cd-44cf-af7b-06081f680f2c" "connection_info"="{\"connector\": {\"initiator\": \"iqn.1994-05.com.redhat:aa532823bac9\", \"ip\": \"127.0.0.1\", \"platform\": \"x86_64\", \"host\": \"localhost.localdomain\", \"do_local_attach\": false, \"os_type\": \"linux2\", \"multipath\": false}, \"conn\": {\"driver_volume_type\": \"rbd\", \"data\": {\"secret_uuid\": null, \"volume_id\": \"5ee5fd7c-45cd-44cf-af7b-06081f680f2c\", \"auth_username\": \"cinder\", \"secret_type\": \"ceph\", \"name\": \"volumes/volume-5ee5fd7c-45cd-44cf-af7b-06081f680f2c\", \"discard\": true, \"keyring\": \"[client.cinder]\\n\\tkey = AQCQPetaof03IxAAoHZJD6kGxiMQfLdn3QzdlQ==\\n\", \"cluster_name\": \"ceph\", \"hosts\": [\"192.168.1.22\"], \"auth_enabled\": true, \"ports\": [\"6789\"]}}}"
$ csc node stage --pub-info connection_info="irrelevant" --cap SINGLE_NODE_WRITER,block --staging-target-path /mnt/staging $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc node publish --cap SINGLE_NODE_WRITER,block --pub-info connection_info="irrelevant" --staging-target-path /mnt/staging --target-path /mnt/publish $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
在裸金属上分离卷
$ csc node unpublish --target-path `realpath tmp/mnt/publish` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc node unstage --staging-target-path `realpath tmp/mnt/staging` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc controller unpublish --node-id `hostname -f` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
在容器上分离卷
$ csc node unpublish --target-path /mnt/publish $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc node unstage --staging-target-path /tmp/mnt/staging $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc controller unpublish --node-id `hostname -f` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
删除卷
$ csc controller delete-volume $vol_id -e tcp://127.0.0.1:50051
如果我们想使用挂载接口而不是块接口,我们也可以这样做,确保我们创建目录而不是文件,并且如果我们想使用 ext4
文件系统,可以将 block
词汇替换为 mount,ext4
。
例如,以下是在裸金属上附加的命令
$ mkdir tmp/mnt/{staging_dir,publish_dir}
$ csc controller publish --cap SINGLE_NODE_WRITER,mount,ext4 --node-id `hostname -f` $vol_id -e tcp://127.0.0.1:50051
$ csc node stage --pub-info connection_info="irrelevant" --cap SINGLE_NODE_WRITER,mount,ext4 --staging-target-path `realpath tmp/mnt/staging_dir` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
$ csc node publish --pub-info connection_info="irrelevant" --cap SINGLE_NODE_WRITER,mount,ext4 -staging-target-path `realpath tmp/mnt/staging_dir` --target-path `realpath tmp/mnt/publish_dir` $vol_id -e tcp://127.0.0.1:50051
5ee5fd7c-45cd-44cf-af7b-06081f680f2c
可操作模式
CIS 规范定义了 CSI 驱动程序可以支持的一系列 AccessModes
,例如单个写入者、单个读取者、多个写入者、单个写入者和多个读取者。
这个 CSI 驱动程序目前只支持 SINGLE_MODE_WRITER
,尽管它也会以 SINGLE_MODE_READER_ONLY
模式成功运行,并将其作为读写挂载。
调试
调试的第一个工具是显示 ember-CSI 所使用的驱动程序代码的详细信息的日志。我们可以使用 X_CSI_EMBER_CONFIG
环境变量启用 INFO 或 DEBUG 日志。
要启用日志,默认为 INFO 级别,我们必须将 disable_logs
键设置为 false
。如果我们想以 DEBUG 级别启用它们,我们还需要将 debug
设置为 true
。
对于裸金属,启用 DEBUG 日志级别可以这样做
export X_CSI_EMBER_CONFIG={"project_id":"io.ember-csi","user_id":"io.ember-csi","root_helper":"sudo","plugin_name": "io.ember-csi","disable_logs":false,"debug":true}
对于容器,我们只需将环境变量添加到文件中,然后使用 --env-file
或在命令行中添加它(使用 -e
)导入我们的运行。
在这两种情况下,都不应包含 export
命令
X_CSI_EMBER_CONFIG={"project_id":"io.ember-csi","user_id":"io.ember-csi","root_helper":"sudo","plugin_name": "io.ember-csi","disable_logs":false,"debug":true}
除了这个基本的调试级别之外,Ember CSI 插件还支持在裸金属上运行以及在容器中运行时的实时调试。
调试驱动程序可以使用两种机制:使用 pdb
和使用 rpdb
。
它们之间的区别在于,pdb
与 stdin 和 stdout 一起工作,而 rpdb
则打开 4444 端口以接受远程调试连接。
调试 Ember CSI 插件需要在启动它之前启用插件上的调试,然后它在运行时我们必须将其打开。
使用 X_CSI_DEBUG_MODE
环境变量启用调试。将其设置为 pdb
或 rpdb
将启用调试。该插件默认禁用了此功能,但我们的 最新 和 master 容器默认启用了此功能,使用 rpdb
。
一旦我们启动了带有启用调试的插件(我们可以在启动消息中看到它),我们就可以使用 SIGUSR1
信号将其打开和关闭,并且服务将输出更改消息,显示 调试已打开 或 调试已关闭。
将其 打开 后,插件将在下一个 GRPC 请求时停止以进行调试。如果使用 pdb
,则进入交互模式;如果使用 rpdb
,则打开端口 4444。当使用 rpdb
时,我们将在插件上看到以下消息:pdb 正在 127.0.0.1:4444 上运行。
切换调试打开/关闭的信号发送相当简单。对于裸金属,我们可以这样做
$ pkill -USR1 ember-csi
对于容器(假设其名称为 ember-csi
,如示例所示),我们可以这样做
$ docker kill -sUSR1 ember-csi
如果我们使用 rpdb
,则必须连接到端口
$ nc 127.0.0.1 4444
故障排除
CSC 命令超时
如果您有一个慢速后端或慢速数据网络连接,并且您正在创建挂载卷,那么在卷上运行节点准备命令时可能会遇到“上下文超时”错误。
这只是一个 60 秒的超时,我们可以通过增加命令完成所需的时间来轻松修复此问题。例如,使用 -t5m
5 分钟或如果我们在服务器端手动调试,则使用 -t1h
1 小时。
在容器中使用 iSCSI 时准备失败
当我想使用容器化的 Node 准备卷时,我看到了错误“ERROR root VolumeDeviceNotFound:在 . 中找不到卷设备”。
将 DEBUG 日志级别调整为显示登录错误
2018-07-03 11:14:57.258 1 WARNING os_brick.initiator.connectors.iscsi [req-0e77bf32-a29b-40d1-b359-9e115435a94a io.ember-csi io.ember-csi - - -] Failed to connect to iSCSI portal 192.168.1.1:3260.
2018-07-03 11:14:57.259 1 WARNING os_brick.initiator.connectors.iscsi [req-0e77bf32-a29b-40d1-b359-9e115435a94a io.ember-csi io.ember-csi - - -] Failed to login iSCSI target iqn.2008-05.com.something:smt00153500071-514f0c50023f6c01 on portal 192.168.1.1:3260 (exit code 12).: ProcessExecutionError: Unexpected error while running command.
并查看主机的日志(其中运行着 iscsid
守护进程)我可以看到 Kmod
错误
Jul 03 13:15:02 think iscsid[9509]: Could not insert module . Kmod error -2
这看起来是由于主机和容器 iSCSI 模块之间的一些不兼容性引起的。我们目前没有除使用 CentOS 7 主机系统之外的其他解决方案。
支持
对于任何问题或疑虑,请在 ember-csi 项目中提交问题,或在 Freenode 的 #openstack-cinder 频道中 ping 我(我的昵称是 geguileo)。
TODO
在这个 POC 驱动程序中需要做的事情有很多,这里是一个非详尽的列表
- NFS 卷支持
- 作为持久化存储支持 Kubernetes CRDs
- 单元测试
- 功能测试
- 改进接收参数检查
- 使驱动程序更具弹性
- 在 Kubernetes 中测试驱动程序
- 审查一些返回的错误代码
- 通过卷类型支持卷属性
- 查看多附加
- 支持只读模式
- 根据过配值报告容量
- 配置私有数据位置
历史
1.0.0 (2019-xx-yy)
错误
- 修复无效令牌的列表
- 修复使用未来令牌的列表分页
- 修复卷克隆
- 修复获取卷统计信息
0.9.0 (2019-06-04)
Beta 版本,支持 CSI v0.2、v0.3 和 v1.0 规范。
功能
- 单个容器上的多驱动程序支持
- 支持挂载文件系统
- 支持块
- 拓扑支持
- 快照支持
- 存活探测
- CRD元数据持久化插件
- 单个容器上的多版本支持
- 配置别名
- 存储驱动列表工具
- 支持运行中驱动程序的实时调试
- 重复请求队列支持(适用于k8s)
- 支持模拟探测
- 可配置默认挂载文件系统
错误
- 修复接收重复RPC调用的问题
- 修复UUID警告
- 检查预发布和发布目标
- 在绑定错误时退出
0.0.2 (2018-06-19)
- 使用cinderlib v0.2.1而不是github分支
0.0.1 (2018-05-18)
- PyPI上的首次发布。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。
源分布
构建分布
ember-csi-0.9.1.tar.gz的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | f24e8f8252813f07cc4f80abb37b8f9f58f076c4506be4b976ff6e0e3434f881 |
|
MD5 | 41056571448d7fdd502ef4b776412ea0 |
|
BLAKE2b-256 | 3fda13427893c92de96b4932caf0fd21b1f9185a069e4972054ebefb483f5023 |
ember_csi-0.9.1-py2.py3-none-any.whl的散列值
算法 | 散列摘要 | |
---|---|---|
SHA256 | 5e305dfa0706dbb985411f3f76fe1c473110249d44c7859db97d2734bf5544b3 |
|
MD5 | ea4874b7a59f198dd2a8c6c53cbf174c |
|
BLAKE2b-256 | f9c250a4d4c7c494a4ef9eb4afaf67397cc8c110a1bce533f45abdebb292f23e |