背景介绍

  • Cloudpods: 是我们开源的多云管理平台,运行在 Kubernetes 之上,里面包含一个完整的私有云实现。
  • Rook: 是一个分布式存储编排系统,目的是在 Kubernetes 上提供存储解决方案,本身不提供存储,而是在 Kubernetes 和存储系统之间提供适配层,简化存储系统的部署和维护工作。其支持的 Ceph 存储为 Stable 生产可用的状态。
  • Ceph: 是开源的分布式存储系统,主要功能包含 RBD 块存储以及 CephFS 分布式文件系统存储。

Cloudpods 服务以容器化的方式运行在 Kubernetes 集群之上,按照 安装部署 文档部署完 Cloudpods 之后,环境就有了一个完整的 Kubernetes 集群。

但 Cloudpods 内置私有云虚拟机使用的是本地存储,本文主要介绍使用 Rook 在 Cloudpods Kubernetes 集群里面的计算节点上部署 Ceph 集群,然后把 Rook 管理的 Ceph 集群暴露出来对接 Cloudpods 的私有云虚拟机。

Cloudpods 内置私有云提供虚拟化功能, Rook 管理的 Ceph 提供分布式存储,并且这些服务都是容器化,基于 Kubernetes 运行的。Cloudpods 运行虚拟机的节点也叫计算节点,计算节点也是 Kubernetes 的 Node,只要计算节点上有独立的裸盘,就可以使用 Rook 把 Ceph 部署到计算节点上,把这些技术结合起来可以轻松实现一个云原生的超融合私有云。

环境准备

  • Cloudpods:v3.6 以上的多节点部署版本
    • 3 台计算节点,有单独的裸盘给 Ceph 使用(同时作为存储节点使用)
  • Kubernetes:v1.15.9 版本(Cloudpods 默认的集群)
  • Rook: v1.7 版本
  • 操作系统:CentOS 7
  • 内核版本:3.10.0-1062.4.3.el7.yn20191203.x86_64
    • 如果使用 CephFS 建议的内核版本是 4.17 以上的版本,可以升级我们官方提供的 5.4 版本内核

其中 Ceph 相关的环境准备工作和限制可以参考 Rook 提供的文档:https://rook.io/docs/rook/v1.7/pre-reqs.html 。

使用 Rook 部署 Ceph

接下来介绍使用 Rook 在已有的 Cloudpods Kubernetes 集群上部署 Ceph 集群,这里有个前提是已经按照 安装部署/添加节点 文档,部署了一个多节点的 Cloudpods 集群。

节点信息

假设已有的 3 个节点为 node-{0,1,2},每个节点的磁盘信息如下,sd{b,c,d} 都是没有分区的裸盘,留给 Ceph 使用:

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 931.5G  0 disk
├─sda1   8:1    0     1M  0 part
├─sda2   8:2    0   512M  0 part /boot
└─sda3   8:3    0   931G  0 part /
sdb      8:16   0 931.5G  0 disk
sdc      8:32   0   3.7T  0 disk
sdd      8:48   0   3.7T  0 disk

使用 kubectl get nodes 可以看到已经在 Kubernetes 集群中的节点:

$ kubectl get nodes
NAME      STATUS   ROLES    AGE   VERSION
cloudbox  Ready    master   34d   v1.15.9-beta.0
node-0    Ready    <none>   12d   v1.15.9-beta.0
node-1    Ready    <none>   11d   v1.15.9-beta.0
node-2    Ready    <none>   11d   v1.15.9-beta.0

然后给对应的节点打上 role=storage-node 的标签:

# 打标签
$ kubectl label node node-0 role=storage-node
$ kubectl label node node-1 role=storage-node
$ kubectl label node node-2 role=storage-node

# 查看标签对应的节点
$ kubectl get nodes -L role
NAME       STATUS   ROLES    AGE   VERSION          ROLE
cloudbox   Ready    master   34d   v1.15.9-beta.0
node-0     Ready    <none>   12d   v1.15.9-beta.0   storage-node
node-1     Ready    <none>   11d   v1.15.9-beta.0   storage-node
node-2     Ready    <none>   11d   v1.15.9-beta.0   storage-node

另外执行 climc host-list 命令(climc 是云平台的命令行工具),也可以看到这 3 个节点作为 Cloudpods 的计算节点加入到了云平台:

