如何使用Rook在Kubernetes中设置Ceph集群

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Mozilla 基金会 来接受捐赠。

介绍

Kubernetes容器的核心原则是无状态,但数据仍然必须被管理、保存并可供其他服务访问。 无状态意味着容器在不了解过去事务的情况下隔离运行,这使得替换、删除或分发容器变得容易。 但是,这也意味着某些生命周期事件(例如重启或删除)会丢失数据。

Rook 是一种存储编排工具,可为各种存储提供商提供云原生的开源解决方案。 Rook 利用 Kubernetes 的强大功能将存储系统转变为自我管理服务,为保存 Kubernetes 应用程序或部署数据提供无缝体验。

Ceph 是一个高度可扩展的分布式存储解决方案,提供对象、块和文件存储。 Ceph 集群旨在使用所谓的 CRUSH 算法(可伸缩散列下的受控复制)在任何硬件上运行。

这种部署的一个主要好处是,您无需使用 Ceph 命令行手动配置即可获得 Ceph 的高度可扩展存储解决方案,因为 Rook 会自动处理它。 然后,Kubernetes 应用程序可以从 Rook 挂载块设备和文件系统,以保存和监控它们的应用程序数据。

在本教程中,您将使用 Rook 设置 Ceph 集群,并使用它为 MongoDB 数据库持久化数据作为示例。

注意: 本指南应作为 Rook Ceph 的介绍,而不是用于具有大量机器的生产部署。


先决条件

在开始本指南之前,您需要以下内容:

  • 具有至少三个节点的 DigitalOcean Kubernetes 集群,每个节点具有 2 个 vCPU 和 4 GB 内存。 要在 DigitalOcean 上创建集群并连接到它,请参阅 Kubernetes 快速入门
  • kubectl 命令行工具安装在开发服务器上并配置为连接到您的集群。 您可以在其 官方文档 中阅读有关安装 kubectl 的更多信息。
  • 一个 DigitalOcean 块存储 卷,对于您刚刚创建的集群的每个节点至少有 100 GB — 例如,如果您有三个节点,则需要三个卷。 选择 手动格式化 而不是自动,然后将您的卷附加到节点池中的液滴。 您可以按照 Volumes 快速入门 来实现此目的。

第 1 步 — 设置 Rook

完成先决条件后,您将拥有一个功能齐全的 Kubernetes 集群,其中包含三个节点和三个卷——您现在可以设置 Rook。

在本节中,您将克隆 Rook 存储库,在 Kubernetes 集群上部署您的第一个 Rook operator,并验证给定的部署状态。 Rook operator 是一个容器,它自动引导存储集群并监控存储守护进程以确保存储集群是健康的。

在开始部署所需的 Rook 资源之前,您首先需要在所有节点上安装 LVM 包作为 Ceph 的先决条件。 为此,您将创建一个 Kubernetes DaemonSet,它使用 apt 在节点上安装 LVM 包。 DaemonSet 是在每个节点上运行一个 pod 的部署。

首先,您将创建一个 YAML 文件:

nano lvm.yaml

DaemonSet 将定义将在每个节点上执行的容器。 在这里,您使用运行 debian 的容器定义 DaemonSet,该容器使用 apt 命令安装 lvm2,然后使用 volumeMounts:

lvm.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
 name: lvm
 namespace: kube-system
spec:
 revisionHistoryLimit: 10
 selector:
   matchLabels:
     name: lvm
 template:
   metadata:
     labels:
       name: lvm
   spec:
     containers:
     - args:
       - apt -y update; apt -y install lvm2
       command:
       - /bin/sh
       - -c
       image: debian:10
       imagePullPolicy: IfNotPresent
       name: lvm
       securityContext:
         privileged: true
       volumeMounts:
       - mountPath: /etc
         name: etc
       - mountPath: /sbin
         name: sbin
       - mountPath: /usr
         name: usr
       - mountPath: /lib
         name: lib
     dnsPolicy: ClusterFirst
     restartPolicy: Always
     schedulerName: default-scheduler
     securityContext:
     volumes:
     - hostPath:
         path: /etc
         type: Directory
       name: etc
     - hostPath:
         path: /sbin
         type: Directory
       name: sbin
     - hostPath:
         path: /usr
         type: Directory
       name: usr
     - hostPath:
         path: /lib
         type: Directory
       name: lib

