Ceph RBD 块设备存储是十分适合作为虚拟化平台的存储后端的, 这也是其最常用的情景之一. 这篇主要介绍如何将 Ceph RBD 作为 QEMU 等的存储端.


Table of Contents

  1. 配置 Ceph
  2. 配置 VM Managers
  3. 创建 VMs
    1. 创建 Linux VMs
    2. 配置 Linux VMS
    3. 配置 Windows VMs
    4. 挂载到现有 VMs
    5. 查看 QEMU 与 CEPH 交互
  4. 配置 QEMU/KVM
    1. 基本用法
    2. 创建 images
    3. 调整 images 大小
    4. 获取 image 信息
    5. 运行 VMs
    6. 调用 Discard/Trim
    7. QEMU Cache 选项

RBD 具有快照的特性, 我们又可以对 RBD 快照进行克隆, 创建一系列的写时复制克隆复本. RBD 的这一特性可以让 Ceph 能够很快地给虚拟机提供块设备, 因为客户端不需要每次在新建虚拟机时都下载整个镜像.

libvirt 为 OpenStack, CloudStack 等云计算平台提供 Ceph 块设备服务, 云计算平台使用 libvirtQEMU/KVM 等交互, QEMU/KVM 等使用 librbd 与 Ceph RBD 块设备交互.

Ceph RBD 可以作为 VMs 的数据盘和系统盘来使用. 下面我们就来看看如何实现这一目标.

配置 Ceph

要配置 Ceph 来配合 libvirt, 可依照如下步骤.

  1. 创建一个 Pool. 专门为 libvirt 创建一个 Pool, 并初始化.
1
2
3
[ceph@ceph0 ~]$ ceph osd pool create libvirt-pool 128 128
[ceph@ceph0 ~]$ ceph osd lspools
[ceph@ceph0 ~]$ rbd pool init libvirt-pool
  1. 创建与 Ceph 交互的 User. 这里使用 client.libvirt 作为用户名, libvirt 会使用 libvirt 而不是 client.libvirt 与 Ceph 交互.
1
2
[ceph@ceph0 ~]$ ceph auth get-or-create client.libvirt mon 'profile rbd' osd 'profile rbd pool=libvirt-pool'
[ceph@ceph0 ~]$ ceph auth ls
  1. 使用 QEMU 新建 images. 比如新建一个 linux-image, 一个 windows-image.
1
2
3
[ceph@ceph0 ~]$ qemu-img create -f rbd rbd:libvirt-pool/linux-image 60G
[ceph@ceph0 ~]$ qemu-img create -f rbd rbd:libvirt-pool/windows-image 80G
[ceph@ceph0 ~]$ rbd -p libvirt-pool ls
  1. 添加如下部分到 /etc/ceph/ceph.conf 中,以便调试错误. (可选)
1
2
3
[client.libvirt]
log file = /var/log/ceph/qemu-guest-$pid.log
admin socket = /var/run/ceph/$cluster-$type.$id.$pid.$cctid.asok

配置 VM Managers

libvirt 可以直接创建 VMs, 但是使用 virt-manager 可能麦加方便一些.

  1. 安装 VM manager.
1
[ceph@ceph0 ~]$ sudo yum install -y virt-manager
  1. 准备好 OS images. 这里我们用 CentOS 7.5Windows 7 64 bit 两个系统.
  2. 启动 VMs manager.
1
[ceph@ceph0 ~]$ virt-manager

接下来我们就开始安装 VMs 了.

创建 VMs

创建 Linux VMs

  1. 点击 Create New Virtual Machine 按钮.
  2. 命名 虚拟机 的域. 例如 centos.
  3. 导入 OS image.
  4. 配置启动 VM
  5. 要使用 Ceph RBD 作为系统盘, 先不要安装系统,
  6. 要使用 Ceph RBD 作为数据盘, 可以先安装系统.VM.

接下我们先关掉 VM.

配置 Linux VMS

  1. 打开 VM 配置文件.
1
sudo virsh edit centos

<devices> 下应该有一个 <disk> 项.

1
2
3
4
5
6
7
8
9
<devices>
<emulator>/usr/bin/kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/path/to/image/recent-linux.img'/>
<target dev='vda' bus='virtio'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
</devices>
  1. 如果使用 RBD 作为数据盘, 在其下面加上下面项. 如果用作系统盘, 去掉上面的一项, 再加上下面一项.
1
2
3
4
5
6
<disk type='network' device='disk'>
<source protocol='rbd' name='libvirt-pool/new-libvirt-image'>
<host name='{monitor-host}' port='6789'/>
</source>
<target dev='vda' bus='virtio'/>
</disk>

将其中的 {monitor-host} 替换成真实的 hosts. 保存并退出.
3. 配置 Ceph Authentication. 一般 Ceph 集群都设置了登录认证. 我们需要生成一个 secret.

1
2
3
4
5
6
7
cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
<usage type='ceph'>
<name>client.libvirt secret</name>
</usage>
</secret>
EOF
  1. 定义 secret.
