K8s使用Ceph纠删码池做持久化卷

  • Ceph侧准备
    • Ceph纠删码相关
    • 创建纠删码规则
    • 创建纠删码池
    • 创建复制集池
    • 创建用户并授权
  • K8s消费ec池
  • 验证
  • (可选)缓存方式

Kubernetes版本:v1.20.4
Ceph版本:v14.2.20(nautilus)
Linux版本:x86_64-Centos7.6
KubeSphere 版本 : v3.1.0
provisioner:rbd.csi.ceph.com

Ceph侧准备

Ceph纠删码相关

Ceph pool有两种保护数据冗余机制,即纠删码(erasure code,简称ec)和复制集(replicated,简称rc)

Ceph pool要保证部分osd损坏时数据不丢失(一般情况下一个disk设置为一个osd);默认情况下创建pool时rule类型选择replicated,即object在多个disk中拷贝保存;pool的另一种rule类型是erasure,这种pool可以节省空间;

纠删码原理
比如 K=3 M=2 K+M=5
这个意思是:
K原始数据盘个数或恢复数据需要的磁盘个数
M校验盘个数或允许出故障的盘个数
使用编码算法,通过K个原始数据生成K+M个新数据
通过任何K个新数据都能还原出原始的K个数据
即允许M个数据盘出故障,数据仍然不会丢失;

参考文档: 浅谈Ceph纠删码_niuanxins的专栏-CSDN博客_ceph 纠删码

我们需要使用rbd作为k8s后端存储,但默认情况下,纠删存储池只能比较好的支持rgw。从L版本开始,纠删存储池支持开启allow_ec_overwrites属性,从而使得纠删存储池可以作为rbd或者cephfs的数据池。支持rbd需要有如下几个条件:

  • 版本大于等于L ceph --version

  • 开启allow_ec_overwrites ceph osd pool set ec_pool allow_ec_overwrites true
    bluestore存储引擎
    方法 ceph daemon osd.0 config show | grep osd_objectstore

  • 纠删存储池不支持omap,需要一个副本存储池存储块设备的元数据等信息。该副本存储池可以初始化为rbd应用,
    在rc池创建image,指定–data-pool为ec池

创建纠删码规则

参考文档: ceph 之 纠删码操作

  • 首先,需要创建 erasure-code-profile ,当然,也可以使用默认的 erasure-code-profile ,列出现有的 erasure-code-profile

ceph osd erasure-code-profile ls

  • 查看指定erasure-code-profile 的详细内容:

ceph osd erasure-code-profile get default

  • 注:删除纠删码配置信息命令

ceph osd erasure-code-profile rm <profile>

  • (可选)自定义erasure-code-profile , 创建一个只用hdd的 erasure-code-profile,我这里没有创建,这里说下方法:
    -ceph osd erasure-code-profile set hdd-3-2 k=3 m=2 crush-device-class=hdd

可用的选项有:

  1. crush-root: the name of the CRUSH node to place data under [default: default].
  2. crush-failure-domain(故障域): the CRUSH type to separate erasure-coded shards across [default: host].
  3. crush-device-class(设备分类): the device class to place data on [default: none, meaning all devices are used].
  4. k and m (and, for the lrc plugin, l): these determine the number of erasure code shards, affecting the resulting CRUSH rule.
  • 根据erasure-code-profile 创建crush rule,注:我这里并没有采用上一步创建的hdd-3-2的erasure-code-profile,直接使用了默认default erasure-code-profile:

ceph osd crush rule create-erasure default default

  • 查看crush rule:

ceph osd crush rule dump default

创建纠删码池

创建一个使用纠删码规则default的pool

ceph osd pool create ec 128 128 default default
语法: osd pool create <int[0-]> {<int[0-]>} {replicated|erasure} [<erasure_code_profile>] {} {}
尽管crush rule 也是根据erasure_code_profile来创建的,但是这里创建纠删码pool的时候,还是需要明确指定erasure_code_profile的
注:pg数量系统不能自动识别,必须根据系统环境计算后指定,计算方法网上较多,自行百度谷歌
由于纠删码池不支持存储omap类型数据,但rbd image的元数据是基于rados的omap实现,所以纠删码池无法创建rbd image,必须创建一个复制集池存放image元数据