现在 DaemonSet 已正确配置,是时候使用以下命令应用它了:

kubectl apply -f lvm.yaml

现在满足所有先决条件,您将克隆 Rook 存储库,因此您拥有开始设置 Rook 集群所需的所有资源:

git clone --single-branch --branch release-1.3 https://github.com/rook/rook.git

此命令将从 GitHub 克隆 Rook 存储库,并在您的目录中创建一个名为 rook 的文件夹。 现在使用以下命令进入目录:

cd rook/cluster/examples/kubernetes/ceph

接下来,您将继续创建 Rook 部署所需的公共资源,您可以通过部署目录中默认可用的 Kubernetes 配置文件来完成此操作:

kubectl create -f common.yaml

您创建的资源主要是 CustomResourceDefinitions (CRD) 并定义了操作员稍后将使用的新资源。 它们包含 ServiceAccount、Role、RoleBinding、ClusterRole 和 ClusterRoleBinding 等资源。

注意: 这个标准文件假定您将在同一个命名空间中部署 Rook 操作符和所有 Ceph 守护进程。 如果要在单独的命名空间中部署操作符,请参阅 common.yaml 文件中的注释。


公共资源创建完成后,下一步就是创建 Rook 算子。

在部署 operator.yaml 文件之前,您需要更改 CSI_RBD_GRPC_METRICS_PORT 变量,因为您的 DigitalOcean Kubernetes 集群已经默认使用标准端口。 使用以下命令打开文件:

nano operator.yaml

然后搜索 CSI_RBD_GRPC_METRICS_PORT 变量,通过删除 # 取消注释,并将端口 9090 的值更改为 9093

运算符.yaml

kind: ConfigMap
apiVersion: v1
metadata:
  name: rook-ceph-operator-config
  namespace: rook-ceph
data:
  ROOK_CSI_ENABLE_CEPHFS: "true"
  ROOK_CSI_ENABLE_RBD: "true"
  ROOK_CSI_ENABLE_GRPC_METRICS: "true"
  CSI_ENABLE_SNAPSHOTTER: "true"
  CSI_FORCE_CEPHFS_KERNEL_CLIENT: "true"
  ROOK_CSI_ALLOW_UNSUPPORTED_VERSION: "false"
  # Configure CSI CSI Ceph FS grpc and liveness metrics port
  # CSI_CEPHFS_GRPC_METRICS_PORT: "9091"
  # CSI_CEPHFS_LIVENESS_METRICS_PORT: "9081"
  # Configure CSI RBD grpc and liveness metrics port
  CSI_RBD_GRPC_METRICS_PORT: "9093"
  # CSI_RBD_LIVENESS_METRICS_PORT: "9080"

完成后,保存并退出文件。

接下来,您可以使用以下命令部署操作员:

kubectl create -f operator.yaml

该命令将输出以下内容:

Outputconfigmap/rook-ceph-operator-config created
deployment.apps/rook-ceph-operator created

同样,您使用带有 -f 标志的 kubectl create 命令来分配要应用的文件。 操作员运行大约需要几秒钟。 您可以使用以下命令验证状态:

kubectl get pod -n rook-ceph

您可以使用 -n 标志来获取特定 Kubernetes 命名空间的 pod(本例中为 rook-ceph)。

一旦操作员部署准备就绪,它将触发创建 DeamonSet,这些 DeamonSet 负责在集群的每个工作节点上创建 rook-discovery 代理。 您将收到类似于以下内容的输出:

