官网:Quickstart - Rook Ceph Documentation
Rook 是 Kubernetes 的存储编排工具;rook-ceph = Rook + Ceph,就是在 K8s 集群里面,用 Rook 自动部署、管理 Ceph 分布式存储
Ceph :开源分布式存储,把多节点磁盘整合为一个大存储池,支持块存储、文件存储、对象存储
Rook :Ceph 原生很复杂,Rook 以 Operator 方式跑在 k8s 里,自动部署、监控、扩缩容、故障自愈 Ceph,不用手动敲大量 ceph 命令

部署ceph集群
集群的状态需要为一master两worker
在实验之前,在k8s三个节点上各添加一块50G磁盘
部署rook-ceph
添加 rook-ceph chart库


再将value.yml文件中的镜像拉取,打标签,上传至私有仓库

笔者这里编辑了一个脚本来自动拉取,打标签,上传

#!/bin/bash
set -e
# 定义镜像数组
images=(
"quay.io/cephcsi/cephcsi:v3.17.1"
"registry.k8s.io/sig-storage/csi-node-driver-registrar:v2.17.0"
"registry.k8s.io/sig-storage/csi-provisioner:v6.2.0"
"registry.k8s.io/sig-storage/csi-snapshotter:v8.5.0"
"registry.k8s.io/sig-storage/csi-attacher:v4.12.0"
"registry.k8s.io/sig-storage/csi-resizer:v2.1.0"
"quay.io/csiaddons/k8s-sidecar:v0.14.0"
)
# 目标仓库前缀
TARGET_PREFIX="reg.westos.org/ceph"
for img in "${images[@]}"; do
echo -e "\n========== Processing $img =========="
# 拉取原始镜像
echo "docker pull $img"
docker pull "$img"
# 提取镜像名:tag
img_name_tag=${img##*/}
new_img="${TARGET_PREFIX}/${img_name_tag}"
# 打新标签
echo "docker tag $img $new_img"
docker tag "$img" "$new_img"
# 推送到私有仓库
echo "docker push $new_img"
docker push "$new_img"
echo "==== Finished $img ===="
done
echo -e "\n✅ 全部镜像拉取、打标签、推送完成!"


还缺少了两个镜像,可以自行拉取

最后再替换掉value.yaml文件中的镜像路径


image:
repository: reg.westos.org/rook/ceph
tag: v1.20.7
csi:
cephcsi:
repository: reg.westos.org/ceph/cephcsi
tag: v3.17.1
registrar:
repository: reg.westos.org/ceph/csi-node-driver-registrar
tag: v2.17.0
provisioner:
repository: reg.westos.org/ceph/csi-provisioner
tag: v6.2.0
snapshotter:
repository: reg.westos.org/ceph/csi-snapshotter
tag: v8.5.0
attacher:
repository: reg.westos.org/ceph/csi-attacher
tag: v4.12.0
resizer:
repository: reg.westos.org/ceph/csi-resizer
tag: v2.1.0
csiAddons:
repository: reg.westos.org/ceph/k8s-sidecar
tag: v0.14.0
tolerations:
effect: NoSchedule
ceph-csi-operator:
controllerManager:
manager:
image:
repository: reg.westos.org/ceph/ceph-csi-operator
tag: v1.0.4
再将k8s1的admin.conf拷贝到该节点,写入kubeconfig
mkdir -p ~/.kube
cp /etc/kubernetes/admin.conf ~/.kube/config
chown $(id -u):$(id -g) ~/.kube/config

验证

部署ceph集群
下载rook-ceph的部署文件,注意匹配版本


修改文件


这里的磁盘必须要是新添加的未使用的盘


参考:
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: rook-ceph
namespace: rook-ceph # namespace:cluster
spec:
cephVersion:
image: reg.westos.org/rook/ceph:v20.2.4
allowUnsupported: false
security:
cephx:
csi:
keyType: aes # required when Kubernetes nodes don't run Linux kernel 7.0+
dataDirHostPath: /var/lib/rook
skipUpgradeChecks: false
continueUpgradeAfterChecksEvenIfNotHealthy: false
waitTimeoutForHealthyOSDInMinutes: 10
upgradeOSDRequiresHealthyPGs: false
mon:
count: 3
allowMultiplePerNode: false
mgr:
count: 2
allowMultiplePerNode: false
modules:
- name: rook
enabled: false
dashboard:
enabled: true
ssl: true
monitoring:
enabled: false
metricsDisabled: false
exporter:
perfCountersPrioLimit: 5
statsPeriodSeconds: 5
network:
connections:
encryption:
enabled: false
compression:
enabled: false
requireMsgr2: false
provider: host
crashCollector:
disable: false
logCollector:
enabled: true
periodicity: daily # one of: hourly, daily, weekly, monthly
maxLogSize: 500M # SUFFIX may be 'M' or 'G'. Must be at least 1M.
cleanupPolicy:
confirmation: ""
sanitizeDisks:
method: quick
dataSource: zero
iteration: 1
allowUninstallWithVolumes: false
placement:
all:
tolerations:
effect: NoSchedule
annotations:
labels:
resources:
removeOSDsIfOutAndSafeToRemove: false
priorityClassNames:
mon: system-node-critical
osd: system-node-critical
mgr: system-cluster-critical
storage: # cluster level storage configuration and selection
useAllNodes: false
useAllDevices: false
config:
allowDeviceClassUpdate: false # whether to allow changing the device class of an OSD after it is created
allowOsdCrushWeightUpdate: false # whether to allow resizing the OSD crush weight after osd pvc is increased
nodes:
- name: "k8s1"
devices:
-
name: "nvme0n2"
-
name: "k8s2"
devices:
-
name: "nvme0n2"
-
name: "k8s3"
devices:
- name: "nvme0n2"
scheduleAlways: false
onlyApplyOSDPlacement: false
disruptionManagement:
managePodBudgets: true
osdMaintenanceTimeout: 30
csi:
readAffinity:
enabled: false
cephfs:
healthCheck:
daemonHealth:
mon:
disabled: false
interval: 45s
osd:
disabled: false
interval: 60s
status:
disabled: false
interval: 60s
livenessProbe:
mon:
disabled: false
mgr:
disabled: false
osd:
disabled: false
startupProbe:
mon:
disabled: false
mgr:
disabled: false
osd:
disabled: false

最终出现三个osd-n的pod即为成功


部署storageclass


创建pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-ceph
spec:
storageClassName: rook-ceph-block
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

Rook 1.20+ 用 helm 部署时: rook-ceph chart 只部署 rook operator + ceph-csi-operator ,不再自动部署 RBD/cephfs CSI 驱动(provisioner、nodeplugin、CSIDriver) 。 必须额外独立安装 ceph-csi-drivers helm chart ,否则:
- kubectl get csidrivers 无资源
- PVC 一直 Pending,卡在等待外部 provisioner rook-ceph.rbd.csi.ceph.com
添加 ceph-csi-operator 仓库

更新

values.yaml 可以在rook目录中找到
rook/deploy/charts/ceph-csi-drivers/values.yaml
拉取所需chart

部署

查看csi驱动

查看pvc,已经变为bound

创建deployment webserver

apiVersion: "v1"
kind: "Service"
metadata:
name: "webserver"
labels:
app: "webserver-ceph"
spec:
type: "LoadBalancer"
ports:
- protocol: "TCP"
port: 80
selector:
app: "webserver-ceph"
apiVersion: "apps/v1"
kind: "Deployment"
metadata:
name: "webserver-ceph"
spec:
replicas: 1
selector:
matchLabels:
app: "webserver-ceph"
template:
metadata:
labels:
app: "webserver-ceph"
spec:
volumes:
- name: "webroot"
persistentVolumeClaim:
claimName: "pvc-ceph"
containers:
- name: "apache-frontend"
image: "reg.westos.org/library/httpd:dns"
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/var/www/html"
name: "webroot"

测试



需要metallb和ip-pool就绪

访问外部ip,返回成功

验证数据持久性
删除pod后访问外部ip依旧可以返回设定内容

验证rbd存储的单点挂载
设置5个副本

会将所有pod调度到k8s2,以保证单点挂载

副本数增加到10个,会发现k8s3上的pod会无法达到running状态

在pod所在的worker节点验证
RBD 块盘已经成功挂载在 k8s2 节点


获取CID

crictl inspect CID | grep -B1 -A2 pvc
获取HOSTPATH

ls HOSTPATH

df -Th HOSTPATH

Pod 内容器目录/var/www/html ⇀ containerd 绑定挂载 ⇀ 宿主机 kubelet 下的 CSI 挂载目录 ⇀ 底层 Ceph RBD 块设备/dev/rbd0
拉伸pvc容量
扩容pvc至2G


等待pvc扩容,并确认大小


改为RWOP模式
`ReadWriteOncePod`:可以被单个 `Pod `以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用 ReadWriteOncePod 访问模式。
ReadWriteOncePod 访问模式仅适用于 CSI 卷和 Kubernetes v1.22+。要使用此特性,你需要将以下 CSI 边车更新为下列或更高版本:
• csi-provisioner:v3.0.0+
• csi-attacher:v3.3.0+
• csi-resizer:v1.3.0+



apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOncePod
resources:
requests:
storage: 1Gi
storageClassName: rook-ceph-block

注意pvc的name,该文件可能需要修改


只允许一个pod挂载
