代码改变世界

OpenStack 对接 Ceph 环境可以创建卷但不能挂载卷的问题

2019-05-07 11:01  云物互联  阅读(887)  评论(0编辑  收藏  举报

问题

环境:Nova、Cinder、Glance 都对接了 Ceph RBD 后端存储。

以往的操作包括上传镜像、创建卷、挂载卷都是一切正常的,但突然出现了无法挂载卷的问题,而且还是因为 Ceph 客户端权限问题导致的:

# nova-compute.log

error connecting: Operation not permitted

这就很神奇了,因为 nova-compute、cinder-volume 共用一个 ceph.client.cinder.keyring,为什么唯独挂载卷权限不足呢?

能创建卷、但无法挂载卷,那么问题多半出现在 Libvirt Secret 上了吧!

解决

当我们配置 OpenStack 对接 Ceph 的时候会创建 client.glance、client.cinder 两个用户,但却不会创建 client.nova 用户,这是因为 Nova 中实际与 Ceph 进行交互的是 Libvirt,而且交互的内容无非就是为 KVM 虚拟机挂载卷、卸载卷。也就是说 Nova 并没有实现 ceph-common 接口调用,所以也就没必要专门创建 client.nova 用户了。抛开 OpenStack 不说,Libvirt 很早就是已经实现了通过 cephx 认证协议与 Ceph RBD 对接的方法,就是 Libvirt Secret。

$ uuidgen
4810c760-dc42-4e5f-9d41-7346db7d7da2

# 获取 client.cinder 的 key
$ ceph auth get-key client.cinder | ssh root@compute tee /tmp/client.cinder.key

# 创建 Libvirt 秘钥文件
$ cat > /tmp/secret.xml <<EOF
<secret ephemeral='no' private='no'>
  <uuid>4810c760-dc42-4e5f-9d41-7346db7d7da2</uuid>
  <usage type='ceph'>
    <name>client.cinder secret</name>
  </usage>
</secret>
EOF

# 定义一个 Libvirt 秘钥
$ sudo virsh secret-define --file /tmp/secret.xml
Secret 4810c760-dc42-4e5f-9d41-7346db7d7da2 created

# 设置秘钥的值,值为 client.cinder 用户的 key
# Libvirt 凭此 key 就可能以 cinder 用户的授权访问 Ceph Pool: volumes 了
$ sudo virsh secret-set-value --secret 4810c760-dc42-4e5f-9d41-7346db7d7da2 --base64 $(cat /tmp/client.cinder.key)
Secret value set

[root@compute ~]# sudo virsh secret-list
 UUID                                  Usage
--------------------------------------------------------------------------------
 4810c760-dc42-4e5f-9d41-7346db7d7da2  ceph client.cinder secret

NOTE:因为挂载的 Ceph Pool: volumes 下的块设备,所以 Libvirt Secret 的 Value 就是 client.cinder 的 key。

介绍为背景后回到导致这个问题的原因,是因为云管人员为了提高安全级别,所以手动的为 client.cinder 用户注入了自定义的密钥(key),但同时只更新了 Cinder 客户端的 keyring,却没有同时更新与之对应的 Libvirt Secret。所以出现问题的现象就是可以创建卷(因为 Cinder 客户端的 ceph.client.cinder.keyring 与 MON 的 keyring 依旧保存对称),但却无法挂载卷(因为 Libvirt Secret 与 MON 的 keyring 没有保持对称)。这个问题的麻烦之处在于只查看表面上的配置是很难判断的,还是要查看 Libvirt Secret 的 Values:

[root@compute ~]# virsh secret-get-value 4810c760-dc42-4e5f-9d41-7346db7d7da2
AQDVgMFcn/7sEhAA1sLOM+CTWkkGGJ47GRqInw==

最终解决的方法自然就是重新生成 Libvirt Secret 并且更新 nova.conf、cinder.conf 配置项了。