如上图报错所示,纠删码池不支持创建image镜像

  • 调优

ceph osd pool set ec 1
目前,这个fast_read 之针对纠删码池有效的

  • 开启allow_ec_overwrites

ceph osd pool set ec allow_ec_overwrites true

创建复制集池

  • 创建一个replication pool来存放image元数据

ceph osd pool create rc 128

  • 检查ceph健康状态

ceph health detail

可以看到有告警,这是因为未设置池子应用类型所致,我们可以将他们均设置为rbd

 ceph osd pool application enable ec rbdceph osd pool application enable rc rbdceph health detail


可以看到已经HEALTH OK了

创建用户并授权

  • 创建用户并授权
    ceph auth get-or-create client.kubernetes-ec mon 'allow r' osd 'allow rwx pool=ec, allow rwx pool=rc' -o /etc/ceph/ceph.client.kubernetes-ec.keyring
  • 查看用户key和权限

ceph auth get client.kubernetes-ec

K8s消费ec池

前置条件:已经安装ceph-rbd-csi,安装步骤请见我的第一篇文档 KubeSphere使用rbd-csi创建快照

  1. 创建secret
  • 查看前面在ceph节点创建的用户的信息

ceph auth get client.kubernetes-ec

[root@ceph01 ~]# ceph auth get client.kubernetes-ec
exported keyring for client.kubernetes-ec
[client.kubernetes-ec]key = AQDyPatgdw0UGRAA3Kkg3uvH9pYr0Epa3TV3rw==caps mon = "allow r"caps osd = "allow rwx pool=ec, allow rwx pool=rc"
  • 创建或修改 vim secret.yaml
---
apiVersion: v1
kind: Secret
metadata:name: csi-rbd-ec-secretnamespace: kube-system
stringData:# Key values correspond to a user name and its key, as defined in the# ceph cluster. User ID should have required access to the 'pool'# specified in the storage classuserID: kubernetes-ec             #  ceph用户userKey: AQDyPatgdw0UGRAA3Kkg3uvH9pYr0Epa3TV3rw==  # 上一步中的key# Encryption passphrase# encryptionPassphrase: test_passphrase
  • 创建secret
    kubectl apply -f secret.yaml
  1. 创建存储类storageclass
  • 创建或修改 vim storageclass.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: csi-rbd-ec-scannotations:storageclass.kubernetes.io/is-default-class: "true"storageclass.kubesphere.io/support-snapshot: 'true'       # 必须置位true,否则 Kubesphere不支持创建快照storageclass.kubesphere.io/supported-access-modes: '["ReadWriteOnce"]'provisioner: rbd.csi.ceph.com