$ climc host-list
+--------------------------------------+----------+-------------------+----------------+--------------+-----------------------------+---------+---------+-------------+----------+-----------+------------+------------+--------------+------------+
|                  ID                  |   Name   |    Access_mac     |   Access_ip    |   Ipmi_Ip    |         Manager_URI         | Status  | enabled | host_status | mem_size | cpu_count | node_count |     sn     | storage_type | host_type  |
+--------------------------------------+----------+-------------------+----------------+--------------+-----------------------------+---------+---------+-------------+----------+-----------+------------+------------+--------------+------------+
| 0d8023ad-ebf9-4a3c-8294-fd170f4ce5c6 | node-0   | 38:ea:a7:8d:94:78 | 172.16.254.127 | 172.16.254.2 | https://172.16.254.127:8885 | running | true    | online      | 128695   | 32        | 2          | 6CU3505M2G | rotate       | hypervisor |
| c02470b3-9666-46f7-852e-9bda8074a72e | node-1   | ec:f4:bb:d7:c4:e0 | 172.16.254.124 | 172.16.254.5 | https://172.16.254.124:8885 | running | true    | online      | 96432    | 48        | 2          | 62CNF52    | rotate       | hypervisor |
| 5811c2d9-2b45-47e4-8c08-a5d479d03009 | node-2   | d4:ae:52:7e:90:9c | 172.16.254.126 | 172.16.254.3 | https://172.16.254.126:8885 | running | true    | online      | 128723   | 24        | 2          | 8Q1PB3X    | rotate       | hypervisor |
+--------------------------------------+----------+-------------------+----------------+--------------+-----------------------------+---------+---------+-------------+----------+-----------+------------+------------+--------------+------------+

部署 Rook 组件

下载 Rook 相关代码:

# clone rook 源码
$ git clone --single-branch --branch release-1.7 https://github.com/rook/rook.git
$ cd rook

部署 rook operator 服务:

# apply rook 相关 CRD
$ cd cluster/examples/kubernetes/ceph/pre-k8s-1.16/
$ kubectl apply -f crds.yaml

# apply rook operator 服务
$ cd ..
$ kubectl apply -f common.yaml -f operator.yaml

# 查看 operator 服务的状态,等待 rook-ceph-operator pod 变为 Running
$ kubectl -n rook-ceph get pods
NAME                                  READY   STATUS    RESTARTS   AGE
rook-ceph-operator-68964f4b87-pc87m   1/1     Running   0          7m38s

创建 ceph 集群

首先根据自己的环境,修改 rook 提供的 cluster.yaml 里面的内容:

$ cp cluster.yaml cluster-env.yaml

下面是修改后的 cluster.yaml 和 cluster-env.yaml 的 diff 内容:

$ diff -u cluster.yaml cluster-env.yaml

请根据自己的节点环境配置,参考 diff 修改,需要注意的地方如下:

  • spec.image: 改为 registry.cn-beijing.aliyuncs.com/yunionio/ceph:v14.2.22 ,这里需要用 v14 版本的镜像,对应的 ceph 版本为 nautilus。如果要使用更高版本 v16 版本ceph,请参考下文 [使用 Pacific (v16) Ceph]。
  • spec.network.provider: 改为 host ,表示 ceph 相关容器使用 hostNetwork ,这样才能给 Kubernetes 集群之外的服务使用
  • spec.placement: 修改了里面的 Kubernetes 调度策略,表示把 ceph pod 调度到 role=storage-node 的节点上
  • spec.storage: 表示存储的配置
    • useAllNodes: 我们指定了role=storage-node 的节点运行 ceph,该值必须设置为false
    • nodes: 分别设置各个节点的存储路径,可以是磁盘或者目录
--- cluster.yaml    2021-10-09 10:49:53.731596210 +0800
+++ cluster-env.yaml    2021-10-09 17:50:01.859112585 +0800
@@ -21,7 +21,7 @@
     # versions running within the cluster. See tags available at https://hub.docker.com/r/ceph/ceph/tags/.
     # If you want to be more precise, you can always use a timestamp tag such quay.io/ceph/ceph:v16.2.6-20210918
     # This tag might not contain a new Ceph version, just security fixes from the underlying operating system, which will reduce vulnerabilities
-    image: quay.io/ceph/ceph:v16.2.6
+    image: registry.cn-beijing.aliyuncs.com/yunionio/ceph:v14.2.22
     # Whether to allow unsupported versions of Ceph. Currently `nautilus`, `octopus`, and `pacific` are supported.
     # Future versions such as `pacific` would require this to be set to `true`.
     # Do not set to true in production.
@@ -81,7 +81,7 @@
     rulesNamespace: rook-ceph
   network:
     # enable host networking
