OpenStack块存储nova-volume工作机制和相关问题


最近有点忙,收到不少邮件或者留言,有些没有回复,在此致歉。在OpenStack中,出现问题比较多的除了网络部分,还有存储部分。对于swift对象存储的研究和相关技术资料已经有很多,而块存储nova-volume相关的介绍还少见,其中也有很多问题出现。

下面将对这一部分的一些问题给予介绍,希望大家有好的经验都分享出来,社区的力量需要每一分子的贡献。最近这几篇文章的目录贴在这里,相关问题可以直接去查阅对应文章,如果还问很多已经在文章里说明的问题我就不回复了。

OneStack:Ubuntu 12.04 (或11.10) 一键部署安装OpenStack云计算平台,这个介绍了onestack这个一键部署的项目;
OpenStack安装部署管理中常见问题解决方法(OpenStack-Lite-FAQ),这个记录了一些基本的问题和解决方法;

构建OpenStack的高可用性(HA,High Availability),这部分介绍了高可用性的OpenStack IaaS平台的一些策略和方案;

OpenStack云平台的网络模式及其工作机制,这个详细分析了网络原理和工作机制;

OpenStack卷存储nova-volume相关问题,由于nova-volume问题较多,单独写这一篇,主要介绍块存储相关的问题;

对swift对象存储的内部原理和相关技术可以查找对象存储、一致性哈希等文章,新浪有几篇技术分享介绍的很好,推荐看一看。

一、相关概念

LVM存储常用术语
物理存储介质(Physical Media):
物理存储设备,如磁盘或者磁盘上的分区,是存储系统的最底层实体。 

物理卷(PV,Physical Volume)硬盘分区或从逻辑上与硬盘分区具有同样功能的设备(如 RAID),是 LVM 的基本存储逻辑块;和基本的物理存储介质(如分、磁盘等)不同的是含有 LVM 管理参数。 

卷组(VG,Volume Group):LVM 中的最高抽象层,由一个或多个物理卷(PV)组成。一个逻辑卷管理系统中可以拥有多个卷组。 
逻辑卷(LV,Logical Volume):逻辑卷(LV)在卷组上建立,相当于非 LVM 系统中的分区。每个逻辑卷属于它所在的卷组。 


VGDA(卷组描述符区域) :和非 LVM 系统将包含分区信息的元数据保存在位于分区起始位置的分区表中一样,逻辑卷以及卷组相关的元数据被保存在位于物理卷起始处的 VGDA 中。VGDA 包括以下内容:PV 描述符、VG 描述符、LV 描述符、和一些 PE 描述符。系统启动 LVM 时激活 VG,并将 VGDA 加载至内存,来识别 LV 的实际物理存储位置。当系统进行 I/O 操作时,就会根据 VGDA 建立的映射机制来访问实际的物理位置。

存储类型

通常来讲,所有磁盘阵列都是基于Block块的模式,所有的NAS产品都是文件级存储,而对象存储(Object-based Storage)是一种新的网络存储架构,它基于对象存储技术。

iSCSI协议

将SCSI命令封装在IP包中,建立会话通过TCP/IP网络传输。iSCSI协议定义了在TCP/IP 网络发送、接收 block(数据块)级的存储数据的规则和方法。发送端将SCSI命令和数据封装到TCP/IP包中再通过网络转发,接收端收到 TCP/IP包之后,将其还原为SCSI命令和数据并执行,完成之后将返回的SCSI命令和数据再封装到 TCP/IP包中再传送回发送端。而整个过程在用户看来,使用远端的存储设备就象访问本地的SCSI设备一样简单。

iscsi-target server

iSCSI有多种存储架构,但是由于PC架构的成本低,同时技术越来越成熟,基于PC架构的iSCSI存储设备应用广泛iSCSI Target软件安装在PC服务器上,使普通的PC服务器转变成一台iSCSI存储设备,并通过PC服务器的以太网卡对外提供基于iSCSI数据传输协议的服务。

iscsi-initiator

Initiator软件可以将以太网卡虚拟为iSCSI卡,接受和发送iSCSI数据报文,从而实现主机和iSCSI设备之间的iSCSI协议和TCP/IP协议传输功能。


二、OpenStack的存储服务

1、存储组件和服务

