使用Rook在Kubernetes上部署Ceph集群
一、简介
在本文中,我们将使用Rook在Kubernetes集群中设置Ceph存储。然后使用Ceph的块存储来持久存储MongoDB数据库的数据。
完成后,您将了解什么是Rook以及如何使用它来部署Ceph。您还将了解如何使用Rook在Kubernetes中部署其他一些存储后端。
二、环境准备
在开始之前,您需要满足以下条件:
- 事先准备好一个具有4个节点的Kubernetes集群:1个Master节点和3个Node节点。每个节点都是具有至少4GB RAM 的Ubuntu 18.04服务器。在本教程中,主节点命名为master,工作节点命名为node-01,node-02和node-03。
- 配置为与上述集群通信的kubectl实用程序。
主机 | 系统 | IP | 配置 |
---|---|---|---|
master | ubuntu18.04 | 10.10.10.61 | 4C8G50G |
node-01 | ubuntu18.04 | 10.10.10.58 | 4C8G50G+50G |
node-02 | ubuntu18.04 | 10.10.10.59 | 4C8G50G+50G |
node-03 | ubuntu18.04 | 10.10.10.60 | 4C8G50G+50G |
1kubectl get node
2NAME STATUS ROLES AGE VERSION
310.10.10.58 Ready worker 81s v1.18.6
410.10.10.59 Ready worker 81s v1.18.6
510.10.10.60 Ready worker 81s v1.18.6
610.10.10.61 Ready controlplane,etcd 84s v1.18.6
备注
如果你还没有Kubernetes集群,推荐使用RKE快速部署Kubernetes集群
工作节点的50G磁盘用于Ceph OSD使用。
三、安装部署
3.1 部署Rook Operator
Rook是[Cloud Native Computing Foundation(CNCF)](https://cncf.io)的一个孵化项目。它专用于存储编排,并允许在Kubernetes集群中直接部署多个存储解决方案。在本文中,我们将重点介绍Ceph存储,但是还可以使用其他存储解决方案。
备注:Ceph和EdgeFS当前是Rook处于Stable状态所支持的两个存储提供程序。其他存储提供程序(如Cassandra,Minio,NFS,CockroachDB,YugabyteDB)处于Alpha状态。
首先,我们从GitHub仓库release页面下载并使用Release 1.4.1(迄今为止的最新版本)
1wget https://github.com/rook/rook/archive/v1.4.1.tar.gz
2tar xf v1.4.1.tar.gz
3cd rook-1.4.1
对于Rook支持的每个存储解决方案,都有一个Kubernetes Operator。简而言之,Operator是一个运行在Pod中的包含管理复杂应用程序的所有逻辑的应用。Operator通常用于管理有状态的应用程序。
首先,我们将进入包含Ceph需要的所有资源的文件夹。
1cd cluster/examples/kubernetes/ceph
接下来,我们部署Rook的Ceph Operator所需的所有资源。
1kubectl create -f common.yaml
2namespace/rook-ceph created
3customresourcedefinition.apiextensions.k8s.io/cephclusters.ceph.rook.io created
4customresourcedefinition.apiextensions.k8s.io/cephclients.ceph.rook.io created
5customresourcedefinition.apiextensions.k8s.io/cephrbdmirrors.ceph.rook.io created
6customresourcedefinition.apiextensions.k8s.io/cephfilesystems.ceph.rook.io created
7customresourcedefinition.apiextensions.k8s.io/cephnfses.ceph.rook.io created
8customresourcedefinition.apiextensions.k8s.io/cephobjectstores.ceph.rook.io created
9customresourcedefinition.apiextensions.k8s.io/cephobjectstoreusers.ceph.rook.io created
10customresourcedefinition.apiextensions.k8s.io/cephobjectrealms.ceph.rook.io created
11customresourcedefinition.apiextensions.k8s.io/cephobjectzonegroups.ceph.rook.io created
12customresourcedefinition.apiextensions.k8s.io/cephobjectzones.ceph.rook.io created
13customresourcedefinition.apiextensions.k8s.io/cephblockpools.ceph.rook.io created
14customresourcedefinition.apiextensions.k8s.io/volumes.rook.io created
15customresourcedefinition.apiextensions.k8s.io/objectbuckets.objectbucket.io created
16customresourcedefinition.apiextensions.k8s.io/objectbucketclaims.objectbucket.io created
17clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-object-bucket created
18serviceaccount/rook-ceph-admission-controller created
19clusterrole.rbac.authorization.k8s.io/rook-ceph-admission-controller-role created
20clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-admission-controller-rolebinding created
21clusterrole.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
22role.rbac.authorization.k8s.io/rook-ceph-system created
23clusterrole.rbac.authorization.k8s.io/rook-ceph-global created
24clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
25clusterrole.rbac.authorization.k8s.io/rook-ceph-object-bucket created
26serviceaccount/rook-ceph-system created
27rolebinding.rbac.authorization.k8s.io/rook-ceph-system created
28clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-global created
29serviceaccount/rook-ceph-osd created
30serviceaccount/rook-ceph-mgr created
31serviceaccount/rook-ceph-cmd-reporter created
32role.rbac.authorization.k8s.io/rook-ceph-osd created
33clusterrole.rbac.authorization.k8s.io/rook-ceph-osd created
34clusterrole.rbac.authorization.k8s.io/rook-ceph-mgr-system created
35role.rbac.authorization.k8s.io/rook-ceph-mgr created
36role.rbac.authorization.k8s.io/rook-ceph-cmd-reporter created
37rolebinding.rbac.authorization.k8s.io/rook-ceph-cluster-mgmt created
38rolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
39rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr created
40rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-system created
41clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-cluster created
42clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-osd created
43rolebinding.rbac.authorization.k8s.io/rook-ceph-cmd-reporter created
44podsecuritypolicy.policy/00-rook-privileged created
45clusterrole.rbac.authorization.k8s.io/psp:rook created
46clusterrolebinding.rbac.authorization.k8s.io/rook-ceph-system-psp created
47rolebinding.rbac.authorization.k8s.io/rook-ceph-default-psp created
48rolebinding.rbac.authorization.k8s.io/rook-ceph-osd-psp created
49rolebinding.rbac.authorization.k8s.io/rook-ceph-mgr-psp created
50rolebinding.rbac.authorization.k8s.io/rook-ceph-cmd-reporter-psp created
51serviceaccount/rook-csi-cephfs-plugin-sa created
52serviceaccount/rook-csi-cephfs-provisioner-sa created
53role.rbac.authorization.k8s.io/cephfs-external-provisioner-cfg created
54rolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role-cfg created
55clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
56clusterrole.rbac.authorization.k8s.io/cephfs-external-provisioner-runner created
57clusterrolebinding.rbac.authorization.k8s.io/rook-csi-cephfs-plugin-sa-psp created
58clusterrolebinding.rbac.authorization.k8s.io/rook-csi-cephfs-provisioner-sa-psp created
59clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
60clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role created
61serviceaccount/rook-csi-rbd-plugin-sa created
62serviceaccount/rook-csi-rbd-provisioner-sa created
63role.rbac.authorization.k8s.io/rbd-external-provisioner-cfg created
64rolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role-cfg created
65clusterrole.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
66clusterrole.rbac.authorization.k8s.io/rbd-external-provisioner-runner created
67clusterrolebinding.rbac.authorization.k8s.io/rook-csi-rbd-plugin-sa-psp created
68clusterrolebinding.rbac.authorization.k8s.io/rook-csi-rbd-provisioner-sa-psp created
69clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-nodeplugin created
70clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role created
这些资源主要是CustomRessourceDefinitions,也称为CRD。它们用于定义将由Operator使用的新资源(Kubernetes中默认不存在的读取资源)。创建的其他资源主要与访问权限链接,因此Operator可以与集群的API Server进行通信:
- ServiceAccount
- Role
- RoleBinding
- ClusterRole
- ClusterRoleBinding
接下来,我们部署Ceph Operator,该Operator将负责Ceph集群的设置和协调。
1kubectl create -f operator.yaml
2configmap/rook-ceph-operator-config created
3deployment.apps/rook-ceph-operator created
Operator需要几秒钟来启动并运行。可以使用以下命令验证其状态。
1kubectl get pod -n rook-ceph
一旦Operator准备就绪,它将触发创建**DaemonSet,**以负责在Kubernetes集群的每个Node节点上部署rook-discover代理。
最后,一切设置完成后,上述命令的结果类似于以下输出。
1NAME READY STATUS RESTARTS AGE
2rook-ceph-operator-58496b74f9-qppxc 1/1 Running 0 4m18s
3rook-discover-cmt2x 1/1 Running 0 3m6s
4rook-discover-p92sh 1/1 Running 0 3m6s
5rook-discover-q9k5z 1/1 Running 0 3m6s
注意
Operator在您的环境中会有所不同
现在一切就绪,可以使用操作员部署Ceph集群了。
3.2 创建Ceph集群
现在,我们将在Kubernetes集群中创建一个Ceph集群。
下图显示了所有与Ceph相关的过程,这些过程将在集群中作为Pod运行。
Rook架构
- mgr是Manager守护程序,负责跟踪运行时指标和Ceph集群的当前状态。对于高可用性群集,至少需要2个Ceph管理器
- mon是一个**Monitor,**负责维护Ceph守护程序相互协调所需的集群状态映射。对于高可用性群集,至少需要三个监视器
- osd是一个对象存储守护程序,负责存储数据,处理数据复制,恢复,重新平衡。对于HA Ceph集群,至少需要3个Ceph OSD
首先,我们使用以下规范定义CephCluster资源。
1---
2apiVersion: ceph.rook.io/v1
3kind: CephCluster
4metadata:
5 name: rook-ceph
6 namespace: rook-ceph
7spec:
8 cephVersion:
9 image: ceph/ceph:v14.2
10 allowUnsupported: false
11 dataDirHostPath: /var/lib/rook
12 skipUpgradeChecks: false
13 mon:
14 count: 3
15 allowMultiplePerNode: false
16 dashboard:
17 enabled: true
18 ssl: true
19 monitoring:
20 enabled: false
21 rulesNamespace: rook-ceph
22 network:
23 hostNetwork: false
24 rbdMirroring:
25 workers: 0
26 storage:
27 useAllNodes: true
28 useAllDevices: true
它基本上定义了集群的配置方式。属性useAllNodes和useAllDevices设置为**true,**这样Kubernetes集群的每个工作节点将用于部署Ceph的进程,并且附加到这些节点的所有设备将用于持久存储Ceph集群的数据。
然后我们创建集群:
1kubectl apply -f cluster.yaml
此新CephCluster资源的创建将通知Ceph Operator,并将向API Server发送请求,以创建所有与Ceph相关的Pod。
接下来,我们确保负责Ceph集群的所有Pod都已启动并正在运行。
1kubectl get pod -n rook-ceph
创建集群通常需要几分钟。完成此操作后,我们将获得类似于以下输出的列表。
1NAME READY STATUS RESTARTS AGE
2csi-cephfsplugin-d9wct 3/3 Running 0 5m54s
3csi-cephfsplugin-m2dgp 3/3 Running 0 5m54s
4csi-cephfsplugin-provisioner-598854d87f-b5v79 6/6 Running 0 5m53s
5csi-cephfsplugin-provisioner-598854d87f-jvbz2 6/6 Running 0 5m53s
6csi-cephfsplugin-vrdz7 3/3 Running 0 5m54s
7csi-rbdplugin-9d6cd 3/3 Running 0 5m54s
8csi-rbdplugin-provisioner-dbc67ffdc-p522n 6/6 Running 0 5m54s
9csi-rbdplugin-provisioner-dbc67ffdc-zm6kw 6/6 Running 0 5m54s
10csi-rbdplugin-s2f4f 3/3 Running 0 5m54s
11csi-rbdplugin-tkc66 3/3 Running 0 5m54s
12rook-ceph-crashcollector-10.10.10.58-df496b478-jrjl5 1/1 Running 0 49s
13rook-ceph-crashcollector-10.10.10.59-8487c88d5c-8w28n 1/1 Running 0 4m33s
14rook-ceph-crashcollector-10.10.10.60-7fcd8df78f-xw8j8 1/1 Running 0 2m39s
15rook-ceph-mgr-a-75b8c8b8f6-6c2wz 1/1 Running 0 86s
16rook-ceph-mon-a-7b55d965b7-mr56c 1/1 Running 0 4m33s
17rook-ceph-mon-b-bfdf4cd44-lh4bf 1/1 Running 0 4m23s
18rook-ceph-mon-c-849775f65f-s5ngv 1/1 Running 0 2m39s
19rook-ceph-operator-58496b74f9-qppxc 1/1 Running 0 13m
20rook-ceph-osd-0-7ddf7cf545-4zk24 1/1 Running 0 52s
21rook-ceph-osd-1-6fb7747465-jjdwr 1/1 Running 0 49s
22rook-ceph-osd-2-767bf9d8cb-pgjn2 1/1 Running 0 49s
23rook-ceph-osd-prepare-10.10.10.58-sgl2x 0/1 Completed 0 86s
24rook-ceph-osd-prepare-10.10.10.59-trdgz 0/1 Completed 0 85s
25rook-ceph-osd-prepare-10.10.10.60-mkr2r 0/1 Completed 0 85s
26rook-discover-cmt2x 1/1 Running 0 11m
27rook-discover-p92sh 1/1 Running 0 11m
28rook-discover-q9k5z 1/1 Running 0 11m
备注:标识符在您的环境中会有所不同
Ceph可以提供几种存储方式:
- 文件系统存储
- 对象存储
- 块存储
接下来,我们将创建使用块存储所需的资源。
3.3 从Ceph获取块存储
文件cluster/examples/kubernetes/ceph/csi/rbd/storageclass.yaml
定义了ReplicaPool和StorageClass来自动创建由Ceph块存储备份的Kubernetes PersistentVolume。
首先,我们创建这些资源:
1kubectl apply -f ./csi/rbd/storageclass.yaml
2cephblockpool.ceph.rook.io/replicapool created
3storageclass.storage.k8s.io/rook-ceph-block created
查看刚创建的存储类
1kubectl get sc
2NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
3rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 2m44s
接下来,我们定义PersistentVolumeClaim,一种用于请求存储的资源。由于它使用先前创建的rook-ceph-block StorageClass,它将自动从Ceph集群中调配块存储。
1---
2apiVersion: v1
3kind: PersistentVolumeClaim
4metadata:
5 name: mongo-pvc
6spec:
7 storageClassName: rook-ceph-block
8 accessModes:
9 - ReadWriteOnce
10 resources:
11 requests:
12 storage: 5Gi
接下来,我们使用以下命令创建PersistentVolumeClaim。
1kubectl apply -f pvc-rook-ceph-block.yaml
然后,我们验证PersistentVolumeClaim是否触发了PersistentVolume的创建。
1kubectl get pvc,pv
2NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
3persistentvolumeclaim/mongo-pvc Bound pvc-3e6c456a-8a3d-40bb-ab1b-16d8349f789d 5Gi RWO rook-ceph-block 9s
4
5NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
6persistentvolume/pvc-3e6c456a-8a3d-40bb-ab1b-16d8349f789d 5Gi RWO Delete Bound default/mongo-pvc rook-ceph-block 7s
我们应该得到一个列表,该列表显示PersistentVolumeClaim和自动设置的PersistentVolume之间的绑定。
引擎盖后面的PersistentVolume存储在附加到工作节点的卷上。
在接下来的步骤中,我们将使用此存储来持久存储MongoDB数据库的数据。
3.4 创建MongoDB数据库
现在,我们将部署数据库工作负载,并使用上一步中提供的存储来持久化Pod的数据。
首先,我们定义一个规范,其中包含:
- 一个运行基于mongo:4.0 Docker映像的1个容器的Deployment。该容器使用上面创建的PersistentVolumeClaim mongo-pvc。关联的PersistentVolume安装在容器文件系统中的*/ data / db*上
- 类型为NodePort 的服务,将mongo Pod 暴露在集群每个节点的端口31017上
1---
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: mongo
6spec:
7 selector:
8 matchLabels:
9 app: mongo
10 template:
11 metadata:
12 labels:
13 app: mongo
14 spec:
15 containers:
16 - image: mongo:4.0
17 name: mongo
18 ports:
19 - containerPort: 27017
20 name: mongo
21 volumeMounts:
22 - name: mongo-persistent-storage
23 mountPath: /data/db
24 volumes:
25 - name: mongo-persistent-storage
26 persistentVolumeClaim:
27 claimName: mongo-pvc
28---
29apiVersion: v1
30kind: Service
31metadata:
32 name: mongo
33 labels:
34 app: mongo
35spec:
36 selector:
37 app: mongo
38 type: NodePort
39 ports:
40 - port: 27017
41 nodePort: 31017
然后,我们创建那些资源。
1kubectl apply -f mongo.yaml
2deployment.apps/mongo created
3service/mongo created
接下来,我们可以验证Pod和Service是否正确创建。
1kubectl get pods,svc
2NAME READY STATUS RESTARTS AGE
3pod/mongo-dbcdddc5b-56gfm 1/1 Running 0 60s
4
5NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
6service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 26m
7service/mongo NodePort 10.43.120.20 <none> 27017:31017/TCP 60s
我们有一个数据库Pod将其数据持久存储在基础Ceph存储中。在接下来的步骤中,我们将使用MongoDB客户端并连接并确保一切正常。
3.5 连接数据库
现在,我们将使用MongoDB客户端并连接到上一步中部署的数据库。
这里直接使用mongo命令行工具,你也可以使用其他MongoDB的客户端工具。
1sudo apt -y install mongodb
由于数据库是通过NodePort类型的服务公开的,因此可以从群集的任何节点在特定端口(在本示例中为31017)上访问数据库。
首先,我们获得节点及其外部IP的列表
1kubectl get nodes -o wide
2NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
310.10.10.58 Ready worker 27m v1.18.6 10.10.10.58 <none> Ubuntu 18.04.5 LTS 4.15.0-112-generic docker://19.3.12
410.10.10.59 Ready worker 27m v1.18.6 10.10.10.59 <none> Ubuntu 18.04.5 LTS 4.15.0-112-generic docker://19.3.12
510.10.10.60 Ready worker 27m v1.18.6 10.10.10.60 <none> Ubuntu 18.04.5 LTS 4.15.0-112-generic docker://19.3.12
610.10.10.61 Ready controlplane,etcd 27m v1.18.6 10.10.10.61 <none> Ubuntu 18.04.5 LTS 4.15.0-112-generic docker://19.3.12
接下来,我们选择一个工作节点IP地址,并使用它与客户端连接。
1mongo --host 10.10.10.58 --port 31017
2MongoDB shell version v3.6.3
3connecting to: mongodb://10.10.10.58:31017/
4MongoDB server version: 4.0.20
5WARNING: shell and server versions do not match
6Server has startup warnings:
72020-08-25T01:41:32.357+0000 I STORAGE [initandlisten]
82020-08-25T01:41:32.357+0000 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
92020-08-25T01:41:32.357+0000 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem
102020-08-25T01:41:33.605+0000 I CONTROL [initandlisten]
112020-08-25T01:41:33.605+0000 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
122020-08-25T01:41:33.605+0000 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
132020-08-25T01:41:33.605+0000 I CONTROL [initandlisten]
14>
然后,我们可以访问数据库并添加一些数据。这些数据将保留在基础Ceph存储中,并跨块卷复制。
四、总结
在本文中,您使用了Rook Operator部署了在Kubernetes中运行Ceph集群所需的所有过程。现在,您可以使用Ceph提供的存储解决方案(对象存储,块存储,文件系统存储)以安全的方式持久保存工作负载的数据。
如果您想探索Rook并了解所有可用的所有存储后端,可以查看Rook GitHub仓库。
- 原文作者:黄忠德
- 原文链接:https://huangzhongde.cn/post/Kubernetes/Deploy_A_Ceph_Cluster_On_Kubernetes_With_Rook/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。