1、Rook介绍
Rook是一个开源的云原生存储协调器,提供平台、框架和对各种存储解决方案的支持,以与云原生环境进行本地集成。
Rook将存储软件转变为自我管理,自我扩展和自我修复的存储服务。它通过自动化部署、引导、配置、供应、扩展、升级、迁移、灾难恢复、监视和资源管理来实现。Rook使用底层云原生容器管理,调度和编排平台提供的功能来执行其职责。
Rook利用扩展点将其深度集成到云原生环境中,并为调度、生命周期管理、资源管理、安全性、监视和用户体验提供无缝的体验。
优点是部署Ceph集群方便。
缺点是如果Ceph集群出现故障,很难排查错误。
我个人还是倾向于使用独立的Ceph集群为k8s提供存储服务。
官网: https://rook.io
官方文档: https://rook.io/docs/rook/v1.8/ceph-storage.html
项目地址: https://github.com/rook
2、存储架构
Ceph 是一个高度可扩展的分布式存储解决方案,用于块存储、对象存储和共享文件系统
Rook 使Ceph 存储能够原生的Kubernetes 上运行。通过在 Kubernetes 集群中运行 Ceph,Kubernetes 应用程序可以挂载 Rook 管理的块设备和文件系统,或者可以使用 S3/Swift API 进行对象存储。Rook operator 自动配置存储组件并监控集群以确保存储保持可用和健康。
Rook operator 是一个简单的容器,它拥有引导和监控存储集群所需的一切。Rook operator将启动和监控Ceph 监控 pod、提供 RADOS 存储的 Ceph OSD 守护进程,以及启动和管理其他 Ceph 守护进程。操作员通过初始化运行服务所需的 Pod 和其他资源来管理池、对象存储 (S3/Swift) 和文件系统的 CRD。
Rook operator将监控存储守护进程以确保集群健康。Ceph mons 将在必要时启动或故障转移,并随着集群的增长或缩小进行其他调整。操作员还将观察 Ceph 自定义资源 (CRs) 中指定的所需状态更改并应用更改。
Rook 会自动配置 Ceph-CSI 驱动程序以将存储挂载到您的 pod。
Rook 包含多个组件:
Rook Operator:Rook 的核心组件,Rook Operator 是一个简单的容器,自动启动存储集群,并监控存储守护进程,来确保存储集群的健康。
Rook Agent:在每个存储节点上运行,并配置一个 FlexVolume 插件,和 Kubernetes 的存储卷控制框架进行集成。Agent 处理所有的存储操作,例如挂接网络存储设备、在主机上加载存储卷以及格式化文件系统等。
Rook Discovers:检测挂接到存储节点上的存储设备。
Rook 还会用 Kubernetes Pod 的形式,部署 Ceph 的 MON、OSD 以及 MGR 守护进程。
Rook Operator 让用户可以通过 CRD 的是用来创建和管理存储集群。每种资源都定义了自己的 CRD.
Rook Clusteropen in new window:提供了对存储机群的配置能力,用来提供块存储、对象存储以及共享文件系统。每个集群都有多个 Pool。
Poolopen in new window:为块存储提供支持。Pool 也是给文件和对象存储提供内部支持。
Object Storeopen in new window:用 S3 兼容接口开放存储服务。
File Systemopen in new window:为多个 Kubernetes Pod 提供共享存储。
3、Rook特点
简单可靠的自动化资源管理
超大规模或超融合您的存储集群
有效地分发和复制数据以最大程度地减少损失
使用多个存储提供程序进行配置、文件、块和对象
管理开源存储技术
在您的数据中心轻松启用弹性存储
在 Apache 2.0 许可下发布的开源软件
优化商品硬件上的工作负载
3、在 Kubernetes 上部署 Rook
官方文档: https://rook.io/docs/rook/v1.8/quickstart.html
环境要求
您已经安装了 Kubernetes 集群,且集群版本不低于 v1.17.0。
发布的架构是amd64 / x86_64和arm64。
为了配置 Ceph 存储集群,至少需要以下本地存储选项之一:
原始设备(无分区或格式化文件系统)
原始分区(无格式化文件系统)
block模式下存储类中可用的 PV
部署准备
1、部署Rook Ceph前提条件
至少准备3个节点、并且全部可以调度pod,满足ceph副本高可用要求
节点存在可用的裸盘或裸分区,无格式化文件系统
如果需要LVM,节点必须安装lvm2软件包 Ceph需要使用RBD模块构建的Linux内核,可以通过运行modprobe
如果要从Ceph共享文件系统(CephFS)创建卷,建议的最低内核版本为4.17,低于 4.17,则不会强制执行请求的 PVC 大小
2、确保所有节点安装LVM2
export NODE_IPS=(172.31.73.14 172.31.73.50 172.31.73.84 172.31.73.89)
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "yum install -y lvm2"
done
3、为K8s工作节点添加新磁盘
Kubernetes 集群有至少 3 个工作节点,且每个工作节点都有一块初系统盘以外的 未格式化 的裸盘(工作节点是虚拟机时,未格式化的裸盘可以是虚拟磁盘),用于创建 3 个 Ceph OSD;
工作节点,挂载了一块 未格式化 的裸盘;
在节点机器上执行
lsblk -f
指令可以查看磁盘是否需被格式化,输出结果如下:NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS loop0 squashfs 4.0 0 100% /snap/core20/1695 loop1 squashfs 4.0 0 100% /snap/lxd/23541 loop2 squashfs 4.0 0 100% /snap/snapd/17576 sda vda ├─vda1 ext4 1.0 cloudimg-rootfs 4471db5e-2d08-46e9-a9b1-0e99c7d5a8f9 42.6G 12% /var/lib/containers/storage/overlay │ / ├─vda14 └─vda15 vfat FAT32 UEFI 8388-755F 99.1M 5% /boot/efi vdb iso9660 Joliet Extension cidata 2023-03-19-14-06-58-00
如果
FSTYPE
字段不为空,则表示该磁盘上已经被格式化。在上面的例子中,可以将磁盘sda
用于 Ceph 的 OSD,而磁盘vda
及其分区则不能用做 Ceph 的 OSD。4.去除污点命令:
kubectl describe node |grep Taint kubectl taint node master node-role.kubernetes.io/master- kubectl taint node master node-role.kubernetes.io/control-plane:NoSchedule-
安装
服务部署
Rook项目地址:https://github.com/rook/rook
git clone --single-branch --branch v1.10
https://github.com/rook/rook.git
wget https://github.com/rook/rook/archive/refs/tags/v1.11.0.tar.gz
tar zxf v1.11.0.tar.gz
cd rook-1.11.0/deploy/examples/
#提前在科学上学的机器上,准备离线镜像
cat images.txt
docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o ceph.tar
配置无密码 SSH 登录
ssh-keygen
for i in ksv-{0..4}; do echo ">>> $i";ssh-copy-id $i;done
for i in master node-{0..2}; do echo ">>> $i";ssh-copy-id $i;done
for i in ksv-{1..2}; do echo ">>> $i";scp /root/ceph-v15.tar $i;done
for i in master node-{0..2}; do echo ">>> $i";scp /root/tag.sh $i:/root;done
修改配置文件
修改Rook CSI驱动注册路径
注意:rook csi驱动挂载的路径是挂载到kubelet所配置的–root-dir参数指定的目录下的;所以需要根据自己实际的–root-dir参数修改下图中rook csi的kubelet路径地址;如果与实际kubelet的–root-dir路径不一致,则会导致后面进行挂载存储时提示 driver name rook-ceph.cephfs.csi.ceph.com not found in the list of registered CSI driver
#备份
cp operator.yaml{,.bak}
vim operator.yaml
ROOK_CSI_KUBELET_DIR_PATH
#修改前
ROOK_CSI_KUBELET_DIR_PATH: "/var/lib/kubelet"
#修改后
ROOK_CSI_KUBELET_DIR_PATH: "/data/k8s/kubelet"
开启准入控制器
准入控制器在对象持久化之前拦截到Kubernetes API服务器的请求,但在对请求进行身份验证和授权之后。
建议启用Rook准入控制器,以提供额外级别的验证,以确保Rook是使用自定义资源(CR)设置正确配置的。
可利用助手脚本自动配置部署Rook准入控制器,这个脚本将帮助我们完成以下任务:
创建自签名证书
为证书创建证书签名请求(
CSR
),并从Kubernetes集群获得批准将这些证书存储为
Kubernetes Secret
创建
Service Account
、ClusterRole
和ClusterRoleBindings
,以便以最低权限运行webhook服务创建
ValidatingWebhookConfig
并使用来自集群的适当值填充CA bundle
kubectl create -f crds.yaml kubectl create -f common.yaml
部署Rook Operator
创建配置持久化目录
export NODE_IPS=(172.31.73.172 172.31.73.233 172.31.73.217 172.31.73.245)
for node_ip in ${NODE_IPS[@]}
do
echo ">>> ${node_ip}"
ssh root@${node_ip} "mkdir -p /data/rook && ls -d /data/rook*"
done
执行创建Operator组件
kubectl create -f operator.yaml
#查看创建的operator pod
kubectl get po -n rook-ceph -o wide
创建 Ceph 集群
给工作节点打上标签
kubectl get nodes
kubectl label no node-0 role=storage-node
kubectl label no node-1 role=storage-node
kubectl label no node-2 role=storage-node
kubectl get no --show-labels | grep role=storage-node
修改Cluster配置文件
文件中有几个地方要注意:
dataDirHostPath: 这个路径是会在宿主机上生成的,保存的是ceph的相关的配置文件,再重新生成集群的时候要确保这个目录为空,否则mon会无法启动,宿主机的/var/lib/rook文件夹。
useAllDevices: 使用所有的设备,建议为false,否则会把宿主机所有可用的磁盘都干掉。
useAllNodes:使用所有的node节点,建议为false,肯定不会用k8s集群内的所有node来搭建ceph。
cp cluster.yaml{,_bak}
vim cluster.yaml
#rook在每个节点启动的agent收集的数据持久化目录
dataDirHostPath: /data/rook
#mon相关的配置,默认3个节点,生产建议多配置几个,主要
mon:
count: 5
#mgr的配置
mgr:
count: 2
#ceph管理面板
dashboard:
enabled: true
ssl: true
#开启节点亲和和pod亲和,用来确保pod可以均衡的分配到每个节点
placement:
all:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: role
operator: In
values:
- storage-node
podAffinity:
podAntiAffinity:
topologySpreadConstraints:
tolerations:
- key: storage-node
operator: Exists
#所有的节点是否为存储节点,生产一定改为false
#使用所有的磁盘,改为false
storage: # cluster level storage configuration and selection
useAllNodes: false
useAllDevices: false
nodes:
- name: "node-0"
devices: # specific devices to use for storage can be specified for each node
- name: "sda"
- name: "sdb"
- name: "node-1"
devices: # specific devices to use for storage can be specified for each node
- name: "sda"
- name: "sdb"
- name: "sdc"
- name: "node-2"
devices: # specific devices to use for storage can be specified for each node
- name: "^sd."
部署并检查创建情况
#创建部署资源
kubectl apply -f cluster.yaml
#查看创建的pods
kubectl get po -n rook-ceph -o wide
#查看集群状态;需要等待各个组件配置初始化完成
kubectl get CephCluster -n rook-ceph
Rook Ceph 工具
kubectl create -f toolbox.yaml
kubectl -n rook-ceph rollout status deploy/rook-ceph-tools
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
部署Ceph Dashboard
kubectl apply -f dashboard-external-https.yaml
查看pod、svc
kubectl get pod -o wide -n rook-ceph
kubectl get svc -n rook-ceph
ceph-tool工具查看集群状态
kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') bash
ceph -s
#查看osd的状态
ceph osd status
ceph df
#查看ceph osd中所有节点的状态
ceph osd tree
#查看osd的使用信息
ceph osd df
#查看mon的信息
ceph mon dump
#查看mon状态
ceph mon stat
ceph pg stat
rados df
ceph osd pool ls
ceph auth ls
#查看pg的详细信息
ceph pg dump
#查看mon节点的时间同步情况
ceph time-sync-status
注:可能出现HEALTH_WARN #警告信息可以暂且忽略,后面可以去掉,这个信息提示允许一个不安全的端口对mons进行一个操作,或者执行以下命令
官方解决方案:https://docs.ceph.com/en/latest/rados/operations/health-checks/
ceph config set mon auth_allow_insecure_global_id_reclaim false1se
查看集群的状态,需要满足下面的条件才认为是健康的:
所有 mons 应该达到法定数量
mgr 应该是激活状态
至少有一个 OSD 处于激活状态
如果不是 HEALTH_OK 状态,则应该查看告警或者错误信息
获取登陆密码
#查看端口
kubectl get svc -n rook-ceph
https://nodeip:nodeport
#获取登陆密码,默认admin用户
kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath="{['data']['password']}" | base64 --decode && echo
设置默认storageclass
kubectl patch storageclass rook-ceph-block -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
kubectl patch storageclass local -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
kubectl edit sc -n ceph local
storageclass.beta.kubernetes.io/is-default-class: "false"
kubectl patch storageclass rook-ceph-block -p '{"metadata": {"annotations":{"storageclass.beta.kubernetes.io/is-default-class":"false"}}}'
测试
RBD测试
kubectl apply -f csi/rbd/storageclass.yaml # 创建一个名为replicapool的rbd pool
kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
rook-ceph-block rook-ceph.rbd.csi.ceph.com Delete Immediate true 80m
kubectl apply -f csi/rbd/storageclass.yaml
kubectl apply -f csi/rbd/pvc.yaml
kubectl apply -f csi/rbd/pod.yaml
kubectl apply -f mysql.yaml
kubectl apply -f wordpress.yaml
kubectl get pv,pvc -n default
kubectl get pod,svc -n default
#删除测试
kubectl delete -f csi/rbd/pod.yaml
kubectl delete -f csi/rbd/pvc.yaml
kubectl delete -f csi/rbd/storageclass.yaml
kubectl delete -f wordpress.yaml
kubectl delete -f mysql.yaml
kubectl delete -n rook-ceph cephblockpools.ceph.rook.io replicapool
kubectl delete storageclass rook-ceph-block
CephFS测试
CephFS 允许用户挂载一个兼容posix的共享目录到多个主机,该存储和NFS共享存储以及CIFS共享目录相似
# 创建 共享文件系统
kubectl apply -f filesystem.yaml
# 提供存储
kubectl apply -f csi/cephfs/storageclass.yaml
kubectl apply -f csi/cephfs/pvc.yaml
kubectl apply -f csi/cephfs/pod.yaml
总结
通过rook复用k8s节点部署的ceph集群虽然部署方便,但是由于rook部署ceph时全程自动化且服务全部为pod导致后期维护ceph集群比较困难,我个人
并不建议在生产环境中使用rook部署ceph集群,生产中应独立部署ceph集群比较方便维护。还有一点是,当你重启k8s节点后,该节点上osd对应的磁盘
ceph集群会识别不到,这可能是一个bug吧,社区应该后期还会再改进。
参考链接:
服务镜像
quay.io/ceph/ceph:v16.2.7
k8s.gcr.io/sig-storage/csi-resizer:v1.3.0
k8s.gcr.io/sig-storage/csi-snapshotter:v4.2.0
k8s.gcr.io/sig-storage/csi-provisioner:v3.0.0
k8s.gcr.io/sig-storage/csi-node-driver-registrar:v2.3.0
k8s.gcr.io/sig-storage/csi-attacher:v3.3.0
quay.io/cephcsi/cephcsi:v3.4.0
rook/ceph:v1.8.0
docker pull csiplugin/csi-neonsan:v1.2.2
docker pull csiplugin/csi-provisioner:v2.2.2
docker pull csiplugin/csi-attacher:v3.2.1
docker pull csiplugin/csi-resizer:v1.2.0
docker pull csiplugin/csi-snapshotter:v4.0.0
docker pull csiplugin/csi-node-driver-registrar:v2.2.0