Kubernetes 集群基于 Rook 搭建 Ceph 分布式存储系统

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aixiaoyang168/article/details/86215080

1、Rook & Ceph 介绍

1.1、Rook

Rook 是专用于 Cloud-Native 环境的文件、块、对象存储服务。它实现了一个自动管理的、自动扩容的、自动修复的分布式存储服务。Rook 支持自动部署、启动、配置、分配、扩容/缩容、升级、迁移、灾难恢复、监控以及资源管理。为了实现所有这些功能,Rook 需要依赖底层的容器编排平台,例如 kubernetes、CoreOS 等。Rook 目前支持 Ceph、NFS、Minio Object Store、Edegefs、Cassandra、CockroachDB 存储的搭建,后期会支持更多存储方案。

1.2、Ceph

Ceph 是一个开源的分布式存储系统,包括对象存储、块设备、文件系统。它具有高可靠性、安装方便、管理简便、能够轻松管理海量数据。Ceph 存储集群具备了企业级存储的能力,它通过组织大量节点,节点之间靠相互通讯来复制数据、并动态地重分布数据,从而达到高可用分布式存储功能

使用 Rook 可以轻松实现在 Kubernetes 上部署并运行 Ceph 存储系统,并且提供 Dashboard 供用户查看存储系统信息,Rook 跟 Kubernetes 集成关系示意图如下:

kubernetes+rook

说明一下:

  • Rook 提供了卷插件,来扩展了 K8S 的存储系统,使用 Kubelet 代理程序 Pod 可以挂载 Rook 管理的块设备和文件系统。
  • Rook Operator 负责启动并监控整个底层存储系统,例如 Ceph Pod、Ceph OSD 等,同时它还管理 CRD、对象存储、文件体统。
  • Rook Agent 代理部署在 K8S 每个节点上以 Pod 容器运行,每个代理 Pod 都配置一个 Flexvolume 驱动,该驱动 主要用来跟 K8S 的卷控制框架集成起来,每个节点上的跟操作相关的操作,例如添加存储设备、挂载、格式化、删除存储等操作,都有该代理来完成。

使用 Rook 部署并管理 Ceph 存储系统,其架构图如下:

rook + ceph

2、环境、软件准备

本次演示环境,我是在虚拟机上安装 Linux 系统来执行操作,通过虚拟机完成 Kubernetes HA 集群的搭建,以下是安装的软件及版本:

  • Oracle VirtualBox: 5.1.20 r114628 (Qt5.6.2)
  • System: CentOS Linux release 7.3.1611 (Core)
  • kubernetes: 1.12.1
  • docker: 18.06.1-ce
  • etcd: 3.3.8
  • Keepalived: v1.3.5
  • HaProxy: version 1.5.18
  • cfssl version 1.2.0
  • Rook version 0.9

注意:Rook 支持的 Kubernetes 版本 >= 1.8,所以我们搭建的 Kubernetes 集群版本要在该版本以上,这里我们使用 1.12.1 版本。Rook 如果配置了 dataDirHostPath 参数来存储 Rook 数据到 Kubernetes 集群主机上,那么需要分配至少 5G 磁盘空间给该路径。

3、Kubernetes HA 集群搭建

Kubernetes HA 集群搭建,主要包含 Etcd HA 和 Master HA。Etcd HA 这个很容易办到,通过搭建 Etcd 集群即可(注意 Etcd 集群只能有奇数个节点)。Master HA 这个稍微麻烦一些,多主的意思就是多个 Kubernetes Master 节点组成,任意一个 Master 挂掉后,自动切换到另一个备用 Master,而且整个集群 Cluster-IP 不发生变化,从而实现高可用。而实现切换时 Cluster-IP 不变化,目前采用最多的方案就是 haproxy + keepalived 实现负载均衡,然后使用 VIP(虚地址) 方式来实现的。

这里推荐使用 kubeasz 项目,该项目致力于提供快速部署高可用 k8s 集群的工具,它基于二进制方式部署和利用 ansible-playbook 实现自动化安装,同时集成了很多常用插件,而且都有对应的文档说明,非常方便操作。它提供了单节点、单主多节点、多主多节点、在公有云上部署等方案,通过它很容易就能完成各种类型版本 k8s 集群的搭建。

本次,我们要搭建的就是多主多节点 HA 集群,请参照 kubeasz 文档 来执行,非常方便,亲测可行,这里就不在演示了。说明一下:同时由于本机内存限制,共开启了 4 个虚拟机节点,每个节点都分别充当了一个或多个角色。