OpenStack创建出来的实例是没有永久存储的,关闭实例后数据都会丢失,所以需要存储卷来保存每个instance的数据。这项工作由nova-volume实现,提供类似亚马逊EBS的块存储服务。其中,nova-volume专门管理卷的创建、删除、挂载等,这些卷基于lvm管理,使用iscsi提供服务,并通过libvirt与虚拟机交互。

lvm提供卷组和逻辑卷管理。首先需要创建一个名为nova-volumes的卷组,不然nova-volume不能正常工作。因为nova-volume所有的创建、删除volume都是针对这个卷组里的逻辑卷。创建volume时nova-volume会调用lvm的命令lvcreate创建逻辑卷。

iscsi提供多个节点间的存储服务。创建volume时计算节点还会创建iscsi IQN,计算节点与iscsi服务器间建立iscsi会话;挂载时实例就拥有了这个逻辑卷;然后使用virsh命令把这个逻辑卷挂载到实例作为它的一块存储设备。

libvirt是一组与多种虚拟机交互的管理工具集。它支持虚拟机KVM/QEMU、Xen、virtual Box、vmware ESX、Hyper-V等。为了使虚拟机获得更强大的后端存储能力,libvirt 提供了对各种存储介质的支持,包括本地文件系统,网络文件系统,iSCSI,LVM 等多种后端存储系统。libvirt 中的存储管理独立于虚拟机管理。也就是存储池和存储卷的操作独立于虚拟机的操作存在,因此进行存储管理时,不需要有虚拟机的存在,可以当虚拟机需要存储资源时再进行分配,非常灵活。

存储卷是一种可以分配给虚拟机使用的存储设备,在OpenStack中就是逻辑卷volume。在虚拟机中与一个挂载点对应,而物理上可以是一个虚拟机磁盘文件或一个真实的磁盘分区,从卷组nova-volumes中分出来的。

存储池是一种可以从中生成存储卷的存储资源,后端可以支持目录池、本地文件系统池、逻辑卷池、磁盘卷池、iSCSI 卷池等,在OpenStack中就是逻辑卷组nova-volumes

存储卷从存储池中划分出来,存储卷分配给虚拟机成为可用的存储设备。存储池在 libvirt 中分配的 id 标志着它成为 libvirt 可管理的对象,生成卷组 vg(volume group,OpenStack中必须nova-volumes) 就有了可划分存储卷的存储池,状态为活跃 (active) 状态才可以执行划分存储卷的操作,可以参考下图。


2、存储结构和机制

安装部署OpenStack时,安装了lvm,安装了libvirt,还安装了tgt和open-iscsi

在nova.conf设置存储管理工具为tgtadm,使用tgt管理target。iscsi target管理工具很多,iscsitarget软件是其中一中。

服务器,tgt提供服务,tgtadm命令查询、创建和删除target。

客户端,open-iscsi提供服务,iscsiadm命令查询、登录和登出target。建立会话,断开会话。

数据库,volume的位置、状态等信息会存到数据库,在onestack安装时,选择mysql,同时安装了phpmyadmin,可以通过web界面访问管理。

nova-volume安装在控制节点,这个物理主机提供volume的创建、删除、挂载等管理功能。

open-iscsi安装在计算节点,提供计算节点上的实例和服务端的target之间的会话管理。

所以在一个all-in-one的部署结构里,物理主机既是server又是client。

在OpenStack的安装过程中,最后nova.conf这个配置文件设置了target管理程序tgtadm,所以使用tgt来提供target服务;iscsi_prefix指明了查找iscsitarget的ip段,可以设为完整的tgt所在的主机ip,或者前缀,可以使用iscsi_ip_addres=192.168.139.50设置指定的ip

这样nova会自动使用iscsiadm从这个ip进行discovery,类似执行命令

iscsiadm -m discovery -t sendtargets -p IP:port

所以每次实例启动时,通过已有的映射挂载这个设备,也就是nova-volumes里的一个逻辑卷,或者说一个iscsi target。这样就可以像普通磁盘设备、物理卷、磁盘分区一样使用这个挂载的volume。


3、存储服务的工作流程

安装部署OpenStack时,安装了lvm,安装了libvirt,还安装了tgt和open-iscsi。

