金融级IT架构与运维:云原生、分布式与安全
上QQ阅读APP看书,第一时间看更新

4.3 容器原生存储的选择

在容器云中,Pod会经常被创建和销毁,也会在不同的主机之间快速迁移。为了保证容器在重启或者迁移以后能够使用原来的数据,容器必须使用持久化存储。因此,持久化存储的管理对于PaaS平台来说非常重要。

Kubernetes/OpenShift通过PV(PVC)管理持久化存储。PV分为动态PV和静态PV。如果使用静态PV,我们就需要手工创建PV或者预先创建大量的PV。在生产中,这种方式会给运维带来极大的困扰,因此我们推荐使用动态PV。接下来介绍如何基于Ceph实现容器原生存储,从而实现动态PV。

为了实现容器存储接口标准化,开源界提出容器存储接口(Container Storage Interface,CSI)。CSI旨在提供一种标准,让块存储和文件系统可以在符合这种标准的情况下,为Kubernetes上的容器提供持久化存储。随着CSI的应用,Kubernetes存储层变得真正可扩展。CSI使得第三方存储提供商可以编写和部署插件,发布支持Kubernetes的存储系统,而无须触及核心Kubernetes代码。CSI为Kubernetes用户提供了更多存储选项,使容器中的应用系统更加安全、可靠。

Ceph从v14开始支持CSI。也就是说,从Ceph v14开始,OpenShift访问Ceph时必须要通过CSI Driver。但是,在部署Ceph集群时,CSI Driver不会被自动部署到集群中,需要手工安装,步骤较为复杂,也不利于运维。出于方便Kubernetes纳管Ceph的目的,开源社区提出了Rook项目。

