Rook部署ceph集群
Ceph介绍
Ceph是一个分布式存储系统,提供文件(file)、块(block)和对象存储(object storage),并在大规模生产集群中部署。
一个Ceph集群至少需要一个Ceph Monitor和一个Manager组件(建议每个Monitor都有一个Manager组件),Ceph Object Storage Daemons(OSDs)则是根据节点的多少而部署多少,必须每个节点都要部署,作为副本复制使用。
Ceph采用数据作为对象存储在逻辑存储池中。Ceph存储采用CRUSH算法来计算哪个Placement Group(PG)应该包含对象,以及哪个OSD应该存储到PG中。CRUSH算法使得Ceph存储具有动态可拓展、可平衡、以及恢复数据的能力。
- Monitors:
Ceph Monitor(ceph-mon)组件维持着Ceph集群的状态,包括monitor数据映射、manager数据映射、osd数据映射、MDS数据映射以及CRUSH映射。同时Monitor也负责管理Ceph守护进程和客户端之间的权限认证。集群部署需要至少3个Monitor来维持高可用状态。 - Managers:
Ceph Manager(ceph-mgr)负责保持运行时指标跟踪和集群状态跟踪,这里包括了存储使用率、当前集群性能指标和集群系统负载。Ceph-Manager作为守护进程,通过Python模块化的功能提供Ceph集群信息,方式为Ceph-Dashboard和REST-API。同时保障高可用需要至少两个Manager进程。 - Ceph OSDs:
Ceph Object Storage Daemon(Ceph OSD,ceph-osd)是Ceph集群的存储组件。负责处理数据复制(replication)、数据恢复(recovery)、数据均衡(rebalance),通过心跳机制提供一些监控数据给Monitor和Managers。高可用集群中需要至少3个OSD节点。 - MDSs:
Ceph Metadata Server(MDS,ceph-mds)负责存储Ceph文件系统的元数据。该组件允许CephFS用户执行一些不会给集群带来负担的基础命令(例如:ls
,find
等)。
以下是Ceph的架构图:
Rook介绍
Rook是一个开源的云原生存储编排组件,通过对Ceph提供平台、框架和支持,使得Ceph能更快速集成到云原生环境中。Rook也是云原生计算基金会(CNCF)的一个项目,从2018年成为孵化项目,并在2020年成为毕业项目。
使用Rook可以自动部署和管理Ceph,提供自我管理、自我扩展和自我修复的存储服务。Rook Operator通过Kubernetes Resources来部署(deploy)、配置(configure)、供应(provision)、扩展(scale)、升级(upgrade)和监控(monitor)Ceph。
环境准备
Ceph集群部署支持多种方式,官方推荐Cephadm和Rook两种部署方式。Cephadm适合独立部署Ceph,可以在k8s外独立部署,而Rook则是直接将Ceph部署到K8s集群内,这样可以合理使用k8s工作节点资源。
其他的部署方式包括:Ceph-ansible、Ceph-deploy、ceph-salt等,当然Ceph也支持手动部署,但手动部署较为复杂。
本文采用Rook方式部署,环境如下:
- 操作系统:Ceotos7.9
- 系统内核:
Linux os-60 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
- Rook版本:v1.15.2
- Ceph版本:v18.2.4
- k8s集群:v1.28.0,containerd: 1.6.33
- 准备4台k8s服务器,1台master,3台工作节点,3台k8s工作节点挂载一个磁盘(但不要挂载),本文采用虚拟机方式部署,需要在VirsualBox或者VM虚拟机上添加一块磁盘。
部署集群
本文采用离线部署,因此需要提前下载Rook仓库代码以及k8s所需要的镜像。
-
挂载磁盘,在三台k8s工作节点上挂载一块20G的磁盘,在服务器上执行:
lsblk
,显示如下"sdb"就是刚才挂载的磁盘:#sdb盘就是刚刚挂载的,TYPE类型是disk,并且没有使用过 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 100G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 99G 0 part ├─centos-root 253:0 0 50G 0 lvm / ├─centos-swap 253:1 0 7.9G 0 lvm └─centos-home 253:2 0 41.1G 0 lvm /home sdb 8:16 0 20G 0 disk sr0 11:0 1 1024M 0 rom
-
准备lvm2环境和rbd模块
#确认安装lvm2 yum install lvm2 -y #启用rbd模块 modprobe rbd cat > /etc/rc.sysinit << EOF #!/bin/bash for file in /etc/sysconfig/modules/*.modules do [ -x \$file ] && \$file done EOF cat > /etc/sysconfig/modules/rbd.modules << EOF modprobe rbd EOF chmod 755 /etc/sysconfig/modules/rbd.modules lsmod |grep rbd #显示如下表示成功加载模块 rbd 83733 2 libceph 314775 2 rbd,ceph
-
rook安装包准备:提前下载rook仓库代码并切换到v1.15.2分支:
git clone https://github.com/rook/rook.git git checkout v1.15.2
-
镜像准备,提前下载如下镜像:
docker.io/rook/ceph:v1.15.2 quay.io/cephcsi/cephcsi:v3.12.2-amd64 registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.11.1 registry.k8s.io/sig-storage/csi-resizer:v1.11.1 registry.k8s.io/sig-storage/csi-provisioner:v5.0.1 registry.k8s.io/sig-storage/csi-snapshotter:v8.0.1 registry.k8s.io/sig-storage/csi-attacher:v4.6.1 quay.io/ceph/ceph:v18.2.4 #找一台可以下载镜像的服务器执行,并将镜像上传到k8s服务器: #rook docker pull --platform=linux/amd64 docker.io/rook/ceph:v1.15.2 docker save -o rook-ceph-v1.15.2.tar.gz docker.io/rook/ceph:v1.15.2 docker pull quay.io/cephcsi/cephcsi:v3.12.2-amd64 docker save -o cephcsi-cephcsi-3.12.2.tar.gz quay.io/cephcsi/cephcsi:v3.12.2-amd64 docker pull --platform=linux/amd64 registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.11.1 docker save -o csi-node-driver-registrar-v2.11.1.tar.gz registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.11.1 docker pull --platform=linux/amd64 registry.k8s.io/sig-storage/csi-resizer:v1.11.1 docker save -o csi-resizer-v1.11.1.tar.gz registry.k8s.io/sig-storage/csi-resizer:v1.11.1 docker pull --platform=linux/amd64 registry.k8s.io/sig-storage/csi-provisioner:v5.0.1 docker save -o csi-provisioner-v5.0.1.tar.gz registry.k8s.io/sig-storage/csi-provisioner:v5.0.1 docker pull --platform=linux/amd64 registry.k8s.io/sig-storage/csi-snapshotter:v8.0.1 docker save -o csi-snapshotter-v8.0.1.tar.gz registry.k8s.io/sig-storage/csi-snapshotter:v8.0.1 docker pull --platform=linux/amd64 registry.k8s.io/sig-storage/csi-attacher:v4.6.1 docker save -o csi-attacher-v4.6.1.tar.gz registry.k8s.io/sig-storage/csi-attacher:v4.6.1 #ceph cluster docker pull --platform=linux/amd64 quay.io/ceph/ceph:v18.2.4 docker save -o ceph-ceph-v18.2.4.tar.gz quay.io/ceph/ceph:v18.2.4
-
k8s服务器上导入镜像,需要在所有的k8s节点上执行:
ctr -n k8s.io image import rook-ceph-v1.15.2.tar.gz && \ ctr -n k8s.io image import ceph-ceph-v18.2.4.tar.gz && \ ctr -n k8s.io image import cephcsi-cephcsi-3.12.2.tar.gz && \ ctr -n k8s.io image import csi-node-driver-registrar-v2.11.1.tar.gz && \ ctr -n k8s.io image import csi-resizer-v1.11.1.tar.gz && \ ctr -n k8s.io image import csi-provisioner-v5.0.1.tar.gz && \ ctr -n k8s.io image import csi-snapshotter-v8.0.1.tar.gz && \ ctr -n k8s.io image import csi-attacher-v4.6.1.tar.gz
部署Rook Operator
安装部署Rook需要在k8s的master节点,首先将Rook仓库代码上传到k8s的master节点上。
进入Rook仓库目录,Rook部署所需要的yaml文件都位于仓库:deploy/examples
下,部署Rook我们需要三个yaml,分别是:common.yaml
、operator.yaml
和 crds.yaml
。
-
进入文件目录
cd rook/deploy/examples
-
部署Rook
kubectl create -f crds.yaml -f common.yaml -f operator.yaml
-
部署ceph集群,在执行部署前,需要修改cluster.yaml的部分配置,修改如下:
#vim cluster.yaml #修改rook存储目录,存放rook相关配置 dataDirHostPath: /home/data/rook #改为false,并非使用所有节点所有磁盘作为osd,devices的name修改为之前挂载的磁盘的名字“sdb” useAllNodes: true useAllDevices: false devices: - name: "sdb" #可选:自定义部署节点,只有useAllNodes为false时生效 nodes: - name: "os-60" deviceFilter: "sdb" - name: "os-61" deviceFilter: "sdb" - name: "os-62" deviceFilter: "sdb" #执行安装Ceph集群 kubectl create -f cluster.yaml
-
查看集群部署情况,部署完毕会在k8s中创建rook-ceph命名空间,所有的rook以及ceph管理都在该空间下。
kubectl -n rook-ceph get pods
-
查看Ceph集群状态:
kubectl get cephcluster -n rook-ceph #显示如下 NAME DATADIRHOSTPATH MONCOUNT AGE PHASE MESSAGE HEALTH EXTERNAL FSID rook-ceph /home/data/rook 3 14d Ready Cluster created successfully HEALTH_WARN 56ff0f1a-1099-4c7a-b3b9-c335ef307206
部署Ceph工具
rook镜像中提供一个ceph镜像工具,内部集成了ceph所有的命令,该工具的pod位于 rook/deploy/examples
内,
cd rook/deploy/examples
kubectl create -f toolbox.yaml
#进入ceph工具内
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
#查看ceph集群状态
ceph status
#结果如下:
bash-5.1$ ceph status
cluster:
id: 56ff0f1a-1099-4c7a-b3b9-c335ef307206
health: HEALTH_WARN
1 mgr modules have recently crashed
services:
mon: 3 daemons, quorum a,b,c (age 29h)
mgr: b(active, since 29h), standbys: a
mds: 1/1 daemons up, 1 hot standby
osd: 3 osds: 3 up (since 29h), 3 in (since 2w)
data:
volumes: 1/1 healthy
pools: 4 pools, 81 pgs
objects: 626 objects, 2.1 GiB
usage: 6.3 GiB used, 54 GiB / 60 GiB avail
pgs: 81 active+clean
io:
client: 852 B/s rd, 1 op/s rd, 0 op/s wr
#查看磁盘使用情况
ceph df
#结果如下,可以看到集群磁盘总大小为60G,已使用6.3G。
bash-5.1$ ceph df
--- RAW STORAGE ---
CLASS SIZE AVAIL USED RAW USED %RAW USED
hdd 60 GiB 54 GiB 6.3 GiB 6.3 GiB 10.57
TOTAL 60 GiB 54 GiB 6.3 GiB 6.3 GiB 10.57
--- POOLS ---
POOL ID PGS STORED OBJECTS USED %USED MAX AVAIL
.mgr 1 1 577 KiB 2 1.7 MiB 0 17 GiB
replicapool 2 32 1.0 GiB 340 3.1 GiB 5.78 17 GiB
myfs-metadata 3 16 468 KiB 26 1.5 MiB 0 17 GiB
myfs-replicated 4 32 1.0 GiB 258 3.0 GiB 5.59 17 GiB
部署Dashboard
ceph提供一个对外的web管理页面,由ceph-Manager提供,但需要暴露service才可以使用,rook的目录下提供一个暴露service的yaml。
cd rook/deploy/examples
kubectl apply -f dashboard-external-https.yaml
#查看service对外端口
kubectl -n rook-ceph get svc
#显示如下,其中rook-ceph-mgr-dashboard-external-https对应的NodePort为31332,访问k8s集群+该端口即可访问管理页
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
rook-ceph-exporter ClusterIP 10.103.229.154 <none> 9926/TCP 14d
rook-ceph-mgr ClusterIP 10.98.218.12 <none> 9283/TCP 14d
rook-ceph-mgr-dashboard ClusterIP 10.108.108.105 <none> 8443/TCP 14d
rook-ceph-mgr-dashboard-external-https NodePort 10.102.158.148 <none> 8443:31332/TCP 14d
rook-ceph-mon-a ClusterIP 10.99.37.109 <none> 6789/TCP,3300/TCP 14d
rook-ceph-mon-b ClusterIP 10.98.151.62 <none> 6789/TCP,3300/TCP 14d
rook-ceph-mon-c ClusterIP 10.97.186.37 <none> 6789/TCP,3300/TCP 14d
本机的k8s集群master节点时10.0.0.60,因此访问地址:https://10.0.0.60:31332
,即可访问dashboard页面:
管理页面的账号是 admin
,密码需要通过k8s-secret获取 kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 -d && echo
,登陆即可在后台页面查看和操作ceph集群。
部署CephRBD
k8s的卷访问模式有四种,其中核心的是 RWO
和 RWX
两种,Ceph提供RBD块状存储,该存储在k8s主要用于访问模式是 ReadWriteOnce
应用,在rook的部署例子中提供了rbd的动态卷的例子。
创建k8s动态卷,卷名称默认为:rook-ceph-block
cd rook/deploy/examples
kubectl apply -f /csi/rbd/storageclass.yaml
#查看动态卷
kubectl get sc
#显示如下
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 14d
动态卷创建完毕以后,在ceph管理页面可以看到新增了一个名为 replicapool
的pool存储池,这个就是动态卷 rook-ceph-block
创建的pool池子。
如果需要修改或者新增动态卷,我们可以通过查看 /csi/rbd/storageclass.yaml
,可以看到meta.name的值就是动态卷的名称,parameters.pool的值就是ceph的pool池子的名称。
部署应用,这里采用例子中的mysql和wordpress部署,首先修改mysql.yaml和wordpress.yaml中的数据库密码,然后执行部署:
kubectl apply -f mysql.yaml
kubectl apply -f wordpress.yaml
#访问wordpress,查看service,wordpress暴露的端口是30255
[root@os-60 ceph]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 123d
wordpress LoadBalancer 10.103.149.80 <pending> 80:30255/TCP 14d
wordpress-mysql ClusterIP None <none> 3306/TCP 14d
访问10.0.0.60集群的30255端口:http://10.0.0.60:30255
,即可访问workpress应用:
如果要测试持久化存储能力,可以删除wordpress所有的pod,通过deployment拉起所有的pod,此时再次访问wordpress链接,仍然是之前的配置,表示持久化存储成功。
部署CephFS
Ceph提供FileSystem文件存储系统,该存储在k8s主要用于访问模式是 ReadWriteMany
应用,可以达到多个k8s应用共享同一块存储,例如日志收集,简单文件存储等。
rook提供cephFS的例子,存放目录在 rook/deploy/examples
。
kubectl apply -f csi/cephfs/storageclass.yaml
#配置cephFS文件系统
kubectl apply -f filesystem.yaml
查看cephFS动态卷,cephFS的动态卷名称为 rook-cephfs
[root@os-60 ceph]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-storage-class iass.default/nfs Delete Immediate false 116d
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 14d
rook-cephfs rook-ceph.cephfs.csi.ceph.com Delete Immediate true 27h
#文件系统已配置完成,请等待mds Pod 启动,查看ceph-mds的状态
kubectl -n rook-ceph get pod -l app=rook-ceph-mds
#显示结果:
NAME READY STATUS RESTARTS AGE
rook-ceph-mds-myfs-a-676ffd56c7-t8cfl 2/2 Running 0 27h
rook-ceph-mds-myfs-b-6d84b7db9f-q8h8k 2/2 Running 0 27h
进入ceph工具内部,rook-ceph-tools
,查看cephFs的状态:
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
#查看osd池子,确认myfs-metadata和myfs-replicated已经创建
bash-5.1$ ceph osd lspools
1 .mgr
2 replicapool
3 myfs-metadata
4 myfs-replicated
#查看fs状态:STATE为active
bash-5.1$ ceph fs status
myfs - 2 clients
====
RANK STATE MDS ACTIVITY DNS INOS DIRS CAPS
0 active myfs-a Reqs: 0 /s 40 29 23 6
0-s standby-replay myfs-b Evts: 0 /s 35 20 14 0
POOL TYPE USED AVAIL
myfs-metadata metadata 1500k 16.8G
myfs-replicated data 3072M 16.8G
MDS version: ceph version 18.2.4 (e7ad5345525c7aa95470c26863873b581076945d) reef (stable)
部署应用使用cephFS存储
首先创建pvc,pvc的配置如下,pvc的名称是 busybox-pvc
,注意这里的accessModes的值是 ReadWriteMany
。
cat < ceph-pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: busybox-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: rook-cephfs
EOF
创建2个busybox应用,挂载的pvc都是 busybox-pvc
。
cat < busybox.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox
spec:
replicas: 2
selector:
matchLabels:
app: busybox
template:
metadata:
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: busybox-pvc
EOF
cat < busybox-1.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: busybox-1
spec:
replicas: 2
selector:
matchLabels:
app: busybox-1
template:
metadata:
labels:
app: busybox-1
spec:
containers:
- name: busybox-1
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: busybox-pvc
EOF
创建两个busybox应用:
kubectl create -f busybox.yam -f busybox-1.yaml
#查看部署状态
[root@os-60 cephFS]# kubectl get pod -l app=busybox
NAME READY STATUS RESTARTS AGE
busybox-6f95b45db6-c2rrf 1/1 Running 23 (47m ago) 23h
busybox-6f95b45db6-qrjw8 1/1 Running 23 (47m ago) 23h
#进入其中一个bosybox
kubectl exec -it deploy/busybox -- sh
#写入数据
echo "hello" >> /data/hello.txt
#进入另一个bosybox
kubectl exec -it deploy/busybox-1 -- sh
cat /data/hello.txt
#结果显示:
hello
结束
Ceph作为分布式存储系统,具有高度稳定性、高性能和高可拓展性,目前是主流的生产级别的存储系统。在云原生时代对于外部存储的要求越来越高,高性能可拓展的存储系统成为了必需品,因此也增强了Ceph的使用。
由于Ceph涉及组件较多,部署运维成本高,Rook的加入则简化了部署运维流程,大大节省了Ceph的运维成本。本文仅研究了Block和FileSystem两种,
第三种是对象存储,用于s3/swift等对外提供存储能力。
参考文献:
Ceph官网
Rook官网
CRUSH - Controlled, Scalable, Decentralized Placement of Replicated Data.