1
[ceph@ceph0 ~]$ sudo virsh secret-define --file secret.xml > uuid.txt
  1. 获取 client.libvirt key, 并保存到 client.libvirt.key.
1
[ceph@ceph0 ~]$ ceph auth get-key client.libvirt | sudo tee client.libvirt.key
  1. 设置 secret 的 UUID.
1
[ceph@ceph0 ~]$ sudo virsh secret-value --secret $(cat uuid.txt) --base64 $(cat client.libvirt.key)
  1. 在虚拟机配置里加上认证信息. 在<disk type='network' device='disk'>下面加上如下项.
1
2
3
<auth username='libvirt'>
<secret type='ceph' uuid='9ec59067-fdbc-a6c0-03ff-df165c0587b8'/>
</auth>
  1. 开机启动 VM, 就可以使用 rbd 来当作系统盘或数据盘了.

配置 Windows VMs

Windows VM 与 Linux VM 下同的一点是它没有自带 virtio 的驱动, 所以在安装系统时, Windows 并不能识别 rbd 设备. 需要下载 virtio-win.
将下载的镜像挂载到 VM 上, 在选择安装到硬盘界面时, 选择加载驱动, 选择 virtio-win 镜像下的 /viostor/w7/amd64/ 文件夹. 加载之后, 就可以识别了. 然后就可以将 Window 安装到 Ceph 的 RBD 上了.

要是将 RBD 当作数据盘, 可以在安装好系统后, 在 Window 下安装驱动, 这更方便.

挂载到现有 VMs

可以动态将 Volume 挂载到 VMs 上:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cat << EOF > device.xml
<disk type='network' device='disk'>
<driver name='qemu' type='raw'/>
<auth username='vmimages'>
<secret type='ceph' uuid='9ec59067-fdbc-a6c0-03ff-df165c0587b8'/>
</auth>
<source protocol='rbd' name='libvirt-pool/new-libvirt-image'>
<host name='{monitor-host}' port='6789'/>
</source>
<target dev='vdc' bus='virtio'/>
</disk>
EOF
$ virsh attach-device centos device.xml --persistent

查看 QEMU 与 CEPH 交互

1
$ sudo virsh qemu-monitor-command --hmp {vm-domain-name} 'info block'

配置 QEMU/KVM

要使 libvirt 能够操作 Ceph RBD, 需要安装 qemu-block-rbd:

1
[ceph@ceph0 ~]$ sudo yum install -y qemu-block-rbd

这里简单介绍一个 与 rbd 相关的 qemu-img 的用法.

基本用法

1
[ceph@ceph0 ~]$ qemu-img {command} [options] rbd:{pool-name}/{image-name}[@snapshot-name]:[:option1=value1][:option2=value2...]

例如, 指定 user id 和 conf 文件

1
$ qemu-img {command} [options] rbd:libvirt-pool/linux:id=libvirt:conf=/etc/ceph/ceph.conf

创建 images

我们可以用 qemu-img 来创建 image, 如下所示. rbd 是必须指定的, pool name 和 image name 也是必须的. 格式 -f raw 是最合理的格式. 其他格式也可以,但可能会引起不必要的又比较麻烦的问题.

1
2
3
4
### Usage
$ qemu-img create -f raw rbd:{pool-name}/{image-name} {size}
### e.g.
$ qemu-img create -f raw rbd:libvirt-pool/new-image 20G

调整 images 大小

1
2
3
4
5
### Usage
$ qemu-img resize rbd:{pool-name}/{image-name} {size}
### e.g.
$ qemu-img resize rbd:libvirt-pool/new-image 50G
$ qemu-img resize rbd:libvirt-pool/new-image +20G

获取 image 信息

1
2
3
4
### Usage
$ qemu-img info rbd:{pool-name}/{image-name}
### e.g.
$ qemu-img info rbd:libvirt-pool/new-image

运行 VMs

QEMU 可以通过 librbd 直接将 rbd 作为虚拟块设备使用. qemu-img 可以将已经存在的虚拟机镜像转换到 Ceph RBD images. 如

1
$ qemu-img convert -f qcow2 -O raw centos.qcow2 rbd:libvirt-pool/centos

要从转换后的 image 启动一个虚拟机, 运行如下命令:

1
$ qemu -m 1024 -drive format=raw,file=rbd:data/centos,cache=writeback

上面的 cache=writeback 是启用 RBD的 caching 功能, 可大大提高 VMs 性能…

调用 Discard/Trim

1
$ qemu -m 1024 -drive format=raw,file=rbd:libvirt-pool/centos,id=libvirt,if=none -device driver=ide-hd,drive=drive1,discard_granularity=512

QEMU Cache 选项

  1. writeback:
1
rbd_cache = true
  1. writethrough:
1
2
rbd_cache = true
rbd_cache_max_dirty = 0
  1. None:
1
rbd_cache = false

QEMU 的 cache 设置会覆掉 Ceph 的设置.