Rook(https://rook.io/)是一个开源项目,红帽是该项目的顶级代码贡献商之一。Rook由Operator提供,它可以实现Ceph的部署、配置、供应、扩展、升级、迁移、灾难恢复、监视和资源管理自动化。红帽OpenShift容器存储架构就是通过Rook纳管Ceph实现的。

4.3.1 OpenShift容器存储架构

基于Ceph和Rook,红帽构建了OpenShift容器存储架构(OpenShift Container Storage,OCS)。需要指出的是,新版本的OCS已经改名为Data Foundation。OCS是Rook和Ceph的企业级解决方案,其架构如图4-53所示。

123-1

图4-53 OCS架构图

从图4-53可以看出,OCS的组件都是以Pod形式运行在OpenShift中,Pod的具体作用会在后文展开说明。

OCS有两种工作模式,分析如下。

  • 内置(Internal)模式:把OCS整体(OCS Operator和Ceph集群)部署在OpenShift集群中,把OpenShift的本地存储空间作为Ceph存储空间。这种模式的部署、使用都非常方便,适合开发测试和PoC环境。
  • 外置(External)模式:在OpenShift上部署OCS Operator,对接在外部物理机上安装的Ceph;然后OpenShift以Rook的方式,管理外部物理机上的Ceph。外置模式的优势是实现了OpenShift和存储的解耦,而且存储性能较高,适合生产环境。

在介绍了OCS的架构后,接下来我们介绍OCS的部署步骤。

4.3.2 创建OCS存储

在OpenShift的Operator Hub中找到对应的Operator(图中显示名称仍为更名之前的称呼),如图4-54所示。

124-1

图4-54 选择OCS Operator

OCS Operator部署成功后会提供三个API:Storage Cluster、Backing Store、Bucket Class,如图4-55所示。

124-2

图4-55 OCS Operator提供的API

OCS Operator安装成功后,会在openshift-storage项目中部署三个Operator:

# oc get pods -n openshift-storage
NAME                                  READY   STATUS    RESTARTS   AGE
noobaa-operator-5c6dcb944b-8cds4      1/1     Running   0          42s
ocs-operator-56d4d7ddc7-4qfxq         1/1     Running   0          45s
rook-ceph-operator-7b46bff769-t9h8c   1/1     Running   0          45s

使用OCS Operator中的Storage Cluster API创建存储集群,如图4-56所示。

125-1

图4-56 创建存储集群

如前文所述,OCS有内置和外置两种模式。我们先选择内置模式,如图4-57所示。

125-2

图4-57 创建存储集群

选择内置模式后,OCS会列出OpenShift集群中可创建存储集群的节点。需要注意的是,OCS要求加入存储集群的OpenShift节点至少有16个CPU和64 GB内存,同时节点至少要选择三个,且不在一个故障域中。我们选择3个OpenShift节点,如图4-58所示。

126-1

图4-58 选择节点

存储空间选择2TiB,这代表三个存储节点,每个节点的内存是2TiB,做三副本,如图4-59所示。

126-2

图4-59 查看OCS相关Pod

存储集群创建后,会在openshift-storage项目中部署对应的Pod,以CSI开头的Pod为与CSI Driver相关的Pod,因此使用OCS时,我们不必单独安装CSI Driver;以rook开头的Pod为被Rook纳管的容器化Ceph组件,如图4-60所示。

126-3

图4-60 查看OCS相关Pod

所有Pod部署完毕后,在OpenShift中查看存储集群,显示已经部署成功:

# oc get storagecluster -n openshift-storage
NAME                 AGE    PHASE     EXTERNAL        CREATED AT      VERSION
ocs-storagecluster   39m    Ready     2020-10-11T     14:20:27Z       4.5.0

查看storagecluster对象中的内容,看到集群有2TiB空间(每个存储节点大小为2TiB,有三个副本),如图4-61所示。

127-1

图4-61 查看存储集群

查看OCS新创建的三个存储类,分别为ceph-rbd、cephfs、ceph-rgw,如图4-62所示。

127-2

图4-62 查看新创建的存储类

接下来,我们查看ceph-rbd、cephfs这两个存储类的相关内容。

查看ceph-rbd,看到其相关的参数和该存储类对应的存储池,如图4-63所示。

127-3

图4-63 查看新创建的ceph-rbd的内容

查看cephfs,发现该存储类不对应pool,而是对应fs,且可以看到fsName,如图4-64所示。

128-1

图4-64 查看新创建的cephfs的内容

如果我们想要从Ceph集群角度查看集群的状态和资源,可以使用Rook-Ceph工具。Rook-Ceph工具需要手工部署:

#oc patch ocsInitialization ocsinit -n openshift-storage --type json --patch
    '[{ "op": "replace", "path": "/spec/enableCephTools", "value": true }]'

在rook-ceph-tools Pod运行之后,采用如下方法访问工具。首先设置变量:

#TOOLS_POD=$(oc get pods -n openshift-storage -l app=rook-ceph-tools -o name)

登录工具Pod:

#oc rsh -n openshift-storage $TOOLS_POD

登录后,就可以使用Ceph命令行来检查存储集群。我们可以看到集群的health、mon、mgr、mds的状态,如图4-65所示。

128-2

图4-65 查看新创建的集群状态

查看Ceph集群OSD状态,可以看到Ceph集群中一共有3个OSD节点,每个节点提供2TiB存储空间,如图4-66所示。

129-1

图4-66 查看Ceph集群存储节点

查看存储空间的使用情况,可以看到rbd和CephFS的使用情况,如图4-67所示。

129-2

图4-67 查看Ceph集群存储空间使用情况

查看Ceph版本,为14.2.8,如图4-68所示。

129-3

图4-68 查看Ceph版本

在成功部署了OCS以后,我们接下来介绍如何基于OCS的存储空间创建应用。在以下两节中,我们主要介绍如何使用OCS的rbd和CephFS来为OpenShift容器应用提供持久化存储。

4.3.3 使用rbd为应用提供持久化存储

接下来,我们在OpenShift中使用OCS-storagecluster-ceph-rbd存储类来创建RWO(ReadWriteOnce)持久性存储,供新建的应用使用。

我们使用rails-pgsql-persistent模板在OpenShift上部署应用(包含前端应用和一个数据库)。该模板包含一个参数STORAGE_CLASS,在部署应用时,我们通过这个参数指定pvc使用的STORAGE_CLASS。

首先创建项目:

oc new-project my-database-app

通过模板创建应用,指定使用名为ocs-storagecluster-ceph-rbd的存储类,所需空间大小为5GiB。

#oc new-app -f /opt/app-root/src/support/ocslab_rails-app.yaml -p STORAGE_CLASS=
    ocs-storagecluster-ceph-rbd -p VOLUME_CAPACITY=5Gi

查看应用的部署情况:前端应用和后端PostgreSQL数据库都已经部署成功,如图4-69所示。

130-1

图4-69 查看成功部署的应用

查看pvc,发现PostgreSQL已经和pvc自动绑定,如图4-70所示。这个pvc是OCS根据部署应用时指定的容量和读写模式最终在Ceph存储上自动创建的rbd卷,如图4-70所示。

130-2

图4-70 查看pvc

接下来,我们从Ceph存储集群角度,确认OCS自动创建的rbd卷。再次登录Ceph工具。

#TOOLS_POD=$(oc get pods -n openshift-storage -l app=rook-ceph-tools -o name)
#oc rsh -n openshift-storage $TOOLS_POD

我们先获取rbd存储池的名称,如图4-71所示,为ocs-storagecluster-cephblockpool。

131-1

图4-71 查看rbd存储池

查看存储池中的卷,如图4-72所示。

131-2

图4-72 查看rbd卷

如果想确认我们刚部署的应用具体使用哪个卷,使用如下脚本:

#CSIVOL=$(oc get pv $(oc get pv | grep my-database-app | awk '{ print $1 }')
    -o jsonpath='{.spec.csi.volumeHandle}' | cut -d '-' -f 6- | awk '{print "csi-
    vol-"$1}')
#echo $CSIVOL

从图4-73所示的输出中,我们可以看到,PostgreSQL数据库使用的pv对应的rbd卷为csi-vol-85766b1b-f719-11ea-b9a2-0a580a830405,即图4-72中的第一个卷。

131-3

图4-73 查看数据库使用的rbd卷

使用如下脚本查看rbd卷的具体信息,可以看到卷的大小,如图4-74所示。

131-4

图4-74 查看rbd卷的信息

TOOLS_POD=$(oc get pods -n openshift-storage -l app=rook-ceph-tools -o name)
    oc rsh -n openshift-storage $TOOLS_POD rbd -p ocs-storagecluster-cephblockpool info $CSIVOL

在介绍了如何通过rbd为容器应用提供持久化存储后,接下来我们介绍如何通过CephFS为容器应用提供持久化存储。

4.3.4 使用CephFS为应用提供持久化存储

使用rbd创建的pv,只能被一个Pod读写。但有些时候,我们需要提供可被多个Pod共享的持久化存储,这就需要使用RWX(ReadWriteMany)模式的pvc。接下来我们通过使用ocs-storagecluster-cephfs存储类,创建可同时由多个Pod使用的存储空间。

首先部署PHP应用程序示例,名为file-uploader:

#oc new-app openshift/php:7.2~https://github.com/christianh814/openshift-php-
    upload-demo --name=file-upload

应用部署成功后,如图4-75所示。此时的应用是没有持久化存储的。

132-1

图4-75 查看部署成功的Pod

为应用创建路由,并将应用的副本数增加到3:

#oc expose svc/file-uploader -n my-shared-storage
#oc scale --replicas=3 dc/file-uploader

接下来,我们使用OCS-storagecluster-cephfs存储类创建一个PersistentVolumeClaim,并使用oc set volume命令将其附加到应用程序中,指定pvc需要的存储空间大小、读写模式:

#oc set volume dc/file-uploader --add --name=my-shared-storage \
-t pvc --claim-mode=ReadWriteMany --claim-size=1Gi \
--claim-name=my-shared-storage --claim-class=ocs-storagecluster-cephfs \
--mount-path=/opt/app-root/src/uploaded \

获取应用的路由:

#oc get route file-uploader -n my-shared-storage -o jsonpath --template="{.spec.host}"

通过浏览器访问应用,如图4-76所示,可以上传文件,将应用Pod重启后,发现上传的文件仍在,证明文件已经被存入持久化存储中。由于篇幅有限,具体步骤不再展开说明。

133-1

图4-76 浏览器访问应用

至此,我们介绍了如何使用OCS的rbd和CephFS为容器提供持久化存储。在以上环境中,我们使用了OCS的内置模式,将Ceph安装在OCP内部。但在生产环境中,如果客户对Ceph的容量和性能要求较高,就需要使用OCS的外置模式。接下来,我们介绍通过OCS纳管外部Ceph存储。

4.3.5 OCS Operator对接外部存储

在创建存储集群时,我们选择外部存储,会看到界面将提示下载一个Python脚本,如图4-77所示。

133-2

图4-77 Operator对接外部存储

我们在外置的Ceph的mon节点上执行这个脚本。首先查看脚本的使用帮助:

#python ceph-external-cluster-details-exporter.py --help

在下面的命令中,rbd-data-pool-name指定要创建的存储池的名称;rgw-endpoint指定Ceph集群对象网关地址:

#python ceph-external-cluster-details-exporter.py --rbd-data-pool-name abc --rgw-
    endpoint 192.168.18.203:8080

命令执行后,会以JSON格式返回一串输出结果,将结果粘贴到图4-77所示的空白处,即可完成添加。后续的操作步骤与内置模式类似,这里不再展开说明。

通过本节,相信你会对容器原生存储有一定的了解。通过Rook Operator,Kubernetes/OpenShift可以方便地使用持久化存储,解决了容器云在运维方面使用持久化存储的困扰。随着容器云的普及,相信Ceph的应用场景会越来越广。