高可用集群节点配置:

  • 部署节点 x 1: 10.222.78.60
  • etcd 节点 x 3: 10.222.78.63、10.222.78.64、10.222.78.86
  • master 节点 x 2: 10.222.78.63、10.222.78.64
  • lb 节点 x 2: 10.222.78.63(主)、10.222.78.64(备)
  • node 节点 x 1 : 10.222.77.86

部署完成后,通过如下命令查看下是否部署成功。

$ kubectl get cs
NAME                 STATUS    MESSAGE             ERROR
controller-manager   Healthy   ok                  
scheduler            Healthy   ok                  
etcd-2               Healthy   {"health":"true"}   
etcd-1               Healthy   {"health":"true"}   
etcd-0               Healthy   {"health":"true"} 

$ kubectl get nodes
NAME            STATUS                     ROLES    AGE   VERSION
10.222.78.63    Ready,SchedulingDisabled   master   1h    v1.12.1
10.222.78.64    Ready,SchedulingDisabled   master   1h    v1.12.1
10.222.78.86    Ready                      node     1h    v1.12.1

默认 K8S Master 节点不参入调度的,不过为了下边每个节点都能部署相应的 Pod,所以这里将两个 Master 节点设置为参与调用。

$ kubectl uncordon 10.222.78.63
$ kubectl uncordon 10.222.78.64
$ kubectl get nodes
NAME           STATUS   ROLES    AGE   VERSION
10.222.78.63   Ready    master   1h    v1.12.1
10.222.78.64   Ready    master   1h    v1.12.1
10.222.78.86   Ready    node     1h    v1.12.1

4、部署 Rook Operator

环境准备就绪,现在可以开始部署 Rook Operator,上来我先填个坑!

$ git clone https://github.com/rook/rook.git
$ cd rook/cluster/examples/kubernetes/ceph
$ kubectl create -f operator.yaml 
$ kubectl create -f cluster.yaml

如果正常的话,Rook 会创建好所有需要的资源,但是很遗憾,你会发现当 cluster.yaml 创建完毕后,不会创建 rook-ceph-mgrrook-ceph-monrook-ceph-osd 等资源。这是个坑,可以参考 Rook Github Issues 2338 这里,我们可以通过查看 rook-ceph-operator Pod 的日志来分析下:

$ kubectl logs -n rook-ceph-system rook-ceph-operator-68576ff976-m9m6l
......
E0107 12:06:23.272607       6 reflector.go:205] github.com/rook/rook/vendor/github.com/rook/operator-kit/watcher.go:76: Failed to list *v1beta1.Cluster: the server could not find the requested resource (get clusters.ceph.rook.io)
E0107 12:06:24.274364       6 reflector.go:205] github.com/rook/rook/vendor/github.com/rook/operator-kit/watcher.go:76: Failed to list *v1beta1.Cluster: the server could not find the requested resource (get clusters.ceph.rook.io)
E0107 12:06:25.288800       6 reflector.go:205] github.com/rook/rook/vendor/github.com/rook/operator-kit/watcher.go:76: Failed to list *v1beta1.Cluster: the server could not find the requested resource (get clusters.ceph.rook.io)

类似以上日志输出,这是因为创建的 CRDs 资源版本不匹配导致的。正确的方法就是切换到最新固定版本,正确的操作如下:

$ git clone https://github.com/rook/rook.git
$ git checkout -b release-0.9 remotes/origin/release-0.9
$ git branch -a
  master
* release-0.9
  remotes/origin/HEAD -> origin/master
  remotes/origin/master
  remotes/origin/release-0.4
  remotes/origin/release-0.5
  remotes/origin/release-0.6
  remotes/origin/release-0.7
  remotes/origin/release-0.8
  remotes/origin/release-0.9
$ cd rook/cluster/examples/kubernetes/ceph

# 部署 Rook Operator
$ kubectl create -f operator.yaml 
namespace/rook-ceph-system created
customresourcedefinition.apiextensions.k8s.io/cephclusters.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephfilesystems.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectstores.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephobjectstoreusers.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/cephblockpools.ceph.rook.io created
customresourcedefinition.apiextensions.k8s.io/volumes.rook.io created
clusterrole.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
role.rbac.authorization.k8s.io/rook-ceph-system created
clusterrole.rbac.authorization.k8s.io/rook-ceph-global created
clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
serviceaccount/rook-ceph-system created
rolebinding.rbac.authorization.k8s.io/rook-ceph-system created
clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-global created
deployment.apps/rook-ceph-operator created

$ kubectl get pods -n rook-ceph-system
NAME                                  READY   STATUS              RESTARTS   AGE
rook-ceph-operator-68576ff976-m9m6l   0/1     ContainerCreating   0          27s