-    #provider: host
+    provider: host
     # enable the Multus network provider
     #provider: multus
     #selectors:
@@ -135,22 +135,22 @@
   # To control where various services will be scheduled by kubernetes, use the placement configuration sections below.
   # The example under 'all' would have all services scheduled on kubernetes nodes labeled with 'role=storage-node' and
   # tolerate taints with a key of 'storage-node'.
-#  placement:
-#    all:
-#      nodeAffinity:
-#        requiredDuringSchedulingIgnoredDuringExecution:
-#          nodeSelectorTerms:
-#          - matchExpressions:
-#            - key: role
-#              operator: In
-#              values:
-#              - storage-node
-#      podAffinity:
-#      podAntiAffinity:
-#      topologySpreadConstraints:
-#      tolerations:
-#      - key: storage-node
-#        operator: Exists
+  placement:
+    all:
+      nodeAffinity:
+        requiredDuringSchedulingIgnoredDuringExecution:
+          nodeSelectorTerms:
+          - matchExpressions:
+            - key: role
+              operator: In
+              values:
+              - storage-node
+      podAffinity:
+      podAntiAffinity:
+      topologySpreadConstraints:
+      tolerations:
+      - key: storage-node
+        operator: Exists
 # The above placement information can also be specified for mon, osd, and mgr components
 #    mon:
 # Monitor deployments may contain an anti-affinity rule for avoiding monitor
@@ -207,8 +207,8 @@
 #    osd: rook-ceph-osd-priority-class
 #    mgr: rook-ceph-mgr-priority-class
   storage: # cluster level storage configuration and selection
-    useAllNodes: true
-    useAllDevices: true
+    useAllNodes: false
+    useAllDevices: false
     #deviceFilter:
     config:
       # crushRoot: "custom-root" # specify a non-default root label for the CRUSH map
@@ -219,17 +219,22 @@
       # encryptedDevice: "true" # the default value for this option is "false"
 # Individual nodes and their config can be specified as well, but 'useAllNodes' above must be set to false. Then, only the named
 # nodes below will be used as storage resources.  Each node's 'name' field should match their 'kubernetes.io/hostname' label.
-    # nodes:
-    #   - name: "172.17.4.201"
-    #     devices: # specific devices to use for storage can be specified for each node
-    #       - name: "sdb"
-    #       - name: "nvme01" # multiple osds can be created on high performance devices
-    #         config:
-    #           osdsPerDevice: "5"
-    #       - name: "/dev/disk/by-id/ata-ST4000DM004-XXXX" # devices can be specified using full udev paths
-    #     config: # configuration can be specified at the node level which overrides the cluster level config
-    #   - name: "172.17.4.301"
-    #     deviceFilter: "^sd."
+    nodes:
+      - name: "node-0"
+        devices: # specific devices to use for storage can be specified for each node
+          - name: "sdb"
+          - name: "sdc"
+          - name: "sdd"
+      - name: "node-1"
+        devices:
+          - name: "sdb"
+          - name: "sdc"
+          - name: "sdd"
+      - name: "node-2"
+        devices:
+          - name: "sdb"
+          - name: "sdc"
+          - name: "sdd"
     # when onlyApplyOSDPlacement is false, will merge both placement.All() and placement.osd
     onlyApplyOSDPlacement: false
   # The section for configuring management of daemon disruptions during upgrade or fencing.

编辑好 cluster-env.yaml 后,使用下面的命令创建 ceph 集群:

$ kubectl apply -f cluster-env.yaml
cephcluster.ceph.rook.io/rook-ceph created

