跳转到主要内容

支持超过80个存储驱动器的多厂商CSI插件

项目描述

Ember CSI

Docker build status Docker build PyPi PyVersion License

支持超过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 全局 Embercinderlib 配置 {"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 环境变量启用调试。将其设置为 pdbrpdb 将启用调试。该插件默认禁用了此功能,但我们的 最新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 (129.2 kB 查看散列值)

上传时间

构建分布

ember_csi-0.9.1-py2.py3-none-any.whl (139.5 kB 查看散列值)

上传时间 Python 2 Python 3

由以下提供支持