$ kubectl get pods -n rook-ceph-system
NAME                                  READY   STATUS    RESTARTS   AGE
rook-ceph-agent-mjzz5                 1/1     Running   0          5m35s
rook-ceph-agent-tsk9l                 1/1     Running   0          5m35s
rook-ceph-agent-w6vfx                 1/1     Running   0          5m35s
rook-ceph-operator-68576ff976-m9m6l   1/1     Running   0          6m17s
rook-discover-44zh5                   1/1     Running   0          5m35s
rook-discover-dzpts                   1/1     Running   0          5m35s
rook-discover-txl96                   1/1     Running   0          5m35s

说明一下,这里先创建了 rook-ceph-operator,然后在由它在每个节点创建 rook-ceph-agentrook-discover。接下来,就可以部署 CephCluster 了。

$ kubectl create -f cluster.yaml 
namespace/rook-ceph created
serviceaccount/rook-ceph-osd created
serviceaccount/rook-ceph-mgr created
role.rbac.authorization.k8s.io/rook-ceph-osd created
role.rbac.authorization.k8s.io/rook-ceph-mgr-system created
role.rbac.authorization.k8s.io/rook-ceph-mgr created
rolebinding.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
rolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-system created
rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
cephcluster.ceph.rook.io/rook-ceph created

$ kubectl get cephcluster -n rook-ceph
NAME        DATADIRHOSTPATH   MONCOUNT   AGE   STATE
rook-ceph   /var/lib/rook     3          29m   Created

$ kubectl get pod -n rook-ceph
NAME                                       READY   STATUS      RESTARTS   AGE
rook-ceph-mgr-a-79564676c7-5crc5           1/1     Running     0          30m
rook-ceph-mon-a-56bfd58fdd-sql6w           1/1     Running     0          31m
rook-ceph-mon-b-68df678588-djj5v           1/1     Running     0          31m
rook-ceph-mon-c-65d8945f5-n4qsv            1/1     Running     0          30m
rook-ceph-osd-0-6ccbd4dc4d-2w9jt           1/1     Running     0          30m
rook-ceph-osd-1-647cbb4b84-65ttr           1/1     Running     0          30m
rook-ceph-osd-2-7b8ff9fc47-g8l6q           1/1     Running     0          30m
rook-ceph-osd-prepare-10.222.78.63-vvv9r   0/2     Completed   1          30m
rook-ceph-osd-prepare-10.222.78.64-nbfwz   0/2     Completed   0          30m
rook-ceph-osd-prepare-10.222.78.86-gp6fj   0/2     Completed   0          30m

说明一下,从 cluster.yaml 文件描述可以看出

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
......
  dataDirHostPath: /var/lib/rook
  mon:
    count: 3
    allowMultiplePerNode: true
  dashboard:
    enabled: true
  network:
    hostNetwork: false
  rbdMirroring:
    workers: 0

cephcluster 是一个 CRD 自定义资源类型,通过它来创建一些列 ceph 的 mgr、osd 等。我们可以直接使用默认配置,默认开启 3 个 mon 资源,dataDirHostPath 存储路径在 /var/lib/rook,当然也可以自定义配置,例如 DATADIRHOSTPATHMONCOUNT 等,可以参考官网文档 ceph-cluster-crd

5、配置 Rook Dashboard

创建完毕,我们可以使用默认启动的 Dashboard 来查看一下,默认 cluster.yaml
dashboard: enabled: true 配置为 true,那么就会自动创建 Dashboard 服务了。

$ kubectl get svc -n rook-ceph |grep mgr-dashboard
rook-ceph-mgr-dashboard                  ClusterIP   10.68.18.172    <none>        8443/TCP         33m

但是默认服务类型为 ClusterIP 类型,只能集群内部访问,通过
https://rook-ceph-mgr-dashboard-https:8443 或者 https://10.68.18.172:8443 地址访问,如果外部访问的话,就需要使用 NodePort 服务暴漏方式。

$ kubectl create -f dashboard-external-https.yaml 
service/rook-ceph-mgr-dashboard-external-https created
$ kubectl get svc -n rook-ceph |grep mgr-dashboard
rook-ceph-mgr-dashboard                  ClusterIP   10.68.18.172    <none>        8443/TCP         23m
rook-ceph-mgr-dashboard-external-https   NodePort    10.68.95.24     <none>        8443:33665/TCP   6m58s

# 查看 K8S 集群 IP
$ kubectl cluster-info |grep master
Kubernetes master is running at https://10.222.78.63:8443