OutputNAME                                  READY   STATUS    RESTARTS   AGE
rook-ceph-operator-599765ff49-fhbz9   1/1     Running   0          92s
rook-discover-6fhlb                   1/1     Running   0          55s
rook-discover-97kmz                   1/1     Running   0          55s
rook-discover-z5k2z                   1/1     Running   0          55s

您已成功安装 Rook 并部署了您的第一个 Operator。 接下来,您将创建一个 Ceph 集群并验证它是否正常工作。

第 2 步 — 创建 Ceph 集群

现在您已在 Kubernetes 集群上成功设置 Rook,您将继续在 Kubernetes 集群中创建 Ceph 集群并验证其功能。

首先让我们回顾一下最重要的 Ceph 组件及其功能:

  • Ceph Monitors,也称为 MON,负责维护 Ceph 守护进程相互协调所需的集群映射。 应该始终运行多个 MON,以提高存储服务的可靠性和可用性。
  • Ceph 管理器,也称为 MGR,是运行时守护进程,负责跟踪运行时指标和 Ceph 集群的当前状态。 它们与您的监控守护程序 (MON) 一起运行,以提供额外的监控以及与外部监控和管理系统的接口。
  • Ceph 对象存储设备,也称为 OSD,负责将对象存储在本地文件系统上,并通过网络提供对它们的访问。 这些通常与集群的一个物理磁盘相关联。 Ceph 客户端直接与 OSD 交互。

为了与 Ceph 存储的数据进行交互,客户端将首先与 Ceph 监视器 (MON) 联系以获取 集群图 的当前版本。 集群地图包含数据存储位置以及集群拓扑。 Ceph 客户端然后使用集群映射来决定他们需要与哪个 OSD 交互。

Rook 使 Ceph 存储能够在您的 Kubernetes 集群上运行。 所有这些组件都在您的 Rook 集群中运行,并将直接与 Rook 代理交互。 通过隐藏归置组和存储映射等 Ceph 组件,同时仍提供高级配置选项,这为管理 Ceph 集群提供了更简化的体验。

现在您对 Ceph 是什么以及如何在 Rook 中使用有了更好的了解,接下来您将继续设置 Ceph 集群。

您可以通过运行示例配置(位于 Rook 项目的 examples 目录中)或编写自己的配置来完成设置。 示例配置适用于大多数用例,并提供了出色的可选参数文档。

现在您将开始创建 Ceph 集群 Kubernetes 对象

首先,您需要创建一个 YAML 文件:

nano cephcluster.yaml

配置定义了 Ceph 集群的部署方式。 在此示例中,您将部署三个 Ceph 监视器 (MON) 并启用 Ceph 仪表板。 Ceph 仪表板 超出了本教程的范围,但您可以稍后在您自己的个人项目中使用它来可视化 Ceph 集群的当前状态。

添加以下内容以定义 apiVersion 和 Kubernetes 对象 kind 以及应该部署对象的 namenamespace

cephcluster.yaml

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph

之后,添加 spec 键,它定义了 Kubernetes 将用于创建 Ceph 集群的模型。 您将首先定义要使用的映像版本以及是否允许不受支持的 Ceph 版本:

cephcluster.yaml

spec:
  cephVersion:
    image: ceph/ceph:v14.2.8
    allowUnsupported: false

然后使用 dataDirHostPath 键设置将保存配置文件的数据目录:

cephcluster.yaml

  dataDirHostPath: /var/lib/rook

接下来,使用以下参数定义是否要跳过升级检查以及何时升级集群:

cephcluster.yaml

  skipUpgradeChecks: false
  continueUpgradeAfterChecksEvenIfNotHealthy: false

您可以使用 mon 键配置 Ceph 监视器 (MON) 的数量。 您还允许每个节点部署多个 MON:

cephcluster.yaml

  mon:
    count: 3
    allowMultiplePerNode: false

Ceph 仪表板的选项在 dashboard 键下定义。 这为您提供了启用仪表板、自定义端口以及在使用反向代理时为其添加前缀的选项:

cephcluster.yaml

  dashboard:
    enabled: true
    # serve the dashboard under a subpath (useful when you are accessing the dashboard via a reverse proxy)
    # urlPrefix: /ceph-dashboard
    # serve the dashboard at the given port.
    # port: 8443
    # serve the dashboard using SSL
    ssl: false

您还可以使用 monitoring 键启用对集群的监控(监控需要预先安装 Prometheus ):

cephcluster.yaml

  monitoring:
    enabled: false
    rulesNamespace: rook-ceph

RDB 代表 RADOS(可靠的自主分布式对象存储)块设备,它是精简配置和可调整大小的 Ceph 块设备,可将数据存储在多个节点上。

通过启用 rbdMirroring,可以在两个 Ceph 集群之间异步共享 RBD 映像。 由于我们在本教程中使用一个集群,因此这不是必需的。 因此工人的数量设置为 0

cephcluster.yaml

  rbdMirroring:
    workers: 0

您可以为 Ceph 守护进程启用崩溃收集器:

cephcluster.yaml

  crashCollector:
    disable: false

仅当您要删除集群时,清理策略才重要。 这就是为什么这个选项必须留空:

cephcluster.yaml

  cleanupPolicy:
    deleteDataDirOnHosts: ""
  removeOSDsIfOutAndSafeToRemove: false

storage 键可让您定义集群级别的存储选项; 例如,要使用哪个节点和设备、数据库大小以及每个设备要创建多少个 OSD:

cephcluster.yaml

  storage:
    useAllNodes: true
    useAllDevices: true
    config:
      # metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.
      # databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB
      # journalSizeMB: "1024"  # uncomment if the disks are 20 GB or smaller

您可以使用 disruptionManagement 键在升级或防护期间管理守护程序中断:

cephcluster.yaml

  disruptionManagement:
    managePodBudgets: false
    osdMaintenanceTimeout: 30
    manageMachineDisruptionBudgets: false
    machineDisruptionBudgetNamespace: openshift-machine-api

这些配置块将产生最终的以下文件:

cephcluster.yaml

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: ceph/ceph:v14.2.8
    allowUnsupported: false
  dataDirHostPath: /var/lib/rook
  skipUpgradeChecks: false
  continueUpgradeAfterChecksEvenIfNotHealthy: false
  mon:
    count: 3
    allowMultiplePerNode: false
  dashboard:
    enabled: true
    # serve the dashboard under a subpath (useful when you are accessing the dashboard via a reverse proxy)
    # urlPrefix: /ceph-dashboard
    # serve the dashboard at the given port.
    # port: 8443
    # serve the dashboard using SSL
    ssl: false
  monitoring:
    enabled: false
    rulesNamespace: rook-ceph
  rbdMirroring:
    workers: 0
  crashCollector:
    disable: false
  cleanupPolicy:
    deleteDataDirOnHosts: ""
  removeOSDsIfOutAndSafeToRemove: false
  storage:
    useAllNodes: true
    useAllDevices: true
    config:
      # metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.
      # databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB
      # journalSizeMB: "1024"  # uncomment if the disks are 20 GB or smaller
  disruptionManagement:
    managePodBudgets: false
    osdMaintenanceTimeout: 30
    manageMachineDisruptionBudgets: false
    machineDisruptionBudgetNamespace: openshift-machine-api

完成后,保存并退出文件。

您还可以通过例如更改数据库大小或为仪表板定义自定义端口来自定义部署。 您可以在 Rook 存储库的 集群示例 中找到更多集群部署选项。

接下来,在您的 Kubernetes 集群中应用此清单:

kubectl apply -f cephcluster.yaml

现在检查 pod 是否正在运行:

kubectl get pod -n rook-ceph

这通常需要几分钟,所以只需刷新,直到您的输出反映如下内容:

OutputNAME                                                   READY   STATUS    RESTARTS   AGE
csi-cephfsplugin-lz6dn                                 3/3     Running   0          3m54s
csi-cephfsplugin-provisioner-674847b584-4j9jw          5/5     Running   0          3m54s
csi-cephfsplugin-provisioner-674847b584-h2cgl          5/5     Running   0          3m54s
csi-cephfsplugin-qbpnq                                 3/3     Running   0          3m54s
csi-cephfsplugin-qzsvr                                 3/3     Running   0          3m54s
csi-rbdplugin-kk9sw                                    3/3     Running   0          3m55s
csi-rbdplugin-l95f8                                    3/3     Running   0          3m55s
csi-rbdplugin-provisioner-64ccb796cf-8gjwv             6/6     Running   0          3m55s
csi-rbdplugin-provisioner-64ccb796cf-dhpwt             6/6     Running   0          3m55s
csi-rbdplugin-v4hk6                                    3/3     Running   0          3m55s
rook-ceph-crashcollector-pool-33zy7-68cdfb6bcf-9cfkn   1/1     Running   0          109s
rook-ceph-crashcollector-pool-33zyc-565559f7-7r6rt     1/1     Running   0          53s
rook-ceph-crashcollector-pool-33zym-749dcdc9df-w4xzl   1/1     Running   0          78s
rook-ceph-mgr-a-7fdf77cf8d-ppkwl                       1/1     Running   0          53s
rook-ceph-mon-a-97d9767c6-5ftfm                        1/1     Running   0          109s
rook-ceph-mon-b-9cb7bdb54-lhfkj                        1/1     Running   0          96s
rook-ceph-mon-c-786b9f7f4b-jdls4                       1/1     Running   0          78s
rook-ceph-operator-599765ff49-fhbz9                    1/1     Running   0          6m58s
rook-ceph-osd-prepare-pool-33zy7-c2hww                 1/1     Running   0          21s
rook-ceph-osd-prepare-pool-33zyc-szwsc                 1/1     Running   0          21s
rook-ceph-osd-prepare-pool-33zym-2p68b                 1/1     Running   0          21s
rook-discover-6fhlb                                    1/1     Running   0          6m21s
rook-discover-97kmz                                    1/1     Running   0          6m21s
rook-discover-z5k2z                                    1/1     Running   0          6m21s

您现在已经成功设置了 Ceph 集群,可以继续创建第一个存储块。

第 3 步 — 添加块存储

块存储允许单个 pod 挂载存储。 在本节中,您将创建一个稍后可以在应用程序中使用的存储块。

在 Ceph 为您的集群提供存储之前,您首先需要创建一个 storageclass 和一个 cephblockpool。 这将允许 Kubernetes 在创建 持久卷 时与 Rook 进行互操作:

kubectl apply -f ./csi/rbd/storageclass.yaml

该命令将输出以下内容:

Outputcephblockpool.ceph.rook.io/replicapool created
storageclass.storage.k8s.io/rook-ceph-block created

注意: 如果您在 rook-ceph 以外的命名空间中部署了 Rook 运算符,则需要更改配置器中的前缀以匹配您使用的命名空间。


成功部署 storageclasscephblockpool 后,您将继续为您的应用程序定义 PersistentVolumeClaim (PVC)。 PersistentVolumeClaim 是用于从集群请求存储的资源。

为此,您首先需要创建一个 YAML 文件:

nano pvc-rook-ceph-block.yaml

为您的 PersistentVolumeClaim 添加以下内容:

pvc-rook-ceph-block.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mongo-pvc
spec:
  storageClassName: rook-ceph-block
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

首先,您需要设置一个apiVersionv1是当前的稳定版本)。 然后,您需要使用 kind 键(在本例中为 PersistentVolumeClaim)告诉 Kubernetes 您要定义哪种类型的资源。

spec 键定义了 Kubernetes 将用来创建 PersistentVolumeClaim 的模型。 这里需要选择之前创建的存储类:rook-ceph-block。 然后,您可以定义访问模式并限制声明的资源。 ReadWriteOnce 表示该卷只能由单个节点挂载。