1)lvm创建卷组(VG),OpenStack中就是逻辑卷组nova-volumes,也就是OpenStack里只能使用这个卷组名。没有这个名字的卷组,nova-volume将不会正常启动,这也会导致nova-compute不能正常启动。

查看卷组vgdisplay

查看哪些nova服务没有正常启动nova-manage service list

2)如果没有nova-volumes卷组,创建这个卷组。这需要一个或者多个物理卷,可以扩展卷组。

pvcreate /dev/sdb3
vgcreate nova-volumes /dev/sdb3

vgextend nova-volumes /dev/sdb4

3)如果没有物理设备,可以使用文件代替,一般实验用。

$ dd if=/dev/zero of=/opt/nova-volumes.img bs=1M seek=100000 count=0
$ losetup -f /opt/nova-volumes.img
$ losetup -a
$ vgcreate nova-volumes /dev/loop0

4)创建nova-volumes卷组后,需要重启nova-volume服务

5)确保tgt服务开启,并且tgt监听3260端口。

lsof | grep 3260

6)以上都正常服务,在客户端(计算节点,或者装了all-in-one的主机)。确保open-iscsi这个客户端软件正常工作。

7)nova volume-create创建volume,可以使用nova命令或者在web进行。

如果创建成功,可以在客户端通过iscsiadm命令查看会话,以及查看服务端的target。

iscsiadm -m session

iscsiadm -m discovery -t sendtargets -p IP:port

在服务端,可以查看target

tgtadm --lld iscsi --op show --mode target

8)创建volume成功,下面可以attach到某个实例。

如果attach不成功,检查日志;

如果一直attaching,请看下面问题和解决方法3.7

9)进入实例,可以fdisk -l看到新挂载的volume。


三、常见问题和解决方法(已加入OpenStack-Lite-FAQ第3节)

3.0、创建太多volume或者instance,不能正常运行,怎么清空数据库并重置数据库

在OneStack项目里,已经加入了这个脚本工具,可以自行更改和增删。镜像相关的数据在glance数据库,身份相关的在keystone,nova相关的数据主要对应nova数据库,包括实例instance表和卷volume表。

清空nova数据库./resetStack clear

然后重新初始化./resetStack

3.1、OpenStack中创建volume一直在creating,什么原因

主要因为nova-volume没有正常启动,可以

nova-manage service list

看看后面的状态,不是笑脸:-)而是xx。如果没有启动,请接着看下一条FAQ(3.2)。

3.2、OpenStack中nova-volume服务不能启动,什么原因

主要因为没有nova-volumes卷组,或者iscsitarget服务没有启动(或者没有安装)。

1、vgdisplay

没有nova-volumes卷组,可以创建卷组和磁盘

$ dd if=/dev/zero of=/opt/nova-volumes.img bs=1M seek=100000 count=0
$ losetup -f /opt/nova-volumes.img
$ losetup -a
$ vgcreate nova-volumes /dev/loop0


记着启动nova-volume然后创建volume,否则下面仍然不能创建

$ service nova-volume restart

$ nova volume-create --display_name "volume1" 10


2、service tgt status

由于nova.conf设置tgtadm管理,在控制节点(nova-volume所在的物理节点)使用tgt提供target服务,通过tgtadm管理。

1)没有安装tgt,或者没有正常启动tgt,可以apt安装(可以用iscsitarget,对于inet管理工具,对应iscsitarget iscsitarget-dkms,需要sed -i -e 's/false/true/' /etc/default/iscsitarget是服务可以工作

然后执行以下命令安装和设置为可以启动

apt-get install -y tgt
service tgt start
service nova-volume restart

lsof | grep 3260可以查看端口是否监听


2)如果既没有nova-volumes卷组,也没有安装tgt,切忌保证这两者都存在,并且nova.conf设置正确,然后重启nova-volume,再创建volume

有人安装tgt并启动后就create,结果nova-volume并没有启动,所以问题依然存在;

有人创建nova-volumes,也没有重启nova-volume,也不能正常工作。


3.3、OpenStack中创建volume一直在creating,怎么停掉(stop)
主要因为nova-volume没有正常启动,即使现在启动了还会停留在这个状态。
需要手动更改数据库里相关状态信息,从creating改为deleted然后删掉。