外部通过 https://<Cluster_ip>:<NodePort> 地址访问,这里我可以通过 https://10.222.78.63:33665 地址访问页面,默认跳转到了登录页面 https://10.222.78.63:33665/#/login 登录页面。
rook-dashboard
但是需要用户名和密码,这里有两种方式获取:

方式一:rook-ceph 默认创建了一个 rook-ceph-dashboard-passwordsecret,可以用这种方式获取 password。

$ kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath='{.data.password}'  |  base64 --decode
21rWFIGtRG

注意:这里的 password 使用了 base64 加密,需要解密一下才可以使用。

方式二,从 rook-ceph-mgr Pod 的日志中获取,日志会打印出来用户名和密码。

$ kubectl get pod -n rook-ceph | grep mgr
rook-ceph-mgr-a-79564676c7-5crc5           1/1     Running     0          24m
$ kubectl -n rook-ceph logs rook-ceph-mgr-a-79564676c7-5crc5 | grep password
2019-01-07 13:32:02.315 7fea0989a700  0 log_channel(audit) log [DBG] : from='client.4168 172.20.0.4:0/4240445010' entity='client.admin' cmd=[{"username": "admin", "prefix": "dashboard set-login-credentials", "password": "21rWFIGtRG", "target": ["mgr", ""], "format": "json"}]: dispatch

使用 admin 账户和上边的密码登录一下,可以登录成功。
rook-dashboard
不过目前只能查看 cluster 中的 HostsMonitorsOSDS 信息,其他 Pools (数据池)Block (块设备)Filesystem (文件系统)Object Gateway (对象存储)暂时没有涉及到,下边会逐步演示到。如果对 Ceph 的块设备、文件系统、对象存储不太清楚的,可以参考之前文章 初试 Ceph 存储之块设备、文件系统、对象存储
rook-dashboard-hosts

rook-dashboard-monitor

rook-dashboard-osds

6、部署 Rook toolbox 并测试

我们知道 Ceph 是有 CLI 工具来查看集群信息的,但是默认启动的 Ceph 集群时开启了 cephx 认证,登录 Ceph 各组件所在的 Pod 是没法执行 CLI 命令的,我们来实验一下:

$ kubectl -n rook-ceph get pod | grep rook-ceph-mon
rook-ceph-mon-a-56bfd58fdd-sql6w           1/1     Running     0          43m
rook-ceph-mon-b-68df678588-djj5v           1/1     Running     0          43m
rook-ceph-mon-c-65d8945f5-n4qsv            1/1     Running     0          42m

# 登录任意一个 Pod,执行 Ceph 命令
$ kubectl -n rook-ceph exec -it rook-ceph-mon-a-56bfd58fdd-sql6w bash
[root@rook-ceph-mon-a-56bfd58fdd-sql6w /]# ceph status
2019-01-07 15:06:03.720 7f7df9d4b700 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory
2019-01-07 15:06:03.720 7f7df9d4b700 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin,: (2) No such file or directory
2019-01-07 15:06:03.722 7f7df9d4b700 -1 monclient: authenticate NOTE: no keyring found; disabled cephx authentication
2019-01-07 15:06:03.722 7f7df9d4b700 -1 monclient: authenticate NOTE: no keyring found; disabled cephx authentication
[errno 95] error connecting to the cluster

从日志可以看到,auth: unable to find a keyring on /etc/ceph/,是没有 cephx 认证文件的。此时需要部署一个 Ceph toolboxtoolbox 以容器的方式在 K8S 内运行,它包含了 cephx 认证文件以及各种 Ceph clients 工具的。我们可以用它来执行一些 Ceph 相关的测试或调试操作。

$ kubectl create -f toolbox.yaml 
deployment.apps/rook-ceph-tools created
$ kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o wide
NAME                               READY   STATUS    RESTARTS   AGE     IP             NODE           NOMINATED NODE
rook-ceph-tools-5bd5cdb949-d22ql   1/1     Running   0          2m15s   10.222.78.64   10.222.78.64   <none>

# Pod 被分配到 node2 上了。
$ kubectl -n rook-ceph exec -it rook-ceph-tools-5bd5cdb949-d22ql bash
[root@node2 /]# ceph status
  cluster:
    id:     6c117372-a462-447c-bfd4-a0378393f69e
    health: HEALTH_WARN
            clock skew detected on mon.a, mon.c
  services:
    mon: 3 daemons, quorum b,a,c
    mgr: a(active)
    osd: 3 osds: 3 up, 3 in
  data:
    pools:   0 pools, 0 pgs
    objects: 0  objects, 0 B
    usage:   21 GiB used, 75 GiB / 96 GiB avail
    pgs:
    