# 查看 rook-ceph namespace 里面的 pod 健康状况
$ kubectl -n rook-ceph get pods
NAME                                                 READY   STATUS      RESTARTS   AGE
rook-ceph-crashcollector-dl380p-55f6cc56c9-b8ghc     1/1     Running     0          3m3s
rook-ceph-crashcollector-r710-7d8659858-mrqgq        1/1     Running     0          2m20s
rook-ceph-crashcollector-r720xd-1-5b686487c5-hvzdb   1/1     Running     0          3m10s
rook-ceph-csi-detect-version-ffdsf                   0/1     Completed   0          26m
rook-ceph-mgr-a-759465b6c7-cslkp                     1/1     Running     0          3m13s
rook-ceph-mon-a-657c4c6769-ljtr9                     1/1     Running     0          18m
rook-ceph-mon-b-7db98b99d4-99pft                     1/1     Running     0          18m
rook-ceph-mon-c-7f84fc475d-5v599                     1/1     Running     0          10m
rook-ceph-operator-68964f4b87-pc87m                  1/1     Running     0          68m
rook-ceph-osd-0-7cc5cb94cb-dxznm                     1/1     Running     0          2m32s
rook-ceph-osd-1-f4d47ddf9-7vgh7                      1/1     Running     0          2m35s
rook-ceph-osd-2-5d7667b8d8-d5tnp                     1/1     Running     0          2m20s
rook-ceph-osd-3-c9c56cd77-8sbzj                      1/1     Running     0          2m32s
rook-ceph-osd-4-88565589c-rnpmg                      1/1     Running     0          2m35s
rook-ceph-osd-5-7d7c554b6c-pvsfx                     1/1     Running     0          2m35s
rook-ceph-osd-6-6c7596c844-jg9qt                     1/1     Running     0          2m20s
rook-ceph-osd-7-55f9987ddf-pjthz                     1/1     Running     0          2m32s
rook-ceph-osd-8-6949b69dd6-685wp                     1/1     Running     0          2m20s
rook-ceph-osd-prepare-dl380p-c6nc8                   0/1     Completed   0          3m3s
rook-ceph-osd-prepare-r710-zkmjz                     0/1     Completed   0          3m3s
rook-ceph-osd-prepare-r720xd-1-fswnf                 0/1     Completed   0          3m2s

# 查看 ceph 集群的健康状况
$ kubectl -n rook-ceph get cephcluster
NAME        DATADIRHOSTPATH   MONCOUNT   AGE   PHASE   MESSAGE                        HEALTH
rook-ceph   /var/lib/rook     3          29m   Ready   Cluster created successfully   HEALTH_OK

ceph 集群部署完后,我们需要部署 toolbox.yaml pod 获取集群连接信息:

$ kubectl apply -f toolbox.yaml
deployment.apps/rook-ceph-tools created

$ kubectl -n rook-ceph get pods | grep tools
rook-ceph-tools-885579f55-qpnhh                      1/1     Running     0          3m44s

# 进入 toolbox pod
$ kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') -- bash
# 查看 mon_host 为: 172.16.254.126:6789,172.16.254.124:6789,172.16.254.127:6789
[root@rook-ceph-tools-885579f55-qpnhh /]$ cat /etc/ceph/ceph.conf
[global]
mon_host = 172.16.254.126:6789,172.16.254.124:6789,172.16.254.127:6789

[client.admin]
keyring = /etc/ceph/keyring

# 查看 keyring 为: AQBHTWFhFQzrORAALLIngo/OOTDdnUf4vNPRoA==
[root@rook-ceph-tools-885579f55-qpnhh /]$ cat /etc/ceph/keyring
[client.admin]
key = AQBHTWFhFQzrORAALLIngo/OOTDdnUf4vNPRoA==

# 查看集群健康状态
[root@rook-ceph-tools-885579f55-qpnhh /]$ ceph status
  cluster:
    id:     233cf123-7a1a-4a7b-b6db-1cee79ec752b
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum a,b,c (age 38m)
    mgr: a(active, since 33m)
    osd: 9 osds: 9 up (since 33m), 9 in (since 34m); 30 remapped pgs

  data:
    pools:   1 pools, 256 pgs
    objects: 0 objects, 0 B
    usage:   57 MiB used, 20 TiB / 20 TiB avail
    pgs:     226 active+clean
             30  active+clean+remapped

# 查看 osd 状态,可以发现对应节点的设备都添加了进来
[root@rook-ceph-tools-885579f55-qpnhh /]$ ceph osd status
ID  HOST    USED  AVAIL  WR OPS  WR DATA  RD OPS  RD DATA  STATE
 0  node-0  6172k  3725G      0        0       0        0   exists,up
 1  node-1  7836k   279G      0        0       0        0   exists,up
 2  node-2  5596k   931G      0        0       0        0   exists,up
 3  node-0  6044k  3725G      0        0       0        0   exists,up
 4  node-1  5980k   279G      0        0       0        0   exists,up
 5  node-1  5980k   279G      0        0       0        0   exists,up
 6  node-2  6236k  3726G      0        0       0        0   exists,up
 7  node-0  7772k  3725G      0        0       0        0   exists,up
 8  node-2  7836k  3726G      0        0       0        0   exists,up

# 创建一个 cloudpods-test 的 pool 用于后面的虚拟机测试
[root@rook-ceph-tools-885579f55-qpnhh /]$ ceph osd pool create cloudpods-test 64 64
pool 'cloudpods-test' created

