igozhang

——

    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. 前置条件与注意事项

    1. 镜像已存在:池 data_pool 中需已有镜像 g1.test3.image(可用 rbd ls data_pool、rbd info data_pool/g1.test3.image 检查)。
    2. 网络可达:宿主机能解析并访问各 ceph-0x Monitor(DNS 或 /etc/hosts)。
    3. 权限匹配:game_storage 用户对目标池/镜像具备读写权限,且 secret 中的 key 与该用户一致。
    4. UUID 一致:secret 定义、secret-set-value 与磁盘 XML 三处 UUID 必须相同。
    5. 安全:文档中的 Base64 密钥仅为示例;勿将生产密钥提交到公开仓库;用完可删除 /tmp/key.xml。
    6. 端口与协议:若集群仅启用 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 地址或端口错误、防火墙拦截。

    MP3