挂载失败本质是跨组件链路故障,核心在计算节点执行层;需优先检查nova-compute.log中attach_device调用是否失败,再依次排查libvirt配置、存储可达性、权限认证、Libvirt Secret一致性、VM锁定状态及SELinux上下文。

挂载失败不是 Cinder 单点问题,而是跨组件链路故障。绝大多数情况,nova volume-attach 命令不报错,但虚拟机里看不到设备,说明问题出在计算节点的执行层——要么 libvirt 没写入配置,要么后端存储不可达,要么权限/认证卡在中间某环。
看 nova-compute.log 里的 attach_device 调用是否失败
这是最直接的切入点。Cinder 只负责调度和准备卷,真正把设备“塞进”运行中虚拟机的是 nova-compute + libvirt。如果挂载静默失败,先 ssh 到对应 compute 节点,查日志:
grep -A5 -B5 "attach_volume" /var/log/nova/nova-compute.log- 重点找
Failed to attach volume at mountpoint或live=.* failed这类错误 - 如果看到
libvirtError: internal error: unable to execute QEMU command 'device_add',大概率是虚拟机太老或启用了不兼容的 CPU 模式,需关机后挂载 - 若出现
Operation not permitted且后端是 Ceph,跳转到 Libvirt Secret 验证环节
检查 /var/lib/cinder/volumes/ 下卷文件的属主和权限
NFS 后端尤其容易栽在这里。cinder-volume 进程以 cinder 用户运行,但它创建的卷文件(比如 /var/lib/cinder/volumes/volume-xxxx)如果被误 chown 成 root:root,后续 nova-compute 就无法读取该文件来构造挂载参数。
- 执行
ls -l /var/lib/cinder/volumes/volume-*,确认所有卷文件属主是cinder:cinder - 如果不是,批量修复:
sudo chown -R cinder:cinder /var/lib/cinder/volumes/ - 注意:不要只改目录权限,NFS 后端实际挂载的是文件,文件本身权限必须可读
- 如果使用 SELinux,还要确认上下文没被重置:
ls -Z /var/lib/cinder/volumes/,应为system_u:object_r:cinder_var_lib_t:s0
验证 Libvirt Secret 是否存在且值正确(Ceph/RBD 后端必查)
Cinder 创建卷时用 client.cinder key 访问 Ceph,但 nova-compute 挂载时走的是 libvirt 的 RBD driver,它不读 ceph.client.cinder.keyring,而是查 virsh secret-get-value 返回的 base64 key。两者 key 不一致就会静默失败。
- 查 secret 列表:
sudo virsh secret-list,确认有类型为ceph的条目 - 查 secret 值是否匹配:
sudo virsh secret-get-value,输出应与| base64 -d ceph auth get-key client.cinder完全一致 - 如果 key 被人工更新过(比如云管重置了 cinder 用户密钥),但没同步到 libvirt secret,就必须重新
virsh secret-set-value - 注意:secret 的
字段只是描述,libvirt 实际只认和 value,别被名字误导
确认虚拟机未被锁定或处于异常状态
OpenStack 的 VM lock 功能会拦截所有变更操作,包括挂载卷,而且不返回明确错误,只让命令“成功返回却无效果”。
- 查 VM 状态:
openstack server show-c status -c locked - 如果
locked字段为True,必须先解锁:openstack server unlock - 另外检查
status是否为ACTIVE;如果是ERROR、SHUTOFF或PAUSED,部分后端(如 LVM)可能拒绝 live attach - 某些旧版 libvirt 对运行超 1 年的虚拟机 live attach 支持不稳定,临时方案是
openstack server stop→ 挂载 →start
挂载链路长、组件多,日志分散在 cinder-volume、nova-compute、libvirt、甚至存储侧。别从配置文件开始猜,先盯住 nova-compute.log 里 attach_device 的调用结果——它不撒谎,只是需要你读懂那几行 traceback 背后的执行意图。