# If topology based provisioning is desired, delayed provisioning of
# PV is required and is enabled using the following attribute
# For further information read TODO<doc>
# volumeBindingMode: WaitForFirstConsumer
parameters:# (required) String representing a Ceph cluster to provision storage from.# Should be unique across all Ceph clusters in use for provisioning,# cannot be greater than 36 bytes in length, and should remain immutable for# the lifetime of the StorageClass in use.# Ensure to create an entry in the configmap named ceph-csi-config, based on# csi-config-map-sample.yaml, to accompany the string chosen to# represent the Ceph cluster in clusterID belowclusterID: b93a2e42-43e1-4975-bc7d-5998ca61a7c4       # ceph集群id  上文中的fsid# (optional) If you want to use erasure coded pool with RBD, you need to# create two pools. one erasure coded and one replicated.# You need to specify the replicated pool here in the `pool` parameter, it is# used for the metadata of the images.# The erasure coded pool must be set as the `dataPool` parameter below.dataPool: ec    # 纠删码存储池# (required) Ceph pool into which the RBD image shall be created# eg: pool: rbdpoolpool: rc    # 复制集存储池# Set thickProvision to true if you want RBD images to be fully allocated on# creation (thin provisioning is the default).thickProvision: "false"# (required) RBD image features, CSI creates image with image-format 2# CSI RBD currently supports `layering`, `journaling`, `exclusive-lock`# features. If `journaling` is enabled, must enable `exclusive-lock` too.# imageFeatures: layering,journaling,exclusive-lockimageFeatures: layering# (optional) mapOptions is a comma-separated list of map options.# For krbd options refer# https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options# For nbd options refer# https://docs.ceph.com/docs/master/man/8/rbd-nbd/#options# mapOptions: lock_on_read,queue_depth=1024# (optional) unmapOptions is a comma-separated list of unmap options.# For krbd options refer# https://docs.ceph.com/docs/master/man/8/rbd/#kernel-rbd-krbd-options# For nbd options refer# https://docs.ceph.com/docs/master/man/8/rbd-nbd/#options# unmapOptions: force# The secrets have to contain Ceph credentials with required access# to the 'pool'.csi.storage.k8s.io/provisioner-secret-name: csi-rbd-ec-secretcsi.storage.k8s.io/provisioner-secret-namespace: kube-systemcsi.storage.k8s.io/controller-expand-secret-name: csi-rbd-ec-secretcsi.storage.k8s.io/controller-expand-secret-namespace: kube-systemcsi.storage.k8s.io/node-stage-secret-name: csi-rbd-ec-secretcsi.storage.k8s.io/node-stage-secret-namespace: kube-system# (optional) Specify the filesystem type of the volume. If not specified,# csi-provisioner will set default as `ext4`.csi.storage.k8s.io/fstype: ext4# (optional) uncomment the following to use rbd-nbd as mounter# on supported nodes# mounter: rbd-nbd# (optional) Prefix to use for naming RBD images.# If omitted, defaults to "csi-vol-".# volumeNamePrefix: "foo-bar-"# (optional) Instruct the plugin it has to encrypt the volume# By default it is disabled. Valid values are "true" or "false".# A string is expected here, i.e. "true", not true.# encrypted: "true"# (optional) Use external key management system for encryption passphrases by# specifying a unique ID matching KMS ConfigMap. The ID is only used for# correlation to configmap entry.# encryptionKMSID: <kms-config-id># Add topology constrained pools configuration, if topology based pools# are setup, and topology constrained provisioning is required.# For further information read TODO<doc># topologyConstrainedPools: |#   [{"poolName":"pool0",#     "dataPool":"ec-pool0" # optional, erasure-coded pool for data#     "domainSegments":[#       {"domainLabel":"region","value":"east"},#       {"domainLabel":"zone","value":"zone1"}]},#    {"poolName":"pool1",#     "dataPool":"ec-pool1" # optional, erasure-coded pool for data#     "domainSegments":[#       {"domainLabel":"region","value":"east"},#       {"domainLabel":"zone","value":"zone2"}]},#    {"poolName":"pool2",#     "dataPool":"ec-pool2" # optional, erasure-coded pool for data#     "domainSegments":[#       {"domainLabel":"region","value":"west"},#       {"domainLabel":"zone","value":"zone1"}]}#   ]reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:- discard
  • 创建 storageclass
    kubectl apply -f storageclass.yaml
  1. 创建酷照类snapshotclass
  • 在K8s节点(192.168.10.182)创建或修改 vim snapshotclass.yaml