[root@node2 /]# ceph df
GLOBAL:
    SIZE       AVAIL      RAW USED     %RAW USED 
    96 GiB     75 GiB       21 GiB         21.52 
POOLS:
    NAME     ID     USED     %USED     MAX AVAIL     OBJECTS 

[root@node2 /]# ceph osd status
+----+----------------------------------+-------+-------+--------+---------+--------+---------+-----------+
| id |               host               |  used | avail | wr ops | wr data | rd ops | rd data |   state   |
+----+----------------------------------+-------+-------+--------+---------+--------+---------+-----------+
| 0  | rook-ceph-osd-0-6ccbd4dc4d-2w9jt | 7893M | 24.2G |    0   |     0   |    0   |     0   | exists,up |
| 1  | rook-ceph-osd-1-647cbb4b84-65ttr | 5148M | 26.9G |    0   |     0   |    0   |     0   | exists,up |
| 2  | rook-ceph-osd-2-7b8ff9fc47-g8l6q | 8096M | 24.0G |    0   |     0   |    0   |     0   | exists,up |
+----+----------------------------------+-------+-------+--------+---------+--------+---------+-----------+    

[root@node2 /]# rados df
POOL_NAME USED OBJECTS CLONES COPIES MISSING_ON_PRIMARY UNFOUND DEGRADED RD_OPS RD WR_OPS WR 

total_objects    0
total_used       21 GiB
total_avail      75 GiB
total_space      96 GiB

# 创建一个新的 pool 
[root@node2 /]# ceph osd pool create test_pool 64
pool 'test_pool' created
[root@node2 /]# ceph osd pool get test_pool size
size: 1

# 再次执行 ceph df 查看是否显示创建的 pool
[root@node2 /]# ceph df
GLOBAL:
    SIZE       AVAIL      RAW USED     %RAW USED 
    96 GiB     75 GiB       21 GiB         21.52 
POOLS:
    NAME          ID     USED     %USED     MAX AVAIL     OBJECTS 
    test_pool     1       0 B         0        67 GiB           0 

可以看到在 toolbox 内部可以执行 CLI 相关命令,此时我们在 Dashboard 上就可以看到创建的 pool 了。
rook-dashboard-pools

7、部署 Ceph Monitoring Prometheus 监控

服务起来了,我们需要实时监控它,这里可以选择 Prometheus 来作为监控组件,部署 Prometheus 可以采用 Prometheus Operator 来部署。

7.1、部署 Prometheus Operator

首先需要部署 Prometheus Operator,部署完毕后,直到 prometheus-operator Pod 状态为 Running 时,才能执行下一步操作。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/prometheus-operator/v0.26.0/bundle.yaml
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator created
clusterrole.rbac.authorization.k8s.io/prometheus-operator created
deployment.apps/prometheus-operator created
serviceaccount/prometheus-operator created
# kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
prometheus-operator-544f649-bhfxz   1/1     Running   0          13m

7.2、部署 Prometheus 实例

Rook 为我们提供好了部署 Prometheus 实例的 yaml 文件。

$ cd cluster/examples/kubernetes/ceph/monitoring
$ kubectl create -f ./
service/rook-prometheus created
serviceaccount/prometheus created
clusterrole.rbac.authorization.k8s.io/prometheus created
clusterrolebinding.rbac.authorization.k8s.io/prometheus created
prometheus.monitoring.coreos.com/rook-prometheus created
servicemonitor.monitoring.coreos.com/rook-ceph-mgr created

$ kubectl -n rook-ceph get pod |grep prometheus-rook
prometheus-rook-prometheus-0               3/3     Running     1          10m

等到 prometheus-rook-prometheus-0 状态为 Running 后,我们就可以访问它了。

7.3、访问 Prometheus Dashboard

Prometheus Dashboard 服务启动后,默认暴漏服务类型为 NodePort,端口号为 30900,那么我们可以通过访问 http://<Cluster_IP>:30900 页面,这里我可以通过 http://10.222.78.63:30900 地址访问。

$ kubectl -n rook-ceph get svc |grep rook-prometheus
rook-prometheus                          NodePort    10.68.152.50    <none>        9090:30900/TCP   13m

rook-prometheus-graph

rook-promethues-targets

下一篇文章,将基于已经搭建好的 Rook 系统,验证一下其提供 Block 块存储、FileSystem 文件存储、Object Gateway 对象存储功能。

参考资料

猜你喜欢

转载自blog.csdn.net/aixiaoyang168/article/details/86215080