环境

说明

k8s版本

kubernetes-docker:v1.24.0

rook版本

1.8.0

Ceph版本

16.2.7 (dd0603118f56ab514f133c8d2e3adfc983942503) pacific (stable)

ceph节点

maser,node-1,node-2,node-3

硬盘

vda (系统盘:50G)sda(数据盘:100G)

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 提供共享存储。

组件

概念

Monitor

一个Ceph集群需要多个Monitor组成的小集群,它们通过Paxos同步数据,用来保存OSD的元数据

OSD

OSD负责相应客户端请求返回具体数据的进程,一个Ceph集群一般都有很多个OSD

MSD

msd全称Cepg Metadata Service,是CephFs服务依赖的元数据服务

Object

Ceph最底层的存储单位是Object对象,每个Object包含元数据和原始数据

PG

PG全称Placement Groups,是一个逻辑的概念,一个PG包含多个OSD。引入PG这一层其实是为了更好的分配数据和定位数据

RADOS

是Ceph集群的精华,为用户实现数据分配,Failover等集群操作

Libradio

Libradio是Rados提供库,因为RADOS是协议很难直接访问,因此上层的RBD、RGW和CephFs都是通过librados访问的目前提供PHP、Ruby、Java、Python等支持

CRUSH

CRUSH是Ceph使用的数据分布算法,类似一致性哈希,让数据分配到预期的地方。

RBD

RBD全称RADOS block device,是Ceph对外提供的块设备服务

RGW

RGW全称RADOS gateway,是Ceph对外提供的对象存储服务,接口与S3和Swift兼容

CephFs

CephFs全称Ceph File System,是Ceph对外提供的文件系统服务

Pool

pool 是Ceph存储时的逻辑分区,它起到namespace的作用

3、Rook特点

  • 简单可靠的自动化资源管理

  • 超大规模或超融合您的存储集群

  • 有效地分发和复制数据以最大程度地减少损失

  • 使用多个存储提供程序进行配置、文件、块和对象

  • 管理开源存储技术

  • 在您的数据中心轻松启用弹性存储

  • 在 Apache 2.0 许可下发布的开源软件

  • 优化商品硬件上的工作负载

3、在 Kubernetes 上部署 Rook

官方文档: https://rook.io/docs/rook/v1.8/quickstart.html

环境要求

  1. 您已经安装了 Kubernetes 集群,且集群版本不低于 v1.17.0。

  2. 发布的架构是amd64 / x86_64和arm64。

  3. 为了配置 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工作节点添加新磁盘

  1. Kubernetes 集群有至少 3 个工作节点,且每个工作节点都有一块初系统盘以外的 未格式化 的裸盘(工作节点是虚拟机时,未格式化的裸盘可以是虚拟磁盘),用于创建 3 个 Ceph OSD;

  2. 工作节点,挂载了一块 未格式化 的裸盘;

  3. 在节点机器上执行 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 AccountClusterRoleClusterRoleBindings,以便以最低权限运行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