---
# Snapshot API version compatibility matrix:
# v1betav1:
#   v1.17 =< k8s < v1.20
#   2.x =< snapshot-controller < v4.x
# v1:
#   k8s >= v1.20
#   snapshot-controller >= v4.x
# We recommend to use {sidecar, controller, crds} of same version
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:name: csi-rbd-ec-sc     #  注意:必须和存储类同名,否则Kubesphere无法创建存储卷对应快照
driver: rbd.csi.ceph.com
parameters:# String representing a Ceph cluster to provision storage from.# Should be unique across all Ceph clusters in use for provisioning,# cannot be greater than 36 bytes in length, and should remain immutable for# the lifetime of the StorageClass in use.# Ensure to create an entry in the configmap named ceph-csi-config, based on# csi-config-map-sample.yaml, to accompany the string chosen to# represent the Ceph cluster in clusterID belowclusterID: b93a2e42-43e1-4975-bc7d-5998ca61a7c4     # ceph集群id,上文的fsid# Prefix to use for naming RBD snapshots.# If omitted, defaults to "csi-snap-".# snapshotNamePrefix: "foo-bar-"csi.storage.k8s.io/snapshotter-secret-name: csi-rbd-ec-secretcsi.storage.k8s.io/snapshotter-secret-namespace: kube-system
deletionPolicy: Delete
  • 创建snapshotclass
    kubectl apply -f snapshotclass.yaml

验证

  1. 使用csi-rbd-ec-sc存储类创建一个pvc,可在后台通过kubectl创建,也可Kubesphere界面操作,这里不再演示 参考 我的第一篇文档 KubeSphere使用rbd-csi创建快照
  2. 将pvc挂载到pod中
  3. 写入5GB数据
    dd if=/dev/zero of=test-file1 bs=10M count=500
  4. 观察结果
  • 到pod所在宿主机观察map结果

rbd showmapped | grep -E rc\|ec

显然挂载的复制集池子

  • 查看池子占用情况

ceph df |grep -E rc\|ec

的确是纠删码池子写入了5GiB数据,而占用了7.6GiB存储空间,符合纠删码K,M定义

  • 查看image情况

rbd ls ec

无image

rbd ls rc

有一个image
这印证了前文所说的复制集存储image元数据,纠删码池存储用户数据。

  • 查看image信息

rbd info rc/172-vo-d3fc8d23-bc54-11eb-bb49-22f8864ed6ad

其中指定了data_pool
这和手动创建image指定–data-pool效果是一致的

rbd create --size 10G --data-pool ec rc/<image_name>

  • 查看池子里的对象
rados -p rc ls


可以看到,复制集池子里只有少量的对象,而纠删码池子有海量的对象(命令是:rados -p ec ls,数据量很大,这里不做展示,请自行查看),符合预期
重点说下rbd_header.7357774f37c这个对象,这个对象存放了rbd image的的一些重要参数,如大小,特性order等等。

rados -p rc listomapvals rbd_header.7357774f37c

资料显示,纠删码池不支持存放如上图所示的omap数据,所以无法在纠删码池上无法直接创建image,具体原因,需要对ceph进行深入研究。

(可选)缓存方式

如果你不想改变原有形式在复制集pool上创建image,例如opendtack nova cinder glance 原生不支持指定 datapool,又不想二次开发,可尝试这种方式,原理是给纠删码池创建一个复制集缓存池,让复制集池覆盖在纠删码池上,将所有的请求都引流到缓存池上,来实现类似在纠删码池上创建image的效果。

参考文档:
ceph 之 纠删码操作
管理ceph缓存池

  1. 创建一个缓存池,也可直接用原有的rc池做缓存池

ceph osd create pool cache 128
2. 设置缓存层

  • 将上面创建的cache池绑定至存储池的前端,ec即为我们的后端存储池

ceph osd tier add ec cache

  • 设置缓存模式为writeback
ceph osd tier cache-mode cache writeback

注:本场景貌似只能设置成 writeback模式,readony会导致创建image失败,需要深入研究
附:几种缓存配置模式 (参考文档: ceph cache teir配置模式以及参数说明)

writeback mode: 当配置为writeback模式时,ceph客户端将数据写入到缓存层并且从缓存层得到已经写入的确认信息。在缓存层中的数据会及时迁移到存储层并且刷新缓存层。当读取数据时,如果数据在缓存层,那么直接在缓存层操作数据,如果缓存没有所需数据,则从存储层将数据读取到缓存层,然后发送给客户端。

readproxy mode : 当配置为此模式时,如果数据在缓存层,则直接操作缓存中的数据,如果不在缓存层,则去存储层操作。假如突然禁用了缓存模式,这种模式则很有用,因为可以直接可以请求存储层。而且在这种模式下,就算缓存耗尽,ceph集群也会从存储层继续提供读写,这样只是IO性能下降了,但是IO还可以继续响应。

