热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

理解OpenStack+Ceph(5):OpenStack与Ceph之间的集成[OpenStackIntegrationwithCeph]...

理解OpenStackCeph系列文章:(1)安装和部署(2)CephRBD接口和工具(3&#x

理解 OpenStack + Ceph 系列文章:

(1)安装和部署

(2)Ceph RBD 接口和工具

(3)Ceph 物理和逻辑结构

(4)Ceph 的基础数据结构

(5)Ceph 与 OpenStack 集成的实现

(6)QEMU-KVM 和 Ceph RBD 的 缓存机制总结

(7)Ceph 的基本操作和常见故障排除方法

1. Glance 与 Ceph RBD 集成

1.1 代码

Kilo 版本中,glance-store 代码被从 glance 代码中分离出来了,地址在 https://github.com/openstack/glance_store。

Glance 中与 Ceph 相关的配置项: 

配置项含义默认值
rbd_pool保存rbd 卷的ceph pool 名称images
rbd_userrbd user id,仅仅在使用 cephx 认证时使用none。让 librados 根据 ceph 配置文件决定
rbd_ceph_confCeph 配置文件的完整路径/etc/ceph/ceph.conf
rbd_store_chunk_size卷会被分成对象的大小(单位为 MB)64
Glance_store 使用 rbd 和 rados 模块:
import rados
    import rbd
Glance_store 中新增了文件 /glance_store/_drivers/rbd.py,其中实现了三个类:
  • class StoreLocation(location.StoreLocation) #表示 Glance image 在 RBD 中的location,格式为 "rbd://///"
  • class ImageIterator(object) #实现从 RBD image 中读取数据块
  • class Store(driver.Store): #实现将 RBD 作为Nova 镜像后端(backend)

class Store(driver.Store) 实现的主要方法:

(1)获取 image 数据:根据传入的Glance image location,获取 image 的 IO Interator

def get(self, location, offset=0, chunk_size=None, context=None):return (ImageIterator(loc.pool, loc.image, loc.snapshot, self), self.get_size(location))
1. 根据 location,定位到 rbd image
2. 调用 image.read 方法,按照 chunk size 读取 image data
3. 将 image data 返回调用端

(2)获取 image 的 size

def get_size(self, location, context=None):
1. 找到 store location:loc = location.store_location
2. 使用 loc 中指定的 pool 或者配置的默认pool
3. 建立 connection 和 打开 IO Context:with rbd.Image(ioctx, loc.image, snapshot=loc.snapshot) as image
4. 获取 image.stat() 并获取 “size”

(3)添加 image

def add(self, image_id, image_file, image_size, context=None):
1. 将 image_id 作为 rbd image name:image_name = str(image_id)
2. 创建 rbd image:librbd.create(ioctx, image_name, size, order, old_format=False, features=rbd.RBD_FEATURE_LAYERING)。如果 rbd 支持 RBD_FEATURE_LAYERING 的话,创建一个 clonable snapshot:rbd://fsid/pool/image/snapshot;否则,创建一个 rbd image:rbd://image
3. 调用 image.write 方法将 image_file 的内容按照 chunksize 依次写入 rbd image
4. 如果要创建 snapshot 的话,调用 image.create_snap(loc.snapshot) 和 image.protect_snap(loc.snapshot) 创建snapshot

(4)删除 image

def delete(self, location, context=None):
1. 根据 location 计算出 rbd image,snapshot 和 pool
2. 如果它是一个 snapshot (location 是 rbd://fsid/pool/image/snapshot),则 unprotect_snap,再 remove_snap,然后删除 image;这时候有可能出错,比如存在基于该 image 的 volume。
3. 如果它不是一个 snapshot (location 是 rbd://image),直接删除 rbd image。这操作也可能会出错。

1.2 使用

(1)使用 Ceph RDB 作为后端存储创建一个 Glance image:
root@controller:~/s1# glance image-show 71dc76da-774c-411f-a958-1b51816ec50f
+------------------+----------------------------------------------------------------------------------+
| Property         | Value                                                                            |
+------------------+----------------------------------------------------------------------------------+
| checksum         | 56730d3091a764d5f8b38feeef0bfcef                                                 |
| container_format | bare                                                                             |
| created_at       | 2015-09-18T10:22:49Z                                                             |
| direct_url         | rbd://4387471a-ae2b-47c4-b67e-9004860d0fd0/images/71dc76da-774c-                 |
|                        | 411f-a958-1b51816ec50f/snap   
可见该Glance image 在 Ceph 中其实是个 RBD snapshot,其父 image 为 rbd://4387471a-ae2b-47c4-b67e-9004860d0fd0/images/71dc76da-774c-411f-a958-1b51816ec50f/,snapshot 名称为 “snap”。
查看 rdb:

root@ceph1:~# rbd info images/71dc76da-774c-411f-a958-1b51816ec50f
rbd image
'71dc76da-774c-411f-a958-1b51816ec50f':
size
40162 kB in 5 objects
order
23 (8192 kB objects)
block_name_prefix: rbd_data.103d2246be0e
format:
2
features: layering

Glance 自动创建了它的 snapshot:

root@ceph1:~# rbd snap ls images/71dc76da-774c-411f-a958-1b51816ec50f
SNAPID NAME SIZE
2 snap 40162 kB

查看该 snapshot:

root@ceph1:~# rbd info images/71dc76da-774c-411f-a958-1b51816ec50f@snap
rbd image '71dc76da-774c-411f-a958-1b51816ec50f':
size 40162 kB in 5 objects
order 23 (8192 kB objects)
block_name_prefix: rbd_data.103d2246be0e
format: 2
features: layering
protected: True

基于该 Glance image 创建的 Cinder volume 都是该 snapshot 的 clone:

root@ceph1:~# rbd children images/71dc76da-774c-411f-a958-1b51816ec50f@snap
volumes
/volume-65dbaf38-0b9d-4654-bba4-53f12cc906e3
volumes
/volume-6868a043-1412-4f6c-917f-bbffb1a8d21a

此时如果试着去删除该 image,则会报错:

The image cannot be deleted because it is in use through the backend store outside of Glance.
这是因为该 image 的 rbd image 的 snapshot 被使用了。

2. Cinder 与 Ceph RBD 的集成

OpenStack Cinder 组件和 Ceph RBD 集成的目的是将 Cinder 卷(volume)保存在 Ceph RBD 中。当使用 Ceph RBD 作为 Cinder 的后端存储时,你不需要单独的一个 Cinder-volume 节点.

2.1 配置项

配置项含义默认值
rbd_pool保存rbd 卷的ceph pool 名称rbd
rbd_user访问 RBD 的用户的 ID,仅仅在使用 cephx 认证时使用none
rbd_ceph_confCeph 配置文件的完整路径‘’,表示使用 librados 的默认ceph 配置文件
rbd_secret_uuidrbd secret uuid 
rbd_flatten_volume_from_snapshotRBD Snapshot 在底层会快速复制一个元信息表,但不会产生实际的数据拷贝,因此当从 Snapshot 创建新的卷时,用户可能会期望不要依赖原来的 Snapshot,这个选项开启会在创建新卷时对原来的 Snapshot 数据进行拷贝来生成一个不依赖于源 Snapshot 的卷。false
rbd_max_clone_depth

卷克隆的最大层数,超过的话则使用 fallter。设为 0 的话,则禁止克隆。

与上面这个选项类似的原因,RBD 在支持 Cinder 的部分 API (如从 Snapshot 创建卷和克隆卷)都会使用 rbd clone 操作,但是由于 RBD 目前对于多级卷依赖的 IO 操作不好,多级依赖卷会有比较严重的性能问题。因此这里设置了一个最大克隆值来避免这个问题,一旦超出这个阀值,新的卷会自动被 flatten。

5
rbd_store_chunk_size每个 RBD 卷实际上就是由多个对象组成的,因此用户可以指定一个对象的大小来决定对象的数量,默认是 4 MB4
rados_connect_timeout连接 ceph 集群的超时时间,单位为秒。如果设为负值,则使用默认 librados 中的值-1

从这里也能看出来,

(1)Cinder 不支持单个 volume 的条带化参数设置,而只是使用了公共配置项 rbd_store_chunk_size 来指定 order。

(2)Cinder 不支持卷被附加到客户机时设置缓存模式。

2.2 代码

Cinder 使用的就是之前介绍过的 rbd phthon 模块:

import rados
import rbd

它实现了以下主要接口。

2.2.1 与 RBD 的连接

(1)初始化连接到 RBD 的连接

def initialize_connection(self, volume, connector):
hosts, ports = self._get_mon_addrs() #调用 args = ['ceph', 'mon', 'dump', '--format=json'] 获取 monmap,再获取 hosts 和 ports
data = {'driver_volume_type': 'rbd','data': {'name': '%s/%s' % (self.configuration.rbd_pool, volume['name']), 'hosts': hosts, 'ports': ports, 'auth_enabled': (self.configuration.rbd_user is not None), 'auth_username': self.configuration.rbd_user, 'secret_type': 'ceph', 'secret_uuid': self.configuration.rbd_secret_uuid, } }

(2)连接到 ceph rados

client = self.rados.Rados(rados_id=self.configuration.rbd_user, conffile=self.configuration.rbd_ceph_conf)
client.connect(timeout= self.configuration.rados_connect_timeout)
ioctx = client.open_ioctx(pool)

(3)断开连接

ioctx.close()
client.shutdown()

2.2.2 创建卷

Cinder API:create_volume
调用的是 RBD 的 create 方法来创建 RBD image:

with RADOSClient(self) as client:self.rbd.RBD().create(client.ioctx,encodeutils.safe_encode(volume['name']),size,order,old_format=old_format,features=features)

2.2.3 克隆卷

#创建克隆卷
def create_cloned_volume(self, volume, src_vref):

# 因为 RBD 的 clone 方法是基于 snapshot 的&#xff0c;所有 cinder 会首先创建一个 snapshot&#xff0c;再创建一个 clone。if CONF.rbd_max_clone_depth <&#61; 0: #如果设置的 rbd_max_clone_depth 为负数&#xff0c;则做一个完整的 rbd image copyvol.copy(vol.ioctx, dest_name)
depth &#61; self._get_clone_depth(client, src_name) #判断 volume 对应的 image 的 clone depth&#xff0c;如果已经达到 CONF.rbd_max_clone_depth&#xff0c;则需要做 flattern
src_volume &#61; self.rbd.Image(client.ioctx, src_name) #获取 source volume 对应的 rbd image
#如果需要 flattern&#xff0c;_pool, parent, snap &#61; self._get_clone_info(src_volume, src_name) #获取 parent 和 snapshotsrc_volume.flatten() # 将 parent 的data 拷贝到该 clone 中parent_volume &#61; self.rbd.Image(client.ioctx, parent) #获取 paraent imageparent_volume.unprotect_snap(snap) #将 snap 去保护parent_volume.remove_snap(snap) #删除 snapshot
src_volume.create_snap(clone_snap) #创建新的 snapshot
src_volume.protect_snap(clone_snap) #将 snapshot 加保护
self.rbd.RBD().clone(client.ioctx, src_name, clone_snap, client.ioctx, dest_name, features&#61;client.features) #在 snapshot 上做clone
self._resize(volume) #如果 clone 的size 和 src volume 的size 不一样&#xff0c;则 resiz

3. Nova 与 Ceph 的集成

常规地&#xff0c;Nova 将虚机的镜像文件放在本地磁盘或者Cinder 卷上。为了与 Ceph 集成&#xff0c;Nova 中添加了新的代码来将镜像文件保存在 Ceph 中。

3.1 Nova 与 Ceph 集成的配置项

配置项含义默认值
images_type

其值可以设为下面几个选项中的一个&#xff1a;

  • raw&#xff1a;实现了 class Raw(Image) 类&#xff0c;在 CONF.instances_path 指定的目录中保存 raw 格式的 镜像文件
  • qcow2&#xff1a;实现了 class Qcow2(Image) 类&#xff0c;在 CONF.instances_path 指定的目录中创建和保存 qcow2 格式的镜像文件 [&#39;qemu-img&#39;, &#39;create&#39;, &#39;-f&#39;, &#39;qcow2&#39;]
  • lvm&#xff1a;实现了 class Lvm(Image) 类&#xff0c;在 CONF.libvirt.images_volume_group 指定的 LVM Volume Group 中创建 local vm 来存放 vm images
  • rbd&#xff1a;实现了 class Rbd(Image) 类
  • default&#xff1a;使用 use_cow_images 配置项
default
images_rbd_pool存放 vm 镜像文件的 RBD poolrbd
images_rbd_ceph_confCeph 配置文件的完整路径‘’
hw_disk_discard

设置使用或者不使用discard 模式&#xff0c;使用的话需要 Need Libvirt(1.0.6)、 Qemu1.5 (raw format) 和 Qemu1.6(qcow2 format)&#39;) 的支持

"unmap" : Discard requests("trim" or "unmap") are passed to the filesystem.
"ignore": Discard requests("trim" or "unmap") are ignored and aren&#39;t passed to the filesystem.

none
rbd_userrbd user ID 
rbd_secret_uuidrbd secret UUID  
关于 discard 模式&#xff08;详情见这篇文章&#xff09;&#xff1a;
Discard&#xff0c;在 SSD 上称为 trim&#xff0c;是在磁盘上回收不使用的数据块的机制。默认地 RBD image 是稀疏的&#xff08;thin provision&#xff09;&#xff0c;这意味着只有在你写入数据时物理空间才会被占用。在 OpenStack 虚机中使用 discard 机制需要满足两个条件&#xff1a;
&#xff08;1&#xff09;虚机使用 Virtio-scsi 作为存储接口&#xff0c;而不是使用传统的 Virtio-blk。这是因为 Virtio-scsi 中实现了如下的新的功能&#xff1a;
  • 设备直接暴露给客户机&#xff08;device pass-through to directly expose physical storage devices to guests&#xff09;
  • 更好的性能&#xff08;better performance and support for true SCSI device&#xff09;
  • 标准的设备命名方法&#xff08;common and standard device naming identical to the physical world thus virtualising physical applications is made easier&#xff09;
  • 更好的扩展性&#xff08;better scalability of the storage where virtual machines can attach more device (more LUNs etc…)&#xff09;

要让虚机使用该接口&#xff0c;需要设置 Glance image 的属性&#xff1a;

$ glance image-update --property hw_scsi_model&#61;virtio-scsi --property hw_disk_bus&#61;scsi

&#xff08;2&#xff09;在 nova.conf 中配置 hw_disk_discard &#61; unmap

注意目前 cinder 尚不支持 discard。

3.2 Nova 中实现的 RBD image 操作

Nova 在 \nova\virt\libvirt\imagebackend.py 文件中添加了支持 RBD 的新类 class Rbd(Image) 来支持将虚机的image 放在 RBD 中。其主要方法包括&#xff1a;

&#xff08;1&#xff09;image create API

def create_image(self, prepare_template, base, size, *args, **kwargs):
# 调用
&#39;rbd&#39;, &#39;import&#39; 命令将 image file 的数据保存到 rbd image 中

rbd import 命令&#xff1a;

import [–image-format format-id] [–order bits] [–stripe-unit size-in-B/K/M –stripe-count num] [–image-feature feature-name]... [–image-shared] src-path[image-spec]
Creates a
new image and imports its data from path (use - for stdin). The import operation will try to create sparse rbd images if possible. For import from stdin, the sparsification unit is the data block size of the destination image (1 << order).
The –stripe
-unit and –stripe-count arguments are optional, but must be used together.

虚机创建成功后&#xff0c;在 RBD 中查看创建出来的 image&#xff1a;

root&#64;ceph1:~# rbd ls vms
74cbdb41
-3789-4eae-b22e-5085de8caba8_disk.localroot&#64;ceph1:~# rbd info vms/74cbdb41-3789-4eae-b22e-5085de8caba8_disk.local
rbd image
&#39;74cbdb41-3789-4eae-b22e-5085de8caba8_disk.local&#39;:
size
1024 MB in 256 objects
order
22 (4096 kB objects)
block_name_prefix: rbd_data.11552ae8944a
format:
2
features: layering

查看虚机的 xml 定义文件&#xff0c;能看到虚机的系统盘、临时盘和交换盘的镜像文件都在 RBD 中&#xff0c;而且可以使用特定的 cache 模式&#xff08;由 CONF.libvirt.disk_cachemodes 配置项指定&#xff09;和 discard 模式&#xff08;由 CONF.libvirt.hw_disk_discard 配置项设置&#xff09;&#xff1a;

"network" device&#61;"disk">"raw" cache&#61;"writeback" discard&#61;"unmap"/>"9.115.251.194" port&#61;"6789"/>"9.115.251.195" port&#61;"6789"/>"9.115.251.218" port&#61;"6789"/>"cinder">"ceph" uuid&#61;"e21a123a-31f8-425a-86db-7204c33a6161"/>"virtio" dev&#61;"vdb"/>"network" device&#61;"disk">"qemu" type&#61;"raw" cache&#61;"writeback"/>"9.115.251.194" port&#61;"6789"/>"9.115.251.195" port&#61;"6789"/>"9.115.251.218" port&#61;"6789"/>"cinder">"ceph" uuid&#61;"e21a123a-31f8-425a-86db-7204c33a6161"/>"virtio" dev&#61;"vda"/>6868a043-1412-4f6c-917f-bbffb1a8d21a

    关于 libvirt.disk_cachemodes 配置项&#xff0c;可以指定镜像文件的缓存模式&#xff0c;其值的格式为 ”A&#61;B"&#xff0c;其中&#xff1a;

  • A 可以为 &#39;file&#39;&#xff0c;&#39;block&#39;&#xff0c;&#39;network&#39;&#xff0c;&#39;mount&#39;。其中&#xff0c;file 是针对 file-backend 的disk&#xff08;比如使用 qcow2 格式的镜像文件&#xff09;&#xff0c;block 是针对块设备的disk&#xff08;比如使用 cinder volume 或者 lvm&#xff09;&#xff0c;network 是针对通过网络连接的设备的disk&#xff08;比如 Ceph&#xff09;。
  • B 可以为 none,writethrough,writeback,directsync,unsafe。writethrough 和 writeback 可以参考 理解 OpenStack &#43; Ceph &#xff08;2&#xff09;&#xff1a;Ceph 的物理和逻辑结构&#xff0c;其它的请自行google。
  • 比如&#xff0c;disk_cachemodes&#61;"network&#61;writeback"&#xff0c;disk_cachemodes&#61;"block&#61;writeback"。

   上面的虚机 XML 定义文件是在Nova 配置为 disk_cachemodes&#61;"network&#61;writeback" 和 hw_disk_discard &#61; unmap 的情形下生成的。

&#xff08;2&#xff09;image clone API

def clone(self, context, image_id_or_uri):
1. 通过 Glance API 获取 image 的 rbd location
2. 检查 rbd image 是否可以被克隆&#xff08;检查它是不是在本 ceph cluster 内、是不是 raw 格式、是不是可以访问等&#xff09;
3. 调用 rbd 的 clone 方法来创建 clone

3.3 镜像 clone 而非下载

    使用传统存储作为 image 的后端存储时&#xff0c;在创建虚机的过程中的创建镜像文件时&#xff0c;都是调用  _try_fetch_image_cache 方法来从 Glance 中将镜像文件下载到本地&#xff08;第一次会缓存&#xff0c;以后就直接读缓存而不用下载&#xff09;&#xff0c;然后再创建镜像文件的方法。而在使用 RBD 作为镜像的后端存储时&#xff0c;如果 Glance 镜像文件被保存在 RBD 中&#xff0c;那么该过程将是重复的&#xff08;先通过 Glance 从 RDB 中倒出镜像&#xff0c;然后再由 Nova 放到RBD中&#xff09;&#xff0c;而且是非常耗时的。针对这种情况&#xff0c;Nova 实现了一种新的办法&#xff0c;具体见下面的蓝色字体部分&#xff1a; 

在 Spawn 虚机过程中&#xff0c;一个步骤是 create image&#xff0c;如下的方法会被调用&#xff1a;

def _create_image(self, context, instance,disk_mapping, suffix&#61;&#39;&#39;,disk_images&#61;None, network_info&#61;None,block_device_info&#61;None, files&#61;None,admin_pass&#61;None, inject_files&#61;True,fallback_from_host&#61;None):if not booted_from_volume: #如果不是从 volume 启动虚机root_fname &#61; imagecache.get_cache_fname(disk_images, &#39;image_id&#39;)size &#61; instance.root_gb * units.Gibackend &#61; image(&#39;disk&#39;)if backend.SUPPORTS_CLONE: #如果 image backend 支持 clone 的话&#xff08;目前的各种 image backend&#xff0c;只有 RBD 支持 clone&#xff09;def clone_fallback_to_fetch(*args, **kwargs):backend.clone(context, disk_images[&#39;image_id&#39;]) #直接调用 backend 的 clone 函数做 image clonefetch_func &#61; clone_fallback_to_fetchelse:fetch_func &#61; libvirt_utils.fetch_image #否则走常规的 image 下载-导入过程self._try_fetch_image_cache(backend, fetch_func, context, root_fname, disk_images[&#39;image_id&#39;], instance, size, fallback_from_host)

    可见&#xff0c;当 nova 后端使用 ceph 时&#xff0c;nova driver 调用 RBD imagebackend 命令&#xff0c;直接在 ceph 存储层完成镜像拷贝动作&#xff08;无需消耗太多的nova性能&#xff0c;也无需将镜像下载到hypervisor本地&#xff0c;再上传镜像到ceph&#xff09;&#xff0c;如此创建虚拟机时间将会大大提升。当然&#xff0c;这个的前提是 image 也是保存在 ceph 中&#xff0c;而且 image 的格式为 raw&#xff0c;否则 clone 过程会报错。 具体过程如下&#xff1a;

&#xff08;1&#xff09;这是 Glance image 对应的 rbd image&#xff1a;

root&#64;ceph1:~# rbd info images/0a64fa67-3e34-42e7-b7b0-423c11850e18
rbd image
&#39;0a64fa67-3e34-42e7-b7b0-423c11850e18&#39;:size 564 MB in 71 objectsorder 23 (8192 kB objects)block_name_prefix: rbd_data.16d21e1d755bformat: 2features: layering

&#xff08;2&#xff09;使用该 image 创建第一个虚机

root&#64;ceph1:~# rbd info vms/982b8eac-6bcc-4a21-bd04-b67e26188be0_disk
rbd image
&#39;982b8eac-6bcc-4a21-bd04-b67e26188be0_disk&#39;:size 3072 MB in 384 objectsorder 23 (8192 kB objects)block_name_prefix: rbd_data.130a36a6b435format: 2features: layeringparent: images/0a64fa67-3e34-42e7-b7b0-423c11850e18&#64;snapoverlap: 564 MBroot&#64;ceph1:~# rbd info vms/982b8eac-6bcc-4a21-bd04-b67e26188be0_disk.local
rbd image
&#39;982b8eac-6bcc-4a21-bd04-b67e26188be0_disk.local&#39;:size 2048 MB in 512 objectsorder 22 (4096 kB objects)block_name_prefix: rbd_data.a69b2ae8944aformat: 2features: layeringroot&#64;ceph1:~# rbd info vms/982b8eac-6bcc-4a21-bd04-b67e26188be0_disk.swap
rbd image
&#39;982b8eac-6bcc-4a21-bd04-b67e26188be0_disk.swap&#39;:size 102400 kB in 25 objectsorder 22 (4096 kB objects)block_name_prefix: rbd_data.a69e74b0dc51format: 2features: layering

&#xff08;3&#xff09;创建第二个虚机

root&#64;ceph1:~# rbd info vms/a9670d9a-8aa7-49ba-baf5-9d7a450172f3_disk
rbd image
&#39;a9670d9a-8aa7-49ba-baf5-9d7a450172f3_disk&#39;:size 3072 MB in 384 objectsorder 23 (8192 kB objects)block_name_prefix: rbd_data.13611f6abac6format: 2features: layeringparent: images/0a64fa67-3e34-42e7-b7b0-423c11850e18&#64;snapoverlap: 564 MB

&#xff08;4&#xff09;会看到 Glance image 对应的 RBD image 有两个克隆&#xff0c;分别是上面虚机的系统盘

root&#64;ceph1:~# rbd children images/0a64fa67-3e34-42e7-b7b0-423c11850e18&#64;snap
vms
/982b8eac-6bcc-4a21-bd04-b67e26188be0_disk
vms
/a9670d9a-8aa7-49ba-baf5-9d7a450172f3_disk

 4. 其它集成

除了上面所描述的 Cinder、Nova 和 Glance 与 Ceph RBD 的集成外&#xff0c;OpenStack 和 Ceph 之间还有其它的集成点&#xff1a;

&#xff08;1&#xff09;使用 Ceph 替代 Swift 作为对象存储 &#xff08;网络上有很多比较 Ceph 和 Swift 的文章&#xff0c;比如 1,2,3,&#xff09;

&#xff08;2&#xff09;CephFS 作为 Manila 的后端&#xff08;backend&#xff09;

&#xff08;3&#xff09;Keystone 和  Ceph Object Gateway 的集成&#xff0c;具体可以参考文章 &#xff08;1&#xff09;&#xff08;2&#xff09;

 参考文档&#xff1a;

http://www.sebastien-han.fr/blog/2015/02/02/openstack-and-ceph-rbd-discard/

http://www.sebastien-han.fr/blog/2013/11/26/back-from-icehouse-openstack-summit-ceph-slash-openstack-integration/

http://www.wzxue.com/openstack-cinder-advance/


    本文转自SammyLiu博客园博客&#xff0c;原文链接&#xff1a;http://www.cnblogs.com/sammyliu/p/4838138.html&#xff0c;如需转载请自行联系原作者





推荐阅读
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 本文详细探讨了二元Probit模型及其在实际应用中的重要性。作为一种广义线性模型,Probit模型主要用于处理二分类问题,与Logistic模型类似,但其假设误差项服从标准正态分布。尽管Probit模型在某些领域应用较少,但在特定情境下仍具有独特优势。文章不仅介绍了模型的基本原理,还通过实例分析展示了其在经济学、社会学等领域的具体应用。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 本文详细解析了使用C++实现的键盘输入记录程序的源代码,该程序在Windows应用程序开发中具有很高的实用价值。键盘记录功能不仅在远程控制软件中广泛应用,还为开发者提供了强大的调试和监控工具。通过具体实例,本文深入探讨了C++键盘记录程序的设计与实现,适合需要相关技术的开发者参考。 ... [详细]
  • 在对WordPress Duplicator插件0.4.4版本的安全评估中,发现其存在跨站脚本(XSS)攻击漏洞。此漏洞可能被利用进行恶意操作,建议用户及时更新至最新版本以确保系统安全。测试方法仅限于安全研究和教学目的,使用时需自行承担风险。漏洞编号:HTB23162。 ... [详细]
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • Python多线程编程技巧与实战应用详解 ... [详细]
  • 本文详细介绍了一种利用 ESP8266 01S 模块构建 Web 服务器的成功实践方案。通过具体的代码示例和详细的步骤说明,帮助读者快速掌握该模块的使用方法。在疫情期间,作者重新审视并研究了这一未被充分利用的模块,最终成功实现了 Web 服务器的功能。本文不仅提供了完整的代码实现,还涵盖了调试过程中遇到的常见问题及其解决方法,为初学者提供了宝贵的参考。 ... [详细]
  • Java中不同类型的常量池(字符串常量池、Class常量池和运行时常量池)的对比与关联分析
    在研究Java虚拟机的过程中,笔者发现存在多种类型的常量池,包括字符串常量池、Class常量池和运行时常量池。通过查阅CSDN、博客园等相关资料,对这些常量池的特性、用途及其相互关系进行了详细探讨。本文将深入分析这三种常量池的差异与联系,帮助读者更好地理解Java虚拟机的内部机制。 ... [详细]
  • 本文探讨了一种高效的算法,用于生成所有数字(0-9)的六位组合,允许重复使用数字,并确保这些组合的和等于给定的整数N。该算法通过优化搜索策略,显著提高了计算效率,适用于大规模数据处理和组合优化问题。 ... [详细]
  • MyISAM和InnoDB是MySQL中最为广泛使用的两种存储引擎,每种引擎都有其独特的优势和适用场景。MyISAM引擎以其简单的结构和高效的读取速度著称,适用于以读操作为主、对事务支持要求不高的应用。而InnoDB引擎则以其强大的事务处理能力和行级锁定机制,在需要高并发写操作和数据完整性的场景下表现出色。选择合适的存储引擎应综合考虑业务需求、性能要求和数据一致性等因素。 ... [详细]
  • 虚拟机网络设置与数据库远程连接优化指南
    本文针对个人计算机上虚拟机网络配置与数据库远程连接的问题,提供了一套详细的优化指南。在探讨远程数据库访问前,需确保网络配置正确,特别是桥接模式的设置。通过合理的网络配置,可以有效解决因虚拟机或网络问题导致的连接失败,提升远程访问的稳定性和效率。 ... [详细]
author-avatar
cl357_475
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有