简介
OpenEBS
是一种开源云原生存储解决方案,托管于CNCF
基金会,目前该项目处于沙箱阶段,
OpenEBS
是一组存储引擎,允许您为有状态工作负载(StatefulSet
)和Kubernetes
平台类型选择正确的存储解决方案。 在高层次上,OpenEBS
支持两大类卷——本地卷和复制卷
OpenEBS
是Kubernetes
本地超融合存储解决方案,它管理节点可用的本地存储,并为有状态工作负载提供本地或高可用的分布式持久卷。 作为一个完全的Kubernetes
原生解决方案的另一个优势是,管理员和开发人员可以使用kubectl
、Helm
、 Prometheus
、Grafana
、Weave Scope
等Kubernetes
可用的所有优秀工具来交互和管理OpenEBS
OpenEBS是一款使用Go语言编写的基于容器的块存储开源软件。OpenEBS使得在容器中运行关键性任务和需要数据持久化的负载变得更可靠。
OpenEBS由CloudByte研发,这是一家专业做容器化存储的公司,OpenEBS是其一款开源产品,CloudByte将其在企业级容器存储的经验付诸到该项目中。这个项目的愿景也很简单,就是让需要持久化存储的工作负载中的存储服务能够直接集成在环境中,存储服务可以自动管理,将存储的细节隐藏起来,就像存储系统是另一套基础架构一样。
使用OpenEBS,你可以将有持久化数据的容器,像对待其他普通容器一样来对待。OpenEBS本身也是通过容器来部署的,支持Kubernetes、Swarm、Mesos、Rancher编排调度,存储服务可以分派给每个pod、应用程序、集群或者容器级别,包括:
- 跨节点的数据持久化
- 跨可用区和云厂商的数据同步
- 使用商业硬件和容器引擎来提供高可扩展的块存储
- 与容器编排引擎集成,开发者的应用程序可以自动的配置OpenEBS
- 基于CloudByte在BSD的容器化经验,为用户提供OpenEBS的QoS保证
OpenEBS
能做什么?
OpenEBS
管理k8s
节点上存储,并为k8s
有状态负载(StatefulSet
)提供本地存储卷或分布式存储卷。
- 本地卷(
Local Storage
)
-
OpenEBS
可以使用宿主机裸块设备或分区,或者使用Hostpaths
上的子目录,或者使用LVM
、ZFS
来创建持久化卷 - 本地卷直接挂载到
Stateful Pod
中,而不需要OpenEBS
在数据路径中增加任何开销 -
OpenEBS
为本地卷提供了额外的工具,用于监控、备份/恢复、灾难恢复、由ZFS
或LVM
支持的快照等
- 对于分布式卷(即复制卷)
-
OpenEBS
使用其中一个引擎(Mayastor
、cStor
或Jiva
)为每个分布式持久卷创建微服务 - 有状态
Pod
将数据写入OpenEBS
引擎,OpenEBS
引擎将数据同步复制到集群中的多个节点。OpenEBS
引擎本身作为pod
部署,并由Kubernetes
进行协调。 当运行Stateful Pod
的节点失败时,Pod
将被重新调度到集群中的另一个节点,OpenEBS
将使用其他节点上的可用数据副本提供对数据的访问 - 有状态的
Pods
使用iSCSI
(cStor
和Jiva
)或NVMeoF
(Mayastor
)连接OpenEBS
分布式持久卷 -
OpenEBS cStor
和Jiva
专注于存储的易用性和持久性。它们分别使用自定义版本的ZFS
和Longhorn
技术将数据写入存储。OpenEBS Mayastor
是最新开发的以耐久性和性能为设计目标的引擎,高效地管理计算(大页面、核心)和存储(NVMe Drives
),以提供快速分布式块存储
注意:
OpenEBS
分布式块卷被称为复制卷,以避免与传统的分布式块存储混淆,传统的分布式块存储倾向于将数据分布到集群中的许多节点上。 复制卷是为云原生有状态工作负载设计的,这些工作负载需要大量的卷,这些卷的容量通常可以从单个节点提供,而不是使用跨集群中的多个节点分片的单个大卷
对比传统分布式存储
OpenEBS
与其他传统存储解决方案不同的几个关键方面:
- 使用微服务体系结构构建,就像它所服务的应用程序一样。
OpenEBS
本身作为一组容器部署在Kubernetes
工作节点上。使用Kubernetes
本身来编排和管理OpenEBS
组件 - 完全建立在用户空间,使其高度可移植性,以运行在任何操作系统/平台。
- 完全意图驱动,继承了
Kubernetes
易用性的相同原则 -
OpenEBS
支持一系列存储引擎,因此开发人员可以部署适合于其应用程序设计目标的存储技术。 像Cassandra
这样的分布式应用程序可以使用LocalPV
引擎进行最低延迟的写操作。 像MySQL
和PostgreSQL
这样的单片应用程序可以使用使用NVMe
和SPDK
构建的Mayastor
或基于ZFS
的cStor
来实现弹性。 像Kafka
这样的流媒体应用程序可以在边缘环境中使用NVMe
引擎Mayastor
以获得最佳性能。
驱使用户使用OpenEBS
的主要原因是:
- 在所有的
Kubernetes
发行版上都是可移植的 - 提高了开发人员和平台
SRE
的生产力 - 与其他解决方案相比,易于使用
- 优秀的社区支持
- 免费开源
本地卷类型
本地卷只能从集群中的单个节点访问。必须在提供卷的节点上调度使用Local Volume
的Pods
。 本地卷通常是分布式工作负载的首选,比如Cassandra
、MongoDB
、Elastic
等,这些工作负载本质上是分布式的,并且内置了高可用性(分片)
根据附加到Kubernetes
工作节点上的存储类型,您可以从不同的动态本地PV
进行选择——Hostpath
、Device
、LVM
、ZFS
或Rawfile
可复制卷类型
复制卷
顾名思义,是指将数据同步复制到多个节点的卷。卷可以支持节点故障。还可以跨可用性区域设置复制,以帮助应用程序跨可用性区域移动。
复制卷还能够提供像快照、克隆、卷扩展等企业存储特性。复制卷是有状态工作负载(如Percona/MySQL
、Jira
、GitLab
等)的首选。
根据附加到Kubernetes
工作节点的存储类型和应用程序性能需求,您可以从Jiva、cStor
或Mayastor
中进行选择
OpenEBS存储引擎建议
应用需求
存储类型
OpenEBS卷类型
低时延、高可用性、同步复制、快照、克隆、精简配置
SSD/云存储卷
OpenEBS Mayastor
高可用性、同步复制、快照、克隆、精简配置
机械/SSD/云存储卷
OpenEBS cStor
高可用性、同步复制、精简配置
主机路径或外部挂载存储
OpenEBS Jiva
低时延、本地PV
主机路径或外部挂载存储
Dynamic Local PV - Hostpath, Dynamic Local PV - Rawfile
低时延、本地PV
本地机械/SSD/云存储卷等块设备
Dynamic Local PV - Device
低延迟,本地PV,快照,克隆
本地机械/SSD/云存储卷等块设备
OpenEBS Dynamic Local PV - ZFS , OpenEBS Dynamic Local PV - LVM
总结:
- 多机环境,如果有额外的块设备(非系统盘块设备)作为数据盘,选用
OpenEBS Mayastor
、OpenEBS cStor
- 多机环境,如果没有额外的块设备(非系统盘块设备)作为数据盘,仅单块系统盘块设备,选用
OpenEBS Jiva
- 单机环境,建议本地路径
Dynamic Local PV - Hostpath, Dynamic Local PV - Rawfile
,由于单机多用于测试环境,数据可靠性要求较低。
由此看来,OpenEBS
常用场景为以上三个场景
OpenEBS特性
容器附加存储
OpenEBS
是一个容器附加存储(Container Attached Storage, CAS
)的例子。 通过OpenEBS
提供的卷总是被容器化。每个卷都有一个专用的存储控制器,用于提高有状态应用程序的持久性存储操作的敏捷性和粒度。
同步复制
同步复制是OpenEBS
的一个可选的流行特性。 当与Jiva
、cStor
和Mayastor
存储引擎一起使用时,OpenEBS
可以同步复制数据卷以实现高可用性。 跨Kubernetes
区域进行复制,从而为跨AZ
设置提供高可用性。 这个特性对于使用GKE、EKS
和AKS
等云提供商服务上的本地磁盘构建高可用状态应用程序特别有用
快照和克隆
写时拷贝快照是OpenEBS
另一个可选的流行特性。 使用cStor
引擎时,快照是瞬时创建的,并且不受快照个数的限制。 增量快照功能增强了跨Kubernetes
集群和跨不同云提供商或数据中心的数据迁移和可移植性。 对快照和克隆的操作完全以Kubernetes
原生方法执行,使用标准kubectl
命令。 常见的用例包括用于备份的高效复制和用于故障排除或针对数据的只读副本进行开发的克隆
备份和恢复
OpenEBS
卷的备份和恢复可以通过开源的OpenEBS Velero
插件与Kubernetes
备份和恢复解决方案(如Velero
(前身为Heptio Ark
))协同工作。 经常使用OpenEBS
增量快照功能,将数据备份到AWS S3、GCP object storage、MinIO
等对象存储目标。 这种存储级别的快照和备份只使用增量数据进行备份,节省了大量的带宽和存储空间。
真正的
Kubernetes
云原生存储
OpenEBS
是Kubernetes
上有状态应用程序的云原生存储,云原生
意味着遵循松散耦合的体系结构。 因此,云原生、松散耦合体系结构的一般好处是适用的。 例如,开发人员和DevOps
架构师可以使用标准的Kubernetes
技能和实用程序来配置、使用和管理持久存储需求
减少存储
TCO
高达50%
在大多数云上,块存储的收费是基于购买的多少,而不是使用的多少; 为了实现更高的性能,并在充分利用容量时消除中断的风险,容量经常被过度配置。 OpenEBS
的精简配置能力可以共享本地存储或云存储,然后根据需要增加有状态应用程序的数据量。 可以动态添加存储,而不会中断暴露给工作负载或应用程序的卷。 某些用户报告说,由于使用了OpenEBS
的精简配置,节省了超过60%
的资源。
高可用性
由于OpenEBS
遵循CAS
架构,在节点故障时,Kubernetes
将重新调度OpenEBS
控制器,而底层数据则通过使用一个或多个副本来保护。 更重要的是——因为每个工作负载都可以利用自己的OpenEBS
——不存在因存储丢失而导致系统大范围宕机的风险。 例如,卷的元数据不是集中的,它可能会像许多共享存储系统那样受到灾难性的通用中断的影响。 相反,元数据保持在卷的本地。丢失任何节点都会导致只存在于该节点上的卷副本的丢失。 由于卷数据至少在其他两个节点上进行了同步复制,因此当一个节点出现故障时,这些数据将在相同的性能级别上继续可用
OpenESB架构介绍
OpenESB
遵循容器附加存储(CAS
)模型,每个卷都有一个专用的控制器POD
和一组副本POD
。 CAS
体系结构的优点在CNCF博客
上进行了讨论。 OpenEBS
操作和使用都很简单,因为它看起来和感觉上就像其他云原生和Kubernetes
友好的项目。
OpenEBS
有许多组件,可以分为以下类别:
- 控制面组件 -
Provisioner
,API Server
,volume exports
,volume sidecars
- 数据面组件 -
Jiva
、cStor
- 节点磁盘管理器 -
Discover
,monitor
, 管理连接k8s
的媒介 - 与云原生工具的集成 - 已经与
Prometheus
,Grafana
,Fluentd
、Jaeger
集成
控制面
OpenEBS
集群的控制平面通常被称为Maya
OpenEBS
控制平面负责提供卷、相关的卷操作,如快照、克隆、创建存储策略、执行存储策略、导出Prometheus/grafana
使用的卷指标,等等。
OpenEBS
提供了一个动态提供程序,这是Kubernetes
的标准外部存储插件。 OpenEBS PV
提供者的主要任务是向应用程序PODS
启动卷供应,并实现PV
的Kubernetes
规范。
m-apiserver
开放存储的REST API
,并承担大量卷策略处理和管理工作。
控制平面和数据平面之间的连通性使用Kubernetes sidecar
模式。控制平面需要与数据平面通信的场景如下所示。
- 对于卷的统计,如
IOPS
,吞吐量,延迟等--通过卷暴漏的sidecar
实现 - 使用卷控制器
pod
执行卷策略,使用卷副本pod
进行磁盘/池管理-通过卷管理sidecar
实现
OpenEBS PV Provisioner
此组件作为POD
运行,并做出配置决策,它的使用方式是:
开发人员用所需的卷参数构造一个声明,选择适当的存储类,并在YAML
规范上调用kubelet
。 OpenEBS PV
动态提供程序与maya-apiserver
交互,在适当的节点上为卷控制器pod
和卷副本pod
创建部署规范。 可以使用PVC
规范中的注释来控制卷Pod
(控制器/副本)的调度。
目前,OpenEBS Provisioner
只支持一种绑定类型,即iSCSI
。
Maya-ApiServer
m-apiserver
作为POD
运行。顾名思义,m-apiserver
公开OpenEBS REST api
m-apiserver
还负责创建创建卷pod
所需的部署规范文件。 在生成这些规范文件之后,它将调用kube-apiserver
来相应地调度这些pods
。 OpenEBS PV
提供者在卷发放结束时,将创建一个PV
对象并将其挂载到应用程序pod
上。 PV
由控制器pod
承载,控制器pod
由不同节点中的一组副本pod
支持。 控制器pod
和复制pod
是数据平面的一部分,在存储引擎部分有更详细的描述。
m-apiserver
的另一个重要任务是卷策略管理。OpenEBS
为表示策略提供了非常细粒度的规范。 m-apiserver
解释这些YAML
规范,将它们转换为可执行的组件,并通过容量管理sidecar
来执行它们
Maya Volume Exporter
Maya
卷导出器是每个存储控制器pod
的sidecar
这些sidecar
将控制平面连接到数据平面以获取统计信息。统计信息的粒度在卷级别。一些统计数据示例如下:
- 卷读取延迟
- 卷写入延迟
- 卷每秒读取速度
- 卷每秒写入速度
- 读取块大小
- 写入块大小
- 容量统计
这些统计信息通常由Prometheus
客户端来拉取,该客户端在OpenBS
安装期间安装和配置
卷管理
sidecar
Sidecars
还用于将控制器配置参数和卷策略传递给卷控制器pod
(卷控制器pod
是一个数据平面), 并将副本配置参数和副本数据保护参数传递给卷副本pod
。
数据面
OpenEBS
数据平面负责实际的卷IO
路径。存储引擎在数据平面实现实际的IO
路径。 目前,OpenEBS
提供了两个可以轻松插入的存储引擎。它们被称为Jiva
和cStor
。 这两个存储引擎都完全运行在Linux
用户空间中,并基于微服务架构。
Jiva
Jiva
存储引擎基于Rancher's LongHorn
与gotgt
开发实现, 使用go
语言开发,并运行于用户命名空间下。 LongHorn
控制器将输入的IO
同步复制到LongHorn
副本。该副本将Linux
稀疏文件视为构建存储特性(如精简配置、快照、重建等)的基础。
cStor
cStor
数据引擎使用C
语言编写,具有高性能的iSCSI target
和Copy-On-Write
块系统,提供数据完整性、数据弹性和时间点的快照和克隆。 cStor
有一个池特性,它以条带、镜像或RAIDZ
模式聚合一个节点上的磁盘,以提供更大的容量和性能单位。 cStor
还可以跨区域将数据同步复制到多个节点,从而避免节点丢失或节点重启导致数据不可用。
LocalPV
对于那些不需要存储级复制的应用程序,LocalPV
可能是很好的选择,因为它能提供更高的性能。 OpenEBS LocalPV
与Kubernetes LocalPV
类似,不同之处在于它是由OpenEBS
控制平面动态提供的, 就像任何其他常规PV
一样。OpenEBS LocalPV
有两种类型:hostpath LocalPV
和device LocalPV
。 hostpath LocalPV
指的是主机上的子目录,LocalPV
指的是在节点上发现的磁盘(可以是直接连接的,也可以是网络连接的)。 OpenEBS
引入了一个LocalPV
提供者,用于根据PVC
和存储类规范中的一些标准选择匹配的磁盘或主机路径。
节点磁盘管理器
节点磁盘管理器(NDM
)填补了使用Kubernetes
管理有状态应用程序的持久存储所需的工具链的空白。 容器时代的DevOps
架构师必须以一种自动化的方式满足应用程序和应用程序开发人员的基础设施需求, 这种方式可以跨环境提供弹性和一致性。这些要求意味着存储堆栈本身必须非常灵活, 以便Kubernetes
和云原生生态系统中的其他软件可以轻松地使用这个堆栈。 NDM
在Kubernetes
的存储堆栈中起着基础性的作用,它统一了不同的磁盘, 并通过将它们标识为Kubernetes
对象,提供了将它们汇聚的能力。 此外,NDM
发现、提供、监视和管理底层磁盘的方式,可以让Kubernetes PV
提供者(如OpenEBS
和其他存储系统)和Prometheus
管理磁盘子系统
CAS引擎
存储引擎概述
存储引擎是持久化卷IO
路径的数据平面组件。 在CAS
架构中,用户可以根据不同的配置策略,为不同的应用工作负载选择不同的数据平面。 存储引擎可以通过特性集或性能优化给定的工作负载。
操作员或管理员通常选择具有特定软件版本的存储引擎,并构建优化的卷模板, 这些卷模板根据底层磁盘的类型、弹性、副本数量和参与Kubernetes
集群的节点集进行微调。 用户可以在发放卷时选择最优的卷模板,从而在给定的Kubernetes
集群上为所有存储卷运行最优的软件和存储组合提供最大的灵活性。
存储引擎类型
OpenEBS
提供了三种存储引擎
-
Jiva
-
Jiva
是OpenEBS 0.1
版中发布的第一个存储引擎,使用起来最简单。它基于GoLang
开发,内部使用LongHorn
和gotgt
堆栈。Jiva
完全在用户空间中运行,并提供同步复制等标准块存储功能。Jiva
通常适用于容量较小的工作负载,不适用于大量快照和克隆特性是主要需求的情况 -
cStor
-
cStor
是OpenEBS 0.7
版本中最新发布的存储引擎。cStor
非常健壮,提供数据一致性,很好地支持快照和克隆等企业存储特性。 它还提供了一个健壮的存储池特性,用于在容量和性能方面进行全面的存储管理。cStor
与NDM
(Node Disk Manager
)一起,为Kubernetes
上的有状态应用程序提供完整的持久化存储特性 -
OpenEBS Local PV
-
OpenEBS Local PV
是一个新的存储引擎,它可以从本地磁盘或工作节点上的主机路径创建持久卷或PV
。CAS
引擎可以从OpenEBS
的1.0.0
版本中获得。使用OpenEBS Local PV
,性能将等同于创建卷的本地磁盘或文件系统(主机路径)。 许多云原生应用程序可能不需要复制、快照或克隆等高级存储特性,因为它们本身就提供了这些特性。这类应用程序需要以持久卷的形式访问管理的磁盘 -
SP
存储池,表示Jiva
自定义存储资源 -
CV
cStor
卷,表示cStor
卷自定义资源 -
CVR
cStor
卷副本 -
SPC
存储池声明,表示cStor
池聚合的自定义资源 -
CSP
cStor
存储池,表示cStor Pool
每个节点上的自定义资源
一个SPC
对应多个CSP
,相应的一个CV
对应多个CVR
存储引擎声明
通过指定注释openebs
来选择存储引擎。 StorageClass
规范中的io/cas-type
。StorageClass
定义了提供程序的细节。为每个CAS
引擎指定单独的供应程序。
cStor
存储类规范文件内容
---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: cStor-storageclass annotations: openebs.io/cas-type: cstor cas.openebs.io/config: | - name: StoragePoolClaim value: "cStorPool-SSD"provisioner: openebs.io/provisioner-iscsi---
Jiva
存储类规范文件内容
---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: jiva-storageclass annotations: openebs.io/cas-type: jiva cas.openebs.io/config: | - name: StoragePool value: defaultprovisioner: openebs.io/provisioner-iscsi---
当cas
类型为Jiva
时,StoragePool
的default
值具有特殊含义。 当pool
为默认值时,Jiva
引擎将从容器(副本pod
)本身的存储空间中为副本pod
开辟数据存储空间。 当所需的卷大小很小(比如5G
到10G
)时,StoragePool default
工作得很好,因为它可以容纳在容器本身内。
Local PV
存储类规范文件内容-主机路径
---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: localpv-hostpath-sc annotations: openebs.io/cas-type: local cas.openebs.io/config: | - name: BasePath value: "/var/openebs/local" - name: StorageType value: "hostpath"provisioner: openebs.io/local---
Local PV
存储类规范文件内容-主机设备
---apiVersion: storage.k8s.io/v1kind: StorageClassmetadata: name: localpv-device-sc annotations: openebs.io/cas-type: local cas.openebs.io/config: | - name: StorageType value: "device" - name: FSType value: ext4provisioner: openebs.io/local---
cStor
、Jiva
、LocalPV
特性比较:
特性
Jiva
cStor
Local PV
轻量级运行于用户空间
Yes
Yes
Yes
同步复制
Yes
Yes
No
适合低容量工作负载
Yes
Yes
Yes
支持快照,克隆
Basic
Advanced
No
数据一致性
Yes
Yes
NA
使用Velero恢复备份
Yes
Yes
Yes
适合高容量工作负载
No
Yes
Yes
自动精简配置
Yes
No
磁盘池或聚合支持
Yes
No
动态扩容
Yes
Yes
数据弹性(RAID支持)
Yes
No
接近原生磁盘性能
No
No
Yes
大多数场景推荐cStor
,因其提供了强大的功能,包括快照/克隆、存储池功能(如精简资源调配、按需扩容等)。
Jiva
适用于低容量需求的工作负载场景,例如5
到50G
。 尽管使用Jiva
没有空间限制,但建议将其用于低容量工作负载。 Jiva
非常易于使用,并提供企业级容器本地存储,而不需要专用硬盘。 有快照和克隆功能的需求的场景,优先考虑使用cStor
而不是Jiva
。
CAS引擎使用场景
如上表所示,每个存储引擎都有自己的优势。 选择引擎完全取决于应用程序的工作负载以及它当前和未来的容量和/或性能增长。 下面的指导原则在定义存储类时为选择特定的引擎提供一些帮助。
选择
cStor
的理想条件
- 当需要同步复制数据并在节点上有多个磁盘时
- 当您从每个节点上的本地磁盘或网络磁盘池管理多个应用程序的存储时。 通过精简配置、存储池和卷的按需扩容、存储池的性能按需扩容等特性,实现对存储层的管理。
cStor
用于在本地运行的Kubernetes
集群上构建Kubernetes
本地存储服务,类似于AWS EBS
或谷歌PD
。 - 当需要存储级快照和克隆能力时
- 当您需要企业级存储保护特性,如数据一致性、弹性(
RAID
保护)。 - 如果您的应用程序不需要存储级复制,那么使用
OpenEBS
主机路径LocalPV
或OpenEBS
设备LocalPV
可能是更好的选择。
选择
Jiva
的理想条件:
- 当您想要数据的同步复制,并且拥有单个本地磁盘或单个管理磁盘(如云磁盘(
EBS
、GPD
)),并且不需要快照或克隆特性时 -
Jiva
是最容易管理的,因为磁盘管理或池管理不在这个引擎的范围内。Jiva
池是本地磁盘、网络磁盘、虚拟磁盘或云磁盘的挂载路径。 - 以下场景
Jiva
更优于cStor
:
- 当程序不需要存储级的快照、克隆特性
- 当节点上没有空闲磁盘时。
Jiva
可以在主机目录上使用,并且仍然可以实现复制。 - 当不需要动态扩展本地磁盘上的存储时。将更多磁盘添加到
Jiva
池是不可能的,因此Jiva
池的大小是固定的,如果它在物理磁盘上。 但是,如果底层磁盘是虚拟磁盘、网络磁盘或云磁盘,则可以动态地更改Jiva
池的大小 - 容量需求较小。大容量应用通常需要动态增加容量,
cStor
更适合这种需求
选择
OpenEBS
主机路径LocalPV
的理想条件:
- 当应用程序本身具备管理复制能力(例如:
es
)时,不需要在存储层进行复制。在大多数这样的情况下,应用程序是作为statefulset
部署的 - 高于
Jiva
与cStor
的读写性能需求 - 当特定应用程序没有专用的本地磁盘或特定应用程序不需要专用的存储时,建议使用
Hostpath
。 如果您想跨多个应用程序共享一个本地磁盘,主机路径LocalPV
是正确的方法
选择
OpenEBS
主机设备LocalPV
的理想条件:
- 当应用程序管理复制本身,不需要在存储层进行复制时。在大多数这种情况下,应用程序被部署为有状态集
- 高于
Jiva
与cStor
的读写性能需求 - 高于
OpenEBS
主机路径LocalPV
的读写性能需求 - 当需要接近磁盘性能时。该卷专用于写入单个
SSD
或NVMe
接口以获得最高性能
总结
- 如果应用程序处于生产中,并且不需要存储级复制,那么首选
LocalPV
- 如果您的应用程序处于生产状态,并且需要存储级复制,那么首选
cStor
- 如果应用程序较小,需要存储级复制,但不需要快照或克隆,则首选
Jiva
节点磁盘管理器(NDM
)
节点磁盘管理器(NDM
)是OpenEBS
体系结构中的一个重要组件。 NDM
将块设备视为需要监视和管理的资源,就像CPU
、内存和网络等其他资源一样。 它是一个在每个节点上运行的守护进程,基于过滤器检测附加的块设备,并将它们作为块设备自定义资源加载到Kubernetes
中。这些定制资源旨在通过提供类似于:
- 轻松访问
Kubernetes
集群中可用的块设备清单 - 预测磁盘的故障,以帮助采取预防措施
- 允许动态地将磁盘挂载/卸载到存储
Pod
中,而无需重新启动在磁盘挂载/卸载的节点上运行的相应NDM Pod
尽管做了上述所有工作,NDM
还是有助于提供持久卷的总体简化。
NDM
是在OpenEBS
安装期间作为守护进程部署的。NDM daemonset
发现每个节点上的磁盘,并创建一个名为Block Device
或BD
的自定义资源。
访问权限说明
NDM
守护进程运行在容器中,必须访问底层存储设备并以特权模式运行。 NDM
需要特权模式,因为它需要访问/dev、/proc
和/sys
目录来监视附加设备,还需要使用各种探测器获取附加设备的详细信息。 NDM
负责发现块设备并过滤掉不应该被OpenEBS
使用的设备;例如,检测有OS
文件系统的磁盘。 NDM pod
默认情况下在容器中挂载主机的/proc
目录,然后加载/proc/1/mounts
,以找到操作系统使用的磁盘
NDM
守护程序功能
- 发现
Kubernetes
节点上的块设备
- 在启动时发现块设备-创建和/或更新状态。
- 维护集群范围内磁盘的唯一
id
: 对WWN / PartitionUUID / FileSystemUUID / DeviceMapperUUID
进行Hash
计算
- 检测节点中添加/移除块设备,并更新块设备状态
- 添加块设备作为
Kubernetes
自定义资源,具有以下属性:
spec
: 如果可用,将更新以下内容
- 设备路径
- 设备链接
- 供应商和型号信息
-
WWN
和序列号 - 容量
- 扇区和区块大小
labels
:
- 主机名称(
kubernetes.io/hostname
) - 块设备类型(
ndm.io/blockdevice-type
) - Managed (
ndm.io/managed
)
status
: 状态可以有以下值
-
Active
: 节点上存在块设备 -
Inactive
: 给定节点上不存在块设备 -
Unknown
:NDM
在块设备最后被检测到的节点上停止/无法确定状态
过滤器
- 为要创建块设备
CR
的块设备类型配置过滤器。过滤器可以通过供应商类型、设备路径模式或挂载点进行配置 - 过滤器可以是包含过滤器,也可以是排除过滤器。它们被配置为
configmap
。 管理员用户可以在OpenEBS
安装时通过更改OpenEBS
操作员yaml
文件或helm
值中的NDM configmap
来配置这些过滤器。yaml
文件。如果这些过滤器需要在安装后更新,那么可以遵循以下方法之一:
- 使用
operator
方式安装OpenEBS
。在Yaml
文件中,更新configmap
中的过滤器并应用operator.yaml
- 如果
OpenEBS
是使用helm
安装的,更新values.yaml
中的configmap
并使用helm
进行升级 - 或者,使用
kubectl
编辑NDM configmap
,更新过滤器
安装
所有K8S计算节点均要安装iSCSI 启动器
yum install iscsi-initiator-utils -y
systemctl enable --now iscsid
systemctl start iscsid.service
systemctl status iscsid.service
安装OpenEBS
kubectl create ns openebs
kubectl apply -f https://openebs.github.io/charts/openebs-operator.yaml
kubectl get pods -n openebs
查看启动服务和存储
kubectl get all -n openebs
[root@k8s-master openebs]# kubectl get pod -nopenebs
NAME READY STATUS RESTARTS AGE
maya-apiserver-f9f7c6bb7-qxbnw 1/1 Running 2 3h55m
openebs-admission-server-7b9d59c456-cj5r7 1/1 Running 0 3h55m
openebs-localpv-provisioner-6f67fb4868-wjnwq 1/1 Running 0 3h55m
openebs-ndm-6b5vd 1/1 Running 0 3h55m
openebs-ndm-8tpmt 1/1 Running 0 3h55m
openebs-ndm-ccrk2 1/1 Running 0 3h55m
openebs-ndm-operator-58bc5f4d47-snv7h 1/1 Running 0 3h55m
openebs-ndm-wbskl 1/1 Running 0 3h55m
openebs-provisioner-76cd669b6-tn7d4 1/1 Running 0 3h55m
openebs-snapshot-operator-54d76b9-lwj7s 2/2 Running 0 3h55m
[root@k8s-master openebs]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
openebs-jiva-default openebs.io/provisioner-iscsi Delete Immediate false 3h54m
openebs-snapshot-promoter volumesnapshot.external-storage.k8s.io/snapshot-promoter Delete Immediate false 3h54m
ssd-storage kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 17d
创建动态Local PV的存储类SC
[root@k8s-master openebs]# cat local-device-sc-hostpath.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-hostpath
annotations:
openebs.io/cas-type: local
cas.openebs.io/config: |
- name: StorageType
value: hostpath
- name: BasePath
value: /home/openebs/local ####更改对应的存储路径
provisioner: openebs.io/local
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
[root@k8s-master openebs]# kubectl apply -f local-device-sc-hostpath.yaml
storageclass.storage.k8s.io/local-hostpath unchanged
[root@k8s-master openebs]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-device openebs.io/local Delete WaitForFirstConsumer false 98m
local-hostpath openebs.io/local Delete WaitForFirstConsumer false 76m
openebs-jiva-default openebs.io/provisioner-iscsi Delete Immediate false 4h
openebs-snapshot-promoter volumesnapshot.external-storage.k8s.io/snapshot-promoter Delete Immediate false 4h
ssd-storage kubernetes.io/no-provisioner Delete WaitForFirstConsumer false 17d
设置local-hostpath为默认存储
[root@k8s-master openebs]# kubectl patch storageclass local-hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
storageclass.storage.k8s.io/local-hostpath patched
[root@k8s-master openebs]# kubectl describe sc/local-hostpath
Name: local-hostpath
IsDefaultClass: Yes
Annotations: cas.openebs.io/config=- name: StorageType
value: hostpath
- name: BasePath
value: /home/openebs/local
,kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{"cas.openebs.io/config":"- name: StorageType\n value: hostpath\n- name: BasePath\n value: /home/openebs/local\n","openebs.io/cas-type":"local"},"name":"local-hostpath"},"provisioner":"openebs.io/local","reclaimPolicy":"Delete","volumeBindingMode":"WaitForFirstConsumer"}
,openebs.io/cas-type=local,storageclass.kubernetes.io/is-default-class=true
Provisioner: openebs.io/local
Parameters: <none>
AllowVolumeExpansion: <unset>
MountOptions: <none>
ReclaimPolicy: Delete
VolumeBindingMode: WaitForFirstConsumer
Events: <none>
创建测试实例验证
[root@k8s-master openebs]# cat local-sc-pod.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-hostpath-pvc
spec:
storageClassName: local-hostpath
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5G
---
apiVersion: v1
kind: Pod
metadata:
name: hello-local-hostpath-pod
spec:
volumes:
- name: local-storage
persistentVolumeClaim:
claimName: local-hostpath-pvc
containers:
- name: hello-container
image: busybox
command:
- sh
- -c
- 'while true; do echo "`date` [`hostname`] Hello from OpenEBS Local PV." >> /mnt/store/greet.txt; sleep $(($RANDOM % 5 + 300)); done'
volumeMounts:
- mountPath: /mnt/store
name: local-storage