readonly mode: 当配置为readonly模式时,Ceph客户端在写数据的时候,直接将数据写入到后端存储层。当读取数据时,Ceph会将请求的对象从存储层复制到缓存层。当在存储层中更新对象时,Ceph不会将这些更新同步到缓存层中相应的对象,所以这个模式在生产环境不推荐使用。

none: 禁用缓存模式。

  • 将所有客户端请求从标准池引导至缓存池
ceph osd tier set-overlay ec cache

其实,不仅纠删码池可以做cache tier,replication 池子也能做cache tier,例如,我们可能有一批ssd盘,我们就可以在ssd上创建pool来充当sas盘的cache tier以提高性能;结合纠删码、replication、sas、ssd,我们可以做出多种不同性能的存储用以应对不同的场景。

  • 如果 ceph 提示: 1 cache pools are missing hit_sets , 还要设置 hit_set_count 和 hit_set_type
ceph osd pool set cache hit_set_count 1
ceph osd pool set cache hit_set_type bloom
  • 设置当缓存池中的数据达到多少个对象时,缓存分层代理就开始从缓存池刷新对象至后端存储池并驱逐:

ceph osd pool set cache target_max_objects 1000
这里为了观察效果,故设置为1000个,实际环境中这个值太小了
还可以设置其他参数,例如

当缓存池中的数据量达到多少字节时开始刷盘并驱逐
ceph osd pool set cache target_max_bytes 10000000000
当脏对象占比达到10%时开始刷盘
ceph osd pool set cache cache_target_dirty_ratio 0.1
当脏对象占比达到60%时开始高速刷盘
cache_target_dirty_high_ratio: 0.6
当缓存池的使用量达到其总量的一定百分比时,缓存分层代理将驱逐对象以维护可用容量(达到该限制时,就认为缓存池满了),此时会将未修改的(干净的)对象刷盘
ceph osd pool set cache cache_target_full_ratio 0.8
定义缓存层将对象刷至存储层或者驱逐的时间:
ceph osd pool set cache cache_min_flush_age 600
ceph osd pool set cache cache_min_evict_age 600
也可将缓存池类型设置为rbdceph osd pool application enable cache rbd
  1. 测试
    可直接在纠删码池直接创建image

rbd create --size 1GiB ec/test.image
是可以成功的,并且cache也有同名的image

rbd ls cache

rbd info cache/test.image
4. 删除缓存池

  • 将缓存模式更改为转发,以便新的和修改的对象刷新至后端存储池:

ceph osd tier cache-mode cache forward

  • 手动刷新

rados -p cache cache-flush-evict-all

  • 查看缓存池以确保所有的对象都被刷新

rados -p cache ls
其实是无法将对象全部刷进ec池的,因为ec池无法存储omap元数控
只好删除image

  • 删除iamge

rbd rm cahce/test.image

  • 删除覆盖层,以使客户端不再将流量引导至缓存

ceph osd tier remove-overlay ec

  • 解除存储池与缓存池的绑定

ceph osd tier remove ec cache

  • 删除缓存池

ceph osd pool delete cache cache --yes-i-really-really-mean-it
注:ceph防止误删,所以命令比较长

