上下文:

在工作中客户要求做一个openstack的镜像,这个操作系统的配置要求非常的高,最小需要896GB内存1TB硬盘。普通的系统可以通过分区扩展脚本做一个20GB的镜像然后在云平台上扩展,但是由于这个系统是封闭的,没法把脚本放进去,所以镜像只能一口气做成1TB大小。

该镜像如果制作成qcow只有5GB的大小。如果做成raw格式的镜像则有1TB大。

原来的设想是将镜像做成qcow2格式然后上传到glance中,没想到qcow2的镜像在创建虚拟机的时候会临时在计算节点上转换成raw格式,这样导致计算节点因为一下子多出了一个1TB文件,占满了磁盘把信息队列堵死了。

无奈在计算节点上将qcow转换成raw的话,也无法放下一个1TB的文件。故此最后决定将镜像上传到存储中去,然后在存储中将qcow转换成raw格式,然后再传到glance中去。

由于这个情况非常复杂,情况特殊,所以我把操作的记录写下来。

 

参数:

在本文中会牵涉到一些参数,这个参数在实际的环境中会有变化故此在这里解释一下。

<pool.name> ceph的池名,可以通过命令:ceph osd lspools查看到。

不知道为什么本环境中所有关于ceph的命令都需要加上--id cinder参数才能显示。

<rbd.id> rbdidid是内容是随机生成的,可以通过命令uuidgen来生成,然后镜像就使用这个id来表示自己。在ceph中的镜像都是用uuid来命名。

 

uuidgen

首先我先运行了uuidgen命令来生成id来用于接下来的一条命令中使用。

 

rbd import --path <*.raw> --dest-pool <pool.name> --dest <rbd.id> --id cinder

import命令将本地的镜像文件<*.raw>上传到了<pool.name>中,而<rbd.id>就是前面的uuidgen生成的字符串。

 

rbd -p <pool.name> info <rbd.id> --id cinder

这条命令是查看池中有没有这个id的镜像,确认上传成功。在完成上传后,我们就要准备将这个raw转换成qcow。所以要为qcow文件准备一个名字,依旧是一个uuid

 

uuidgen

这一次生成的uuid是给qcow文件准备的。

 

qemu-img convert -O raw rbd:<pool.name>/<old.rbd.id>:id=cinder rbd:<pool.name>/<new.rbd.id>:id-cinder

这个是一个qemu-img转换镜像格式的命令,不过后面的路径是rbd的。

 

rbd -p <pool.name> info <new.rbd.id> --id cinder

检查池中有没有新生成的镜像文件。

 

qemu-img info rbd:<pool.name>/<new.rbd.id>:id=cinder

可以通过qemu-img查看这个文件,看到这个文件是否为raw文件。

 

rbd --pool <pool.name> snap create --snap snap <rbd.id> --id cinder

rbd --pool <pool.name> snap protect --image <rbd.id> --snap snap --id cinder

rbd -p <pool.name> snap ls <rbd.id> --id cinder

 

最后是上传镜像(这个命令有点怪,貌似是上一个版本的openstack命令,我用的是m版本)

glance --os-image-api-version 1 image-create --id <rbd.id> --name <image.name> --store rbd --disk-format raw --container-format bare --location rbd://$(ceph fsid --id cinder)/<pool.name>/<rbd.ip>/snap