KVM使用ceph存储
在 KVM/libvirt 环境中,通过 RBD(RADOS Block Device)将 Ceph 块设备挂载为虚拟机网络磁盘。本文说明客户端依赖安装、Ceph 密钥注入 libvirt secret,以及域 XML 中网络盘的配置方式。
环境
| 项目 | 说明 |
|---|---|
| 操作系统 | Ubuntu 20.04.1 |
| 虚拟化 | KVM + libvirt(virsh) |
| 存储 | Ceph RBD |
操作需在具备
virsh权限的宿主机上执行;下列密钥与 UUID 请按实际集群替换。
1. 安装客户端依赖
在 KVM 宿主机安装 Ceph 通用客户端工具包(含 rbd 等命令及库依赖):
apt-get -y install ceph-common
如需指定版本或使用发行版仓库以外的 Ceph 源,请先配置对应 apt 源后再安装。
2. 添加 Ceph 密钥(libvirt secret)
libvirt 通过 secret 对象保存 Ceph 用户密钥,供虚拟机磁盘鉴权使用。流程为:定义 secret → 写入密钥值。
2.1 定义 secret
创建 secret 描述文件:
cat > /tmp/key.xml << 'EOF'
<secret ephemeral='no' private='no'>
<uuid>2c79423e-1c0b-4e97-ac93-5d80f211d0e8</uuid>
<usage type='ceph'>
<name>client.game_storage secret</name>
</usage>
</secret>
EOF
注册到 libvirt:
virsh secret-define /tmp/key.xml
说明:
uuid:secret 唯一标识,需与下文磁盘 XML 中的secret uuid一致。usage type='ceph':标明用途为 Ceph。name:通常对应 Ceph 客户端标识(如client.game_storage);此处示例名为client.game_storage secret,可按集群约定调整。ephemeral='no':持久 secret,重启后仍保留;private='no':允许非特权查询(生产环境可按安全要求改为private='yes')。
2.2 设置密钥值
将 Ceph 用户的 keyring 以 Base64 形式写入 secret(以下为示例值,必须替换为真实密钥):
virsh secret-set-value \
--secret 2c79423e-1c0b-4e97-ac93-5d80f211d0e8 \
--base64 AQBye8VhSUpDGxAArsoViVyf9Q2uh9KmAwC6yg==
从 keyring 提取 Base64 密钥的常用方式(示例):
# 假设 keyring 中含 [client.game_storage] 的 key=
grep key /etc/ceph/ceph.client.game_storage.keyring | awk '{print $3}'
验证 secret 是否已定义:
virsh secret-list
virsh secret-dumpxml 2c79423e-1c0b-4e97-ac93-5d80f211d0e8
3. 添加网络盘(域 XML)
在虚拟机域 XML 的 <devices> 中增加 type='network' 的磁盘设备,通过 RBD 协议连接 Ceph 集群。示例:
<disk type='network' device='disk'>
<driver name='qemu' type='raw' cache='none' discard='unmap'/>
<auth username='game_storage'>
<secret type='ceph' uuid='2c79423e-1c0b-4e97-ac93-5d80f211d0e8'/>
</auth>
<source protocol='rbd' name='data_pool/g1.test3.image'>
<host name='ceph-01' port='6789'/>
<host name='ceph-02' port='6789'/>
<host name='ceph-03' port='6789'/>
<host name='ceph-04' port='6789'/>
<host name='ceph-05' port='6789'/>
</source>
<target dev='vdb' bus='virtio'/>
<serial>G0-Z00000000000</serial>
<address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/>
</disk>
字段说明
| 配置项 | 含义 |
|---|---|
driver type='raw' |
RBD 镜像按 raw 暴露给 QEMU;cache='none' 适合配合 Ceph;discard='unmap' 便于 TRIM/丢弃回收 |
auth username |
Ceph 客户端用户名(不含 client. 前缀),需与密钥所属用户一致 |
secret uuid |
与第 2 步定义的 secret UUID 一致 |
source protocol='rbd' |
使用 RBD 协议 |
source name |
格式为 池名/镜像名,示例为 data_pool/g1.test3.image |
host |
Ceph Monitor 地址与端口(经典默认端口为 6789;若使用 msgr2,常见为 3300,以集群实际配置为准) |
target dev='vdb' |
客户机内设备名;bus='virtio' 为 VirtIO 磁盘 |
serial |
磁盘序列号,便于客户机内识别;示例 G0-Z00000000000 |
address |
PCI 插槽;热插拔或与已有设备冲突时需调整 slot |
应用配置
编辑已有虚拟机配置并生效,例如:
# 编辑域 XML(保存退出后按提示处理)
virsh edit <域名或UUID>
# 或导出后修改再 redefine
virsh dumpxml <域名> > /tmp/vm.xml
# 编辑 /tmp/vm.xml 后:
virsh define /tmp/vm.xml
运行中虚拟机若支持热插拔,也可使用 virsh attach-device / attach-disk(需按实际 libvirt 版本与参数编写设备 XML)。
4. 前置条件与注意事项
- 镜像已存在:池
data_pool中需已有镜像g1.test3.image(可用rbd ls data_pool、rbd info data_pool/g1.test3.image检查)。 - 网络可达:宿主机能解析并访问各
ceph-0xMonitor(DNS 或/etc/hosts)。 - 权限匹配:
game_storage用户对目标池/镜像具备读写权限,且 secret 中的 key 与该用户一致。 - UUID 一致:secret 定义、
secret-set-value与磁盘 XML 三处 UUID 必须相同。 - 安全:文档中的 Base64 密钥仅为示例;勿将生产密钥提交到公开仓库;用完可删除
/tmp/key.xml。 - 端口与协议:若集群仅启用 msgr2 或 Monitor 端口非
6789,请同步修改<host port='...'>。
5. 简要排查
# secret 是否存在
virsh secret-list
# 宿主机侧能否访问镜像(需已配置 ceph.conf / keyring)
rbd info data_pool/g1.test3.image
# 查看虚拟机磁盘与错误日志
virsh dumpxml <域名> | grep -A20 "type='network'"
journalctl -u libvirtd -e
常见问题:鉴权失败多因 UUID/用户名/密钥不匹配;无法连接多因 Monitor 地址或端口错误、防火墙拦截。