# 初始化这个pool 为 RBD
[root@rook-ceph-tools-885579f55-qpnhh /]$ rbd pool init cloudpods-test

[root@rook-ceph-tools-885579f55-qpnhh /]$ ceph osd lspools
1 cloudpods-test

Cloudpods 虚拟机使用 Rook 部署的 Ceph

通过之前的步骤,已经使用 Rook 在 Kubernetes 集群里面部署了 Ceph 集群,接下来将 Ceph 集群的连接信息导入到 Cloudpods 私有云平台,就可以给虚拟机使用了。

从之前的步骤得到 ceph 的连接信息如下:

  • mon_host: 172.16.254.126:6789,172.16.254.124:6789,172.16.254.127:6789
  • keyring: AQBHTWFhFQzrORAALLIngo/OOTDdnUf4vNPRoA==
  • rbd pool: cloudpods-test

然后登录 cloudpods 前端创建 ceph rbd 存储并且关联宿主机,操作如下:

  1. 创建名为 rook-ceph 的块存储,填入上面的信息:

  1. 默认创建好的 rook-ceph 块存储为离线状态,需要关联平台的私有云宿主机,宿主机会探测 ceph 集群的连通性,并且获取对应的 pool 容量信息:

  1. rook-ceph 块存储关联好宿主机后,状态就会变为“在线”,并且获取到了 20T 的容量:

  1. 创建虚拟机使用 rook-ceph 存储,这里主要是在虚拟机创建页面添加磁盘,选择存储类型为 Ceph RBD

  1. 等待虚拟机创建完成,通过 vnc 或者 ssh 登录虚拟机:

可以发现虚拟机里面挂载了 /dev/sda(系统盘) 和 /dev/sdb(数据盘),底层都为 ceph 的 RBD 块设备,因为 ceph 底层块设备用的机械盘,用 dd 简单测试速度在 99 MB/s ,符合预期。

  1. 然后使用平台的 climc 命令查看虚拟机所在的宿主机,发现虚拟机 ceph-test-vm 运行在 node-1 计算节点上,同时改节点也是 Ceph 集群的存储节点,实现了超融合的架构:
$ climc server-list --details --search ceph-test-vm
+--------------------------------------+--------------+--------+---------------+--------+---------+------------+-----------+------------+---------+
|                  ID                  |     Name     |  Host  |     IPs       |  Disk  | Status  | vcpu_count | vmem_size | Hypervisor | os_type |
+--------------------------------------+--------------+--------+---------------+--------+---------+------------+-----------+------------+---------+
| ffd8ec7c-1e2d-4427-89e0-81b6ce184185 | ceph-test-vm | node-1 | 172.16.254.252| 235520 | running | 2          | 2048      | kvm        | Linux   |
+--------------------------------------+--------------+--------+---------------+--------+---------+------------+-----------+------------+---------+

其它操作

使用 Pacific (v16) Ceph

上文介绍的流程适合部署 v14 版本的ceph,为了部署 v16 版本的ceph,首先需要把待部署的 ceph 镜像改为:

registry.cn-beijing.aliyuncs.com/yunionio/ceph:v16.2.14

另外,每个计算节点默认部署的是CentOS 7自带的ceph-common,版本为 v10.2.5。该版本的 ceph-common 已经无法访问 v16 ceph。为此,还需要升级每个计算节点的 ceph-common 版本。具体方法如下:

配置 ceph rpm repo 文件 /etc/yum.repos.d/ceph.repo, 内容为:

[ceph]
name=Ceph packages for $basearch
baseurl=https://download.ceph.com/rpm-15.2.17/el7/$basearch
enabled=1
priority=2
gpgcheck=1
gpgkey=https://download.ceph.com/keys/release.asc

[ceph-noarch]
name=Ceph noarch packages
baseurl=https://download.ceph.com/rpm-15.2.17/el7/noarch
enabled=1
priority=2
gpgcheck=1
gpgkey=https://download.ceph.com/keys/release.asc

[ceph-source]
name=Ceph source packages
baseurl=https://download.ceph.com/rpm-15.2.17/el7/SRPMS
enabled=0
priority=2
gpgcheck=1
gpgkey=https://download.ceph.com/keys/release.asc

保存 ceph.repo 后,执行如下命令安装 v15.2.17 的 ceph-common:

yum install -y ceph-common

注:因为ceph官方rpm未提供v16的CentOS 7 rpms,因此安装v15的rpms,该版本兼容v16的ceph-common。

 
Logo

开源、云原生的融合云平台

更多推荐