K8s使用Ceph纠删码池做持久化卷相关推荐

  1. 「Ceph源码分析」纠删码解码

    存储系统:ceph-14.2.22 操作系统:ubuntu-server-18.04 总体框架 源码分析 ECBackend::objects_read_and_reconstruct [ 文件路径 ...

  2. ceph的压缩、加密、纠删码

    ceph的压缩.加密.纠删码 ① 压缩(Compression ) 对ceph压缩的一写描述: (1)The Ceph Object Gateway supports server-side comp ...

  3. minio分布式集群搭建完全教程(纠删码,数据恢复)

    minio存储 单机测试 minio对象存储: 编译安装: minio 服务器安装: git clone https://gitee.com/mirrors/minio.git cd minio go ...

  4. Ceph 进阶系列(四):Ceph的纠删码特性 EC(Erasure Code)

    从GitHub上Clone Ceph项目,我是基于(ceph version 12.2.11 luminous 版本)的代码来分析的 一.EC(Erasure Code)是什么? Ceph的纠删码特性 ...

  5. 全网最新最全的 HDFS 文件纠删码技术分析

    前言 本文隶属于专栏<1000个问题搞定大数据技术体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见1000个问题搞定大数据技 ...

  6. Erasure-Code(纠删码) 最佳实践

    Erasure-Code(纠删码) 最佳实践 1. 纠删码原理 这个星球产生的数据越来越庞大,差不多2010年开始各大互联网公司大都上线了系统以应对数据膨胀带来的成本增长.Erasure-Code(纠 ...

  7. 分布式系统下的纠删码技术(一) -- Erasure Code (EC)

    近几个月主要参与一个分布式存储系统的纠删码部分(用于数据容错),纠删码在学术界出现比较早,现在ceph,微软的存储系统,Hadoop 3.0等都用了EC.文章会分为多篇,主要将Erasure Code ...

  8. 【海云捷迅云课堂】分布式存储系统纠删码技术分享

    云课堂专题 海云捷迅云课堂专题,旨在秉承开源理念,为大家提供OpenStack技术原理与实践经验,该专题文章均由海云捷迅工程师理论与实践相结合总结而成,如大家有其他想要了解的信息,可留言给我们,我们会 ...

  9. 我慌了,纠删码是什么?我被面试官问蒙了

    几年前去某大厂面试,岗位是:高级运维工程师.一面二面都很顺利,三面是技术总监,问了很多linux操作系统,shell,python,自动化运维等问题,可以说是对答如流,出口成章,滔滔不绝,心里觉得这下 ...

最新文章

  1. java多线程-死锁的一些问题
  2. OVS vxlan(二十八)
  3. python日期函数_python 时间及日期函数
  4. EOS生产区块:解析插件producer_plugin
  5. java地图点线面_openlayers之点,线,面(以城市,河流,省份为例,分别对应点线面)...
  6. 搭建云计算机win10,win10家庭版连接云主机
  7. 用c语言计算1+2+3+......+100
  8. 多学一点(十二)——使用extundelete恢复Linux下误删除文件
  9. (附源码)ssm基于JSP的养老院信息管理系统的设计与实现 毕业设计 211141
  10. 实测 ubuntu 20.04 使用 lidar_imu_calib 功能包 进行 激光雷达与imu标定
  11. HTML中使用360浏览器默认用极速模式
  12. 前端学习笔记(注册页面综合案例html5)
  13. jquery.uploadify php,jQuery上传插件Uploadify的使用方法
  14. 软考是什么?关于软考经验分享
  15. 刘润对谈吴军:给腾讯和所有上进企业的4点建议
  16. 简单谈谈如何提高后台管理系统的易用性、可操作性和人性化程度
  17. Java Nio 之高级搬砖工(FileChannel)二
  18. docsify部署静态文件服务器,云开发 Docsify 文档部署
  19. torchvision transform巨坑
  20. Linux内核4.14版本——mmc core(10)——mmc core主模块(6)mmc请求相关

热门文章

  1. 【小程序】之net::ERR_NAME_NOT_RESOLVED的问题
  2. 《面向对象程序设计(Java)》第四周学习总结
  3. Boost库-功能介绍-Geometry-图形开发库-计算几何-常用功能封装-GraphicalDebugging(二)
  4. Wilson‘s theorem(威尔逊定理)
  5. 小米秋招软件开发笔试题
  6. DH-UAP(大华统一应用开发平台)简介
  7. Excel 2010 VBA 入门 139 创建工作簿级的自定义选项卡
  8. Centos7下安装FastDFS服务
  9. 上网行为管理_上网行为管理如何预防以及屏蔽勒索病毒攻击
  10. 华为OD机试题 - 数据分类(JavaScript)| 代码+思路+重要知识点