对于这个没有创建成功的volume,可以直接更改数据库改为deleted,注意nova volume-delete会提示找不到。

如果不能创建某些卷,并且提示存在这种volume,比如lvdisplay查到这个逻辑卷,需要lvremove;如果tgt中可以看到这个target,需要使用tgtadm删除

tgtadm --op delete --lld=iscsi --mode=target --tid=1


3.4、OpenStack中nova-volume执行出现问题,检查什么地方
主要因为nova-volume没有正常启动或者计算节点没有能找到target,可以检查以下这些问题。
nova-volume是否正常;控制点,详见问题3.2
tgt是否开启;服务端
open-iscsi是否安装和开启;客户端
客户端(计算节点)iscsiadm discovery看看能不能找到存储服务;
分析nova-volume.log、nova-compute.log和libvirt.log。


3.5、OpenStack中tgt管理target
控制节点查看target
tgtadm --lld iscsi --op show --mode target
建立target
sudo tgtadm --op new --lld=iscsi --mode=target --tid=1 --targetname=iqn.2010-10.org.openstack:volume-00000001

3.6、OpenStack中计算节点管理volume
查看建立的session
sudo iscsiadm -m session
手动发现target
sudo iscsiadm -m discovery -t sendtargets -p IP:port
登入登出
sudo iscsiadm -m node -T targetname(iqn.2010-10.org.openstack:volume-00000004) -p 10.200.200.4:3260 --login
sudo iscsiadm -m node -T targetname(iqn.2010-10.org.openstack:volume-00000004) -p 10.200.200.4:3260 --logout
sudo iscsiadm -m node -o [delete|new|update] -T targetname


如果使用命令

sudo iscsiadm -m discovery -t sendtargets -p compute_node
报以下错误
iscsiadm: Connection to Discovery Address 192.168.139.50 closed
iscsiadm: Login I/O error, failed to receive a PDU
这是因为没有找到target,可以create一个volume,此时会建立一个卷,建立一个target。

3.7、OpenStack中挂载volume一直阻塞停留在attaching,什么原因,怎么解决

在volume-create成功创建volume后,挂载到实例,如果遇到什么提示都没有nova volume-attach后仍然为available,那么是你的挂载有问题,比如使用的设备名/dev/vdc已经使用了,需要检查日志。

更多的问题是,nova volume-attach一直attaching,删不掉也挂不上。这时候,nova-manage service list你会发现nova-compute已经停止,如果以上所描述的问题(nova-volume没有正常工作)都不存在,那么需要你更改OpenStack源代码了,这是OpenStack的一个bug。

1)对于这个没有挂载成功的volume,可以直接更改数据库改为available,或者使用nova-manage volume delete来通过数据库删除这个volume,注意nova volume-delete会删不掉。

2)对于这个bug,需要更改以下两处源代码:

vi /usr/share/pyshared/nova/virt/libvirt/connection.py

把virt_dom.attachDevice(xml)这一行改为

LOG.info("attaching device with virsh")
device_path = connection_info['data']['device_path']
utils.execute('virsh', "attach-disk", instance_name, device_path, mount_device, run_as_root=True )

vi /usr/share/pyshared/nova/rootwrap/compute.py

添加一行

filters.CommandFilter("/usr/bin/virsh", "root"),

这样就行了,注意volume-attach填写的设备名不能重复,虽然它并不一定使用你指定的设备名作为实例的设备名。

如果很多服务没有正常工作,可以重启所有服务

for a in libvirt-bin nova-network nova-compute nova-api nova-objectstore nova-scheduler novnc nova-volume nova-consoleauth; do service "$a" restart; done

为了集中这些讨论,请访问原始出处:《OpenStack块存储nova-volume相关问题》。如有OpenStack问题和解决,请直接下面回复,这样也方便后来人。如有其它问题反馈,Kayven微博留言E-mail)。国内对于OpenStack还处于比较初级的阶段,技术研究公开的资料较少,多为一些安装部署问题相关的文章,比较深入的技术分析和比较全面的介绍较少。希望有什么经验和观点,可以在这里分享出来供大家讨论,也帮助理清自己的思路。


你可能感兴趣的:(OpenStack块存储nova-volume工作机制和相关问题)