现在您已经定义了 PersistentVolumeClaim,是时候使用以下命令部署它了:

kubectl apply -f pvc-rook-ceph-block.yaml

您将收到以下输出:

Outputpersistentvolumeclaim/mongo-pvc created

您现在可以检查 PVC 的状态:

kubectl get pvc

当 PVC 被绑定后,你就准备好了:

OutputNAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
mongo-pvc   Bound    pvc-ec1ca7d1-d069-4d2a-9281-3d22c10b6570   5Gi        RWO            rook-ceph-block   16s

您现在已经成功创建了一个存储类,并使用它创建了一个 PersistenVolumeClaim,您将在下一节中将其挂载到应用程序以持久保存数据。

第 4 步 — 使用 rook-ceph-block 创建 MongoDB 部署

现在您已经成功创建了一个存储块和一个持久卷,您将通过在 MongoDB 应用程序中实现它来使用它。

配置将包含一些内容:

  • 基于mongo镜像最新版本的单容器部署。
  • 用于保存 MongoDB 数据库数据的持久卷。
  • 在每个节点的端口 31017 上公开 MongoDB 端口的服务,以便您以后可以与之交互。

首先打开配置文件:

nano mongo.yaml

使用 Deployment 资源启动清单:

mongo.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongo
spec:
  selector:
    matchLabels:
      app: mongo
  template:
    metadata:
      labels:
        app: mongo
    spec:
      containers:
      - image: mongo:latest
        name: mongo
        ports:
        - containerPort: 27017
          name: mongo
        volumeMounts:
        - name: mongo-persistent-storage
          mountPath: /data/db
      volumes:
      - name: mongo-persistent-storage
        persistentVolumeClaim:
          claimName: mongo-pvc

...

对于清单中的每个资源,您需要设置一个 apiVersion。 对于部署和服务,请使用 apiVersion: apps/v1,这是一个稳定版本。 然后,使用 kind 键告诉 Kubernetes 您要定义哪个资源。 每个定义还应该有一个在 metadata.name 中定义的名称。

spec 部分告诉 Kubernetes 最终部署状态的期望状态是什么。 此定义要求 Kubernetes 应创建一个具有一个副本的 pod。

标签是帮助您组织和交叉引用 Kubernetes 资源的键值对。 您可以使用 metadata.labels 定义它们,以后可以使用 selector.matchLabels 搜索它们。

spec.template 键定义了 Kubernetes 将用于创建每个 pod 的模型。 在这里,您将定义 pod 部署的细节,例如镜像名称、容器端口和应该挂载的卷。 然后,Kubernetes 会自动从镜像注册表中提取镜像。

在这里,您将使用之前创建的 PersistentVolumeClaim 来持久化 pod 的 /data/db 目录的数据。 您还可以指定额外的信息,例如环境变量,这将帮助您进一步自定义部署。

接下来,将以下代码添加到文件中以定义一个 Kubernetes Service,它在集群中每个节点的端口 31017 上公开 MongoDB 端口:

mongo.yaml

...

---
apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    app: mongo
spec:
  selector:
    app: mongo
  type: NodePort
  ports:
    - port: 27017
      nodePort: 31017

这里还定义了一个 apiVersion,但不是使用 Deployment 类型,而是定义一个 Service。 该服务将接收端口 31017 上的连接并将它们转发到 pod 的端口 27017,然后您可以在其中访问应用程序。

该服务使用 NodePort 作为服务类型,这将在 3000032767 之间的静态端口(31017 在这种情况下)。

现在您已经定义了部署,是时候部署它了:

kubectl apply -f mongo.yaml

您将看到以下输出:

Outputdeployment.apps/mongo created
service/mongo created

您可以检查部署和服务的状态:

kubectl get svc,deployments

输出将是这样的:

OutputNAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE
service/kubernetes   ClusterIP   10.245.0.1       <none>        443/TCP           33m
service/mongo        NodePort    10.245.124.118   <none>        27017:31017/TCP   4m50s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mongo   1/1     1            1           4m50s

部署准备好后,您可以开始将数据保存到数据库中。 最简单的方法是使用 MongoDB shell,它包含在您刚刚启动的 MongoDB pod 中。 您可以使用 kubectl 打开它。

为此,您将需要 pod 的名称,您可以使用以下命令获取该名称:

kubectl get pods

输出将与此类似:

OutputNAME                     READY   STATUS    RESTARTS   AGE
mongo-7654889675-mjcks   1/1     Running   0          13m

现在复制名称并在 exec 命令中使用它:

kubectl exec -it your_pod_name mongo

现在您在 MongoDB shell 中,让我们继续创建一个数据库:

use test

use 命令在数据库之间切换或在数据库不存在时创建它们。

Outputswitched to db test

然后将一些数据插入到新的 test 数据库中。 您使用 insertOne() 方法在创建的数据库中插入一个新文档:

db.test.insertOne( {name: "test", number: 10  })
Output{
    "acknowledged" : true,
    "insertedId" : ObjectId("5f22dd521ba9331d1a145a58")
}

下一步是检索数据以确保已保存,这可以在您的集合上使用 find 命令完成:

db.getCollection("test").find()

输出将与此类似:

OutputNAME                     READY   STATUS    RESTARTS   AGE
{ "_id" : ObjectId("5f1b18e34e69b9726c984c51"), "name" : "test", "number" : 10 }

现在您已经将一些数据保存到数据库中,它将被持久化在底层的 Ceph 卷结构中。 这种部署的一大优势是卷的动态配置。 动态配置意味着应用程序只需要请求存储,它将由 Ceph 自动提供,而不是开发人员通过向其存储提供者发送请求来手动创建存储。

让我们通过重新启动 pod 并检查数据是否仍然存在来验证此功能。 您可以通过删除 pod 来做到这一点,因为它将重新启动以实现部署中定义的状态:

kubectl delete pod -l app=mongo

现在让我们通过连接到 MongoDB shell 并打印出数据来验证数据是否仍然存在。 为此,您首先需要获取 pod 的名称,然后使用 exec 命令打开 MongoDB shell:

kubectl get pods

输出将与此类似:

OutputNAME                     READY   STATUS    RESTARTS   AGE
mongo-7654889675-mjcks   1/1     Running   0          13m

现在复制名称并在 exec 命令中使用它:

kubectl exec -it your_pod_name mongo

之后,您可以通过连接到数据库并打印整个集合来检索数据:

use test
db.getCollection("test").find()

输出将类似于以下内容:

OutputNAME                     READY   STATUS    RESTARTS   AGE
{ "_id" : ObjectId("5f1b18e34e69b9726c984c51"), "name" : "test", "number" : 10 }

如您所见,即使您重新启动了 pod,您之前保存的数据仍在数据库中。 现在您已成功设置 Rook 和 Ceph 并使用它们来持久化部署数据,让我们回顾一下 Rook 工具箱以及您可以使用它做什么。

第 5 步 — 运行 Rook 工具箱

Rook Toolbox 是一种工具,可帮助您了解 Ceph 部署的当前状态并在出现问题时进行故障排除。 它还允许您更改 Ceph 配置,例如启用某些模块、创建用户或池。

在本节中,您将安装 Rook Toolbox 并使用它来执行基本命令,例如获取当前 Ceph 状态。

工具箱可以通过部署toolbox.yaml文件来启动,该文件在examples/kubernetes/ceph目录下:

kubectl apply -f toolbox.yaml

您将收到以下输出:

Outputdeployment.apps/rook-ceph-tools created

现在检查 pod 是否正在运行:

kubectl -n rook-ceph get pod -l "app=rook-ceph-tools"

您的输出将与此类似:

OutputNAME                               READY   STATUS    RESTARTS   AGE
rook-ceph-tools-7c5bf67444-bmpxc   1/1     Running   0          9s

pod 运行后,您可以使用 kubectl exec 命令连接到它:

kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') bash

让我们分解这个命令以便更好地理解:

  1. kubectl exec 命令可以让你在一个 pod 中执行命令; 比如设置环境变量或启动服务。 在这里,您使用它来打开 pod 中的 BASH 终端。 您要执行的命令在命令末尾定义。
  2. 您使用 -n 标志来指定 pod 正在运行的 Kubernetes 命名空间。
  3. -i (interactive) 和 -t (tty) 标志告诉 Kubernetes 您希望在启用 tty 的情况下以交互模式运行命令。 这使您可以与打开的终端进行交互。
  4. $() 允许您在命令中定义表达式。 这意味着表达式将在主命令之前被评估(执行),然后将结果值作为参数传递给主命令。 这里我们定义另一个 Kubernetes 命令来获取标签 app=rook-ceph-tool 的 pod,并使用 jsonpath 读取 pod 的名称。 然后我们使用名称作为我们第一个命令的参数。

注意: 如前所述,此命令将在 pod 中打开一个终端,因此您的提示将更改以反映这一点。


现在您已连接到 pod,您可以执行 Ceph 命令来检查当前状态或排除错误消息。 例如,ceph status 命令将为您提供 Ceph 配置的当前健康状态以及更多信息,例如正在运行的 MON、当前正在运行的数据池、可用和已用存储以及当前 I/O 操作:

ceph status

这是命令的输出:

Output  cluster:
    id:     71522dde-064d-4cf8-baec-2f19b6ae89bf
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,b,c (age 23h)
    mgr: a(active, since 23h)
    osd: 3 osds: 3 up (since 23h), 3 in (since 23h)

  data:
    pools:   1 pools, 32 pgs
    objects: 61 objects, 157 MiB
    usage:   3.4 GiB used, 297 GiB / 300 GiB avail
    pgs:     32 active+clean

  io:
    client:   5.3 KiB/s wr, 0 op/s rd, 0 op/s wr

您还可以使用以下命令查询特定项目(如 OSD)的状态:

ceph osd status

这将打印有关您的 OSD 的信息,例如已用和可用存储以及 OSD 的当前状态:

Output+----+------------+-------+-------+--------+---------+--------+---------+-----------+
| id |    host    |  used | avail | wr ops | wr data | rd ops | rd data |   state   |
+----+------------+-------+-------+--------+---------+--------+---------+-----------+
| 0  | node-3jis6 | 1165M | 98.8G |    0   |     0   |    0   |     0   | exists,up |
| 1  | node-3jisa | 1165M | 98.8G |    0   |  5734   |    0   |     0   | exists,up |
| 2  | node-3jise | 1165M | 98.8G |    0   |     0   |    0   |     0   | exists,up |
+----+------------+-------+-------+--------+---------+--------+---------+-----------+

有关可用命令以及如何使用它们来调试 Ceph 部署的更多信息,请参阅 官方文档

您现在已经成功地在 Kubernetes 上设置了一个完整的 Rook Ceph 集群,它可以帮助您持久化部署的数据并在不同的 pod 之间共享它们的状态,而无需使用某种外部存储或手动配置存储。 您还学习了如何启动 Rook Toolbox 并使用它来调试和排除 Ceph 部署故障。

结论

在本文中,您在 Kubernetes 上配置了自己的 Rook Ceph 集群,并使用它为 MongoDB 应用程序提供存储。 您提取了有用的术语并熟悉了 Rook 的基本概念,因此您可以自定义您的部署。

如果您有兴趣了解更多信息,请考虑查看官方 Rook 文档 以及存储库中提供的示例配置,以获取更多配置选项和参数。

如果您想同时将同一个卷挂载到多个 Pod,您还可以尝试 Ceph 提供的其他类型的存储,例如 共享文件系统