一、介绍

1.1、Ceph CSI 介绍

Ceph CSI 插件实现了支持 CSI 的容器编排器 (CO) 与 Ceph 集群之间的接口。它们支持动态配置 Ceph 卷并将其附加到工作负载。项目地址: https://github.com/ceph/ceph-csi 。该仓库包含用于 RBD、CephFS 和 Kubernetes sidecar 部署 YAML 的 Ceph 容器存储接口 (CSI) 驱动程序,以支持 CSI 功能:provisioner、attacher、resizer、driver-registrar 和 snapper。

本文基于 Ceph CSI v3.14.1 版本进行测试。

Ceph CSI 驱动与测试过的 Kubernetes 版本信息表: (参考 known-to-work-co-platforms)

Ceph CSI 版本 Kubernetes 版本
v3.14.1 v1.30、v1.31、v1.32
v3.14.0 v1.30、v1.31、v1.32
v3.13.1 v1.29、v1.30、v1.31
v3.13.0 v1.29、v1.30、v1.31

Ceph-CSI RBD 功能和可用版本信息表: (参考 ceph-csi-features-and-available-versions)

特性 状态 CSI 驱动版本 CSI 规范版本 Ceph 集群版本 Kubernetes 版本
动态/取消配置块模式 RWO 卷 正式版本 >= v1.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置块模式 RWX 卷 正式版本 >= v1.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置文件模式 RWO 卷 正式版本 >= v1.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
创建/删除快照 正式版本 >= v1.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.17.0
从快照配置卷 正式版本 >= v1.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.17.0
从另一个卷配置卷 正式版本 >= v1.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.16.0
文件模式卷的卷/PV 指标 正式版本 >= v1.2.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.15.0
区块模式卷的卷/PV 指标 正式版本 >= v1.2.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.21.0
扩大卷 Beta版本 >= v2.0.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.15.0
拓扑感知配置支持 Alpha版本 >= v2.1.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.14.0
从快照配置文件模式 ROX 卷 Alpha版本 >= v3.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.17.0
从另一个卷配置文件模式 ROX 卷 Alpha版本 >= v3.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.16.0
从快照配置块模式 ROX 卷 Alpha版本 >= v3.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.17.0
从另一个卷提供块模式 ROX 卷 Alpha版本 >= v3.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.16.0
动态/取消文件模式 RWOP 卷 Alpha版本 >= v3.5.0 >= v1.5.0 Pacific (>=v16.2.0) >= v1.22.0
动态/取消配置块模式 RWOP 卷 Alpha版本 >= v3.5.0 >= v1.5.0 Pacific (>=v16.2.0) >= v1.22.0

Ceph-CSI CephFS 功能和可用版本信息表: (参考 ceph-csi-features-and-available-versions)

特性 状态 CSI 驱动版本 CSI 规范版本 Ceph 集群版本 Kubernetes 版本
动态/取消配置文件模式 RWO 卷 正式版本 >= v1.1.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置文件模式 RWX 卷 正式版本 >= v1.1.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
创建和删除快照 正式版本 >= v3.1.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.17.0
从快照配置卷 正式版本 >= v3.1.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.17.0
从另一个卷配置卷 正式版本 >= v3.1.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.16.0
文件模式卷的卷/PV 指标 正式版本 >= v1.2.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.15.0
扩大卷 Beta版本 >= v2.0.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.15.0
动态/取消配置文件模式 ROX 卷 Alpha版本 >= v3.0.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置文件模式 RWOP 卷 Alpha版本 >= v3.5.0 >= v1.5.0 Pacific (>=v16.2.0) >= v1.22.0
创建和删除卷组快照 Alpha版本 >= v3.11.0 >= v1.9.0 Squid (>=v19.0.0) >= v1.31.0

Ceph-CSI NFS 功能和可用版本信息表: (参考 ceph-csi-features-and-available-versions)

特性 状态 CSI 驱动版本 CSI 规范版本 Ceph 集群版本 Kubernetes 版本
动态/取消配置文件模式 RWO 卷 Alpha版本 >= v3.6.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置文件模式 RWX 卷 Alpha版本 >= v3.6.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置文件模式 ROX 卷 Alpha版本 >= v3.6.0 >= v1.0.0 Pacific (>=v16.2.0) >= v1.14.0
动态/取消配置文件模式 RWOP 卷 Alpha版本 >= v3.6.0 >= v1.5.0 Pacific (>=v16.2.0) >= v1.22.0
扩大卷 Alpha版本 >= v3.7.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.15.0
创建和删除快照 Alpha版本 >= v3.7.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.17.0
从快照配置卷 Alpha版本 >= v3.7.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.17.0
从另一个卷配置卷 Alpha版本 >= v3.7.0 >= v1.1.0 Pacific (>=v16.2.0) >= v1.16.0

1.2、资源拓扑情况

本文中机器资源部署拓扑情况如下所示:

机器节点 机器IP地址 角色
node01 10.10.0.1 CephServer
node02 10.10.0.2 CephServer
node03 10.10.0.3 CephServer/minikube

字段解释:

  • CephServer: 其中部署了 Ceph Monitor/Manager/OSD等组件的节点,使用的 Ceph 版本为 v19.2.1
  • minikube: 搭建 K8S 测试集群的节点;

二、配置 Ceph 环境

我们可以使用 cephadm 来搭建部署一个新的集群,并在已部署的 Ceph 集群之上确保初始化如下配置环境,用于支持后续通过 Ceph CSI 组件来访问 Ceph 集群数据。

2.1、初始化数据访问环境

相关命令:

# 初始化 CephFS 环境
# 如果集群未创建 MDS 组件并启用 CephFS ,可使用下面的命令创建并启用
# 创建一个名为 cephfs 的文件系统,对应的两个存储池为 cephfs.cephfs.data 和 cephfs.cephfs.meta
ceph fs volume create cephfs
ceph fs status

# 初始化 CephRBD 环境
# 创建并初始化一个名为 cephrbd 的存储池
ceph osd pool create cephrbd
ceph osd pool application enable cephrbd rbd
rbd pool init cephrbd

# 创建一个 RBD Image ,用于支持 Ceph CSI 静态配置 RBD
rbd create -p cephrbd --image cephrbdimg01 --size 5G

2.2、新增访问密钥

按照 Ceph-CSI CephFS CapabilitiesCeph-CSI CephRBD Capabilities 中所描述的访问密钥的所需能力,我们执行如下操作创建对应密钥。

要求的权限能力:

# for CephFS
mgr "allow rw"
osd "allow rw tag cephfs metadata=<cephfs_name>, allow rw tag cephfs data=<cephfs_name>"
mds "allow r fsname=<cephfs_name> path=/volumes, allow rws fsname=<cephfs_name> path=/volumes/csi"
mon "allow r fsname=<cephfs_name>"

# for CephRBD
mgr "profile rbd pool=<rbd_pool_name>"
osd "profile rbd pool=<rbd_pool_name>"
mon "profile rbd"

相关命令:

# 新增 CephFS 访问用户
# 创建一个 csifsuser 的用户,赋予其访问名为 cephfs 文件系统的能力
ceph auth get-or-create client.csifsuser \
mgr "allow rw" \
osd "allow rw tag cephfs metadata=cephfs, allow rw tag cephfs data=cephfs" \
mds "allow r fsname=cephfs path=/volumes, allow rws fsname=cephfs path=/volumes/csi" \
mon "allow r fsname=cephfs"


# 新增 CephRBD 访问用户
# 创建一个 csirbduser 的用户,赋予其访问名为 cephrbd 存储池的能力
ceph auth get-or-create client.csirbduser \
mgr "profile rbd pool=cephrbd" \
osd "profile rbd pool=cephrbd" \
mon "profile rbd"

# 获取用户信息
ceph auth get client.csifsuser
ceph auth get client.csirbduser

2.3、挂载 Ceph 服务

相关命令: (位于 10.10.0.3 机器上执行)

# Kernel 方式挂载 CephFS
mkdir -p /mnt/cephfs
mount -t ceph 10.10.0.1:6789,10.10.0.2:6789,10.10.0.3:6789:/ /mnt/cephfs -o name=admin,secret=AQC3D25odVnvHRAAGDHbtmq7OaNiCa/oaZ4K3g==

三、搭建 K8S 集群

3.1、安装基础工具

为了进行测试,这里使用 minikube 工具搭建单节点的 K8S 测试集群。为此我们需要安装 kubectl 和 minikube 工具。

相关命令: (位于 10.10.0.3 机器上执行)

# 安装 kubectl
curl -LO "https://dl.k8s.io/release/v1.32.6/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl version --client

# 安装 minikube
curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64
minikube version

3.2、搭建集群

需要注意,由于我的测试机器上使用的是 podman ,所以在使用 minikube 部署集群的时候建议使用非 root 用户执行。

相关命令: (位于 10.10.0.3 机器上执行)

# 通过 minikube 搭建单节点集群
# 注意: 由于 minikube 是创建了虚拟机节点,因此为了能够成功启动对应的 Pod ,我们需要将对应路径 mount 到虚拟机节点内部
minikube start --mount=true \
--mount-string="/mnt/cephfs:/mnt/cephfs" \
--kubernetes-version="v1.32.6" \
--image-mirror-country="cn"

# 查看虚拟机内部挂载目录信息
minikube ssh "hostname; df -h"

# 启动 dashboard(单独 shell 窗口执行,该命令会前台运行)
minikube dashboard --url=true

# 启动 proxy 代理,用于浏览器窗口访问
kubectl proxy --port=8000 --address='10.10.0.3' --accept-hosts='^.*'

# 浏览器访问 dashboard
http://10.10.0.3:8000/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

相关输出信息:

[bugwz@node03 data]$ minikube start --mount=true --mount-string="/mnt/cephfs:/mnt/cephfs" --kubernetes-version="v1.32.6" --image-mirror-country="cn"
* minikube v1.36.0 on Centos 8.5.2111
==== AUTHENTICATING FOR org.libvirt.unix.manage ====
System policy prevents management of local virtualized systems
Multiple identities can be used for authentication:
1. admin
2. bugwz
Choose identity to authenticate as (1-2): 2
Password:
==== AUTHENTICATION COMPLETE ====
* Automatically selected the podman driver. Other choices: none, ssh
* Using image repository registry.cn-hangzhou.aliyuncs.com/google_containers
* Using Podman driver with root privileges
* Starting "minikube" primary control-plane node in "minikube" cluster
* Pulling base image v0.0.47 ...
E0709 20:10:41.669773 249209 cache.go:225] Error downloading kic artifacts: not yet implemented, see issue #8426
* Creating podman container (CPUs=2, Memory=3900MB) ...
* Preparing Kubernetes v1.32.6 on Docker 28.1.1 ...
- Generating certificates and keys ...
- Booting up control plane ...
- Configuring RBAC rules ...
* Configuring bridge CNI (Container Networking Interface) ...
* Verifying Kubernetes components...
- Using image registry.cn-hangzhou.aliyuncs.com/google_containers/storage-provisioner:v5
* Enabled addons: storage-provisioner, default-storageclass
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

四、部署 CSI 服务

以下使用的配置文件位于 ceph-csi v3.14.1 项目中。

4.1、部署 CephFS CSI 服务

相关命令: (以下操作参考 cephfs deploy)

# 创建 csi driver 对象
kubectl create -f ./deploy/cephfs/kubernetes/csidriver.yaml

# 为 sidecar 容器和节点插件部署 RBAC
# 这些清单部署了服务帐户、集群角色和集群角色绑定。
# rbd 和 cephfs csi 插件共享这些清单,因为它们需要相同的权限。
kubectl create -f ./deploy/cephfs/kubernetes/csi-provisioner-rbac.yaml
kubectl create -f ./deploy/cephfs/kubernetes/csi-nodeplugin-rbac.yaml

# 为 csi 插件部署 config map 【需修改该文件】
# config map 会部署一个空的 csi 配置,该配置会以卷的形式挂载到 Ceph CSI 插件 Pod 中
kubectl create -f ./deploy/cephfs/kubernetes/csi-config-map.yaml

# 为 csi pod 部署 ceph 配置 config map
kubectl create -f ./deploy/ceph-conf.yaml

# 部署 csi sidecar 容器
kubectl create -f ./deploy/cephfs/kubernetes/csi-cephfsplugin-provisioner.yaml

# 部署 csi cephfs 驱动程序
kubectl create -f ./deploy/cephfs/kubernetes/csi-cephfsplugin.yaml

# 解决配置依赖问题
# 问题详见 https://github.com/ceph/ceph-csi/issues/834
kubectl apply -f ./examples/kms/vault/kms-config.yaml


# 验证部署情况
# 由于镜像拉取速度受限于网络情况,所以各组件的初始化过程耗时可能较长
kubectl get all -n default

# 查看异常 pod 情况
kubectl describe pod csi-cephfsplugin-provisioner-7968db74cb-5d4kn -n default

注意: 由于 csi-cephfsplugin-provisioner.yaml 内部配置了 podAntiAffinity ,所以会导致 csi-cephfsplugin-provisioner pod 会分布在不同的 pod 中,但是由于测试环境中仅有一个 minikube 节点,所以会导致只有一个 csi-cephfsplugin-provisioner pod 处于运行状态。可以通过 kubectl describe pod <name> 指令来查看对应的 pod 详细信息,其中可以看到对应的 0/1 nodes are available: 1 node(s) didn't match pod anti-affinity rules. preemption: 0/1 nodes are available: 1 node(s) didn't match pod anti-affinity rules. 消息。

csi-config-map.yaml 文件内容示例: (参考示例文件 ./deploy/csi-config-map-sample.yaml)

---
apiVersion: v1
kind: ConfigMap
metadata:
name: "ceph-csi-config"
data:
config.json: |-
[
{
"clusterID": "13db9fce-5c90-11f0-8c5e-005056854af3",
"monitors": [
"10.10.0.1:6789",
"10.10.0.2.58:6789",
"10.10.0.3.59:6789"
]
}
]

文件解析:

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/cephfs/kubernetes/csidriver.yaml
csidriver.storage.k8s.io/cephfs.csi.ceph.com created

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/cephfs/kubernetes/csi-provisioner-rbac.yaml
serviceaccount/cephfs-csi-provisioner created
clusterrole.rbac.authorization.k8s.io/cephfs-external-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role created
role.rbac.authorization.k8s.io/cephfs-external-provisioner-cfg created
rolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-role-cfg created

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/cephfs/kubernetes/csi-nodeplugin-rbac.yaml
serviceaccount/cephfs-csi-nodeplugin created
clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/cephfs/kubernetes/csi-config-map.yaml
configmap/ceph-csi-config created

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/ceph-conf.yaml
configmap/ceph-config created

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/cephfs/kubernetes/csi-cephfsplugin-provisioner.yaml
service/csi-cephfsplugin-provisioner created
deployment.apps/csi-cephfsplugin-provisioner created

[bugwz@node03 ceph-csi]$ kubectl create -f ./deploy/cephfs/kubernetes/csi-cephfsplugin.yaml
daemonset.apps/csi-cephfsplugin created
service/csi-metrics-cephfsplugin created

[bugwz@node03 ceph-csi]$ kubectl create -f ./examples/kms/vault/kms-config.yaml
configmap/ceph-csi-encryption-kms-config created

[bugwz@node03 ceph-csi]$ kubectl get all -n default
NAME READY STATUS RESTARTS AGE
pod/csi-cephfsplugin-68knr 3/3 Running 0 44m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 44m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 44m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 44m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 44m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 44m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 53m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 44m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 44m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 44m

4.2、部署 CephRBD CSI 服务

相关命令: (以下操作参考 cephrbd deploy)

# 创建 csi driver 对象
kubectl create -f ./deploy/rbd/kubernetes/csidriver.yaml

# 为 sidecar 容器和节点插件部署 RBAC
# 这些清单部署了服务帐户、集群角色和集群角色绑定。
# rbd 和 cephfs csi 插件共享这些清单,因为它们需要相同的权限。
kubectl create -f ./deploy/rbd/kubernetes/csi-provisioner-rbac.yaml
kubectl create -f ./deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml

# 为 csi 插件部署 config map 【需修改该文件】
# config map 会部署一个空的 csi 配置,该配置会以卷的形式挂载到 Ceph CSI 插件 Pod 中
kubectl create -f ./deploy/rbd/kubernetes/csi-config-map.yaml

# 为 csi pod 部署 ceph 配置 config map
kubectl create -f ./deploy/ceph-conf.yaml

# 部署 csi sidecar 容器
kubectl create -f ./deploy/rbd/kubernetes/csi-rbdplugin-provisioner.yaml

# 部署 csi rbd 驱动程序
kubectl create -f ./deploy/rbd/kubernetes/csi-rbdplugin.yaml

# 解决配置依赖问题
# 问题详见 https://github.com/ceph/ceph-csi/issues/834
kubectl apply -f ./examples/kms/vault/kms-config.yaml


# 验证部署情况
# 由于镜像拉取速度受限于网络情况,所以各组件的初始化过程耗时可能较长
kubectl get all -n default

# 查看异常 pod 情况
kubectl describe pod csi-rbdplugin-8gpf7 -n default

csi-config-map.yaml 文件内容示例: (参考示例文件 ./deploy/csi-config-map-sample.yaml)

---
apiVersion: v1
kind: ConfigMap
metadata:
name: "ceph-csi-config"
data:
config.json: |-
[
{
"clusterID": "13db9fce-5c90-11f0-8c5e-005056854af3",
"monitors": [
"10.10.0.1:6789",
"10.10.0.2:6789",
"10.10.0.3:6789"
]
}
]

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl get all -n default
NAME READY STATUS RESTARTS AGE
pod/csi-rbdplugin-8gpf7 3/3 Running 0 33m
pod/csi-rbdplugin-provisioner-967b7f495-cfgft 0/7 Pending 0 33m
pod/csi-rbdplugin-provisioner-967b7f495-qmvrz 0/7 Pending 0 33m
pod/csi-rbdplugin-provisioner-967b7f495-z4rgc 7/7 Running 0 33m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-metrics-rbdplugin ClusterIP 10.101.143.224 <none> 8080/TCP 33m
service/csi-rbdplugin-provisioner ClusterIP 10.104.36.46 <none> 8080/TCP 33m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 37m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-rbdplugin 1 1 1 1 1 <none> 33m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-rbdplugin-provisioner 1/3 3 1 33m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-rbdplugin-provisioner-967b7f495 3 3 1 33m

五、CephFS 对接 CSI

注意: 动态配置卷会在收到请求时由驱动程序删除。对于静态配置卷(插件版本低于或等于 1.0.0),在执行删除操作时不会执行任何操作,预计会由用户在 Ceph 集群上删除。

5.1、创建Secret

无论是使用静态配置还是动态配置,都需要创建 Secret ,因此这里统一设置。

相关命令:

# 应用 secret.yaml
# 根据上面创建的 CephFS 的密钥修改对应的参数
kubectl apply -f ./examples/cephfs/secret.yaml

# 查看 secret
kubectl get secret -n default

secret.yaml 文件示例: (参考文件 ./examples/cephfs/secret.yaml)

---
apiVersion: v1
kind: Secret
metadata:
name: csi-cephfs-secret
namespace: default
stringData:
userID: csifsuser
userKey: AQBlF25o2MkeDBAAGccHVhMXE+ZKy/b7hLuZLw==
encryptionPassphrase: test_passphrase

配置解析:

  • userID : 创建的访问 CephFS 的用户名;
  • userKey : 创建的访问 CephFS 的用户密码;
  • encryptionPassphrase : 加密密码;

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl apply -f ./examples/cephfs/secret.yaml
secret/csi-cephfs-secret created

[bugwz@node03 ceph-csi]$ kubectl get secret -n default
NAME TYPE DATA AGE
csi-cephfs-secret Opaque 3 9m55s

5.2、静态配置

我们可以将手动创建的 CephFS 子卷或卷挂载到应用程序并卸载,以下步骤显示如何创建 CephFS 子卷或卷、静态 PV 和静态 PVC。参考文档

5.2.1、创建子卷

注意: 静态配置方式中,删除 PV 和 PVC 不会删除后端 CephFS 子卷或卷,如果需要,用户需要手动删除 CephFS 子卷或卷。

相关命令: (位于 10.10.0.1 节点上执行)

# 创建子卷组
# cephfs 文件系统名称,将在其中创建对应的子卷组
# cephfsgroup 创建的子卷组名称
ceph fs subvolumegroup create cephfs cephfsgroup

# 创建子卷
# k8ssubvolume 子卷名称,大小为 1GB
ceph fs subvolume create cephfs csisubvolume cephfsgroup --size=1073741824

# 获取子卷路径信息
ceph fs subvolume getpath cephfs csisubvolume cephfsgroup

# 查看文件系统中的子卷组信息
ceph fs subvolumegroup ls cephfs

# 查看文件系统中特定子卷组中的子卷信息
ceph fs subvolume ls cephfs cephfsgroup

相关操作记录:

[bugwz@node01 data]# ceph fs subvolumegroup create cephfs cephfsgroup

[bugwz@node01 data]# ceph fs subvolume create cephfs csisubvolume cephfsgroup --size=1073741824

[bugwz@node01 data]# ceph fs subvolume getpath cephfs csisubvolume cephfsgroup
/volumes/cephfsgroup/csisubvolume/7f646a62-f63d-42b7-8b15-7af9c8072788

[bugwz@node01 data]# ceph fs subvolumegroup ls cephfs
[
{
"name": "cephfsgroup"
}
]

[bugwz@node01 data]# ceph fs subvolume ls cephfs cephfsgroup
[
{
"name": "csisubvolume"
}
]

5.2.2、创建PV

相关命令: (位于 10.10.0.3 节点上执行)

# 创建 static-pv.yaml
vi ./examples/cephfs/static-pv.yaml

# 创建 pv
kubectl create -f ./examples/cephfs/static-pv.yaml

# 查看状态
kubectl get all,pv -n default

static-pv.yaml 示例文件: (参考资料 create-cephfs-static-pv)

apiVersion: v1
kind: PersistentVolume
metadata:
name: cephfs-static-pv
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 1Gi
csi:
driver: cephfs.csi.ceph.com
nodeStageSecretRef:
name: csi-cephfs-secret
namespace: default
volumeAttributes:
fsName: "cephfs"
clusterID: "13db9fce-5c90-11f0-8c5e-005056854af3"
staticVolume: "true"
rootPath: /volumes/cephfsgroup/csisubvolume
volumeHandle: cephfs-static-pv
persistentVolumeReclaimPolicy: Retain
volumeMode: Filesystem

配置解析:

  • nodeStageSecretRef :
    • name : 之前创建的密钥名。必需参数。
    • namespace : 之前创建的密钥所在的命名空间。必需参数。
  • volumeAttributes : 卷相关属性。
    • fsName : 待挂载的 CephFS 文件系统名称。不传递此选项将挂载默认文件系统。可选参数。
    • clusterID : Ceph 集群 ID 。必需参数。
    • staticVolume : 必须将值设置为 true 才能挂载和卸载静态 CephFS PVC 。必需参数。
    • rootPath : Ceph 集群中子卷的实际路径,或者卷的文件夹路径。必需参数。
  • volumeHandle : 可以是任何内容,不需要与 PV 名称或卷名称相同。为了简洁起见保持相同。
  • persistentVolumeReclaimPolicy : Ceph-CSI 不支持删除静态 PV 的 CephFS 子卷。所以该参数必须设置为 Retain ,以避免在 csi-provisioner 中尝试删除 PV 。

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl create -f ./examples/cephfs/static-pv.yaml
persistentvolume/cephfs-static-pv created

[bugwz@node03 ceph-csi]$ kubectl get all,pv -n default
NAME READY STATUS RESTARTS AGE
pod/csi-cephfsplugin-68knr 3/3 Running 0 63m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 63m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 63m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 63m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 63m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 63m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 72m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 63m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 63m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 63m

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/cephfs-static-pv 1Gi RWX Retain Available <unset> 3m39s

5.2.3、创建PVC

相关命令: (位于 10.10.0.3 节点上执行)

# 创建 static-pvc.yaml
vi ./examples/cephfs/static-pvc.yaml

# 创建 pvc
kubectl create -f ./examples/cephfs/static-pvc.yaml

# 查看状态
kubectl get all,pv,pvc -n default

static-pvc.yaml 示例文件: (参考资料 create-cephfs-static-pvc)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cephfs-static-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: ""
volumeMode: Filesystem
volumeName: cephfs-static-pv

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl create -f ./examples/cephfs/static-pvc.yaml
persistentvolumeclaim/cephfs-static-pvc created

[bugwz@node03 ceph-csi]$ kubectl get all,pv,pvc -n default
NAME READY STATUS RESTARTS AGE
pod/csi-cephfsplugin-68knr 3/3 Running 0 66m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 66m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 66m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 66m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 66m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 66m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 75m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 66m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 66m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 66m

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/cephfs-static-pv 1Gi RWX Retain Bound default/cephfs-static-pvc <unset> 6m53s

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/cephfs-static-pvc Bound cephfs-static-pv 1Gi RWX <unset> 26s

5.2.4、创建Pod

相关命令: (位于 10.10.0.3 节点上执行)

# 创建 static-pod.yaml
vi ./examples/cephfs/static-pod.yaml

# 创建 pod
kubectl create -f ./examples/cephfs/static-pod.yaml

# 查看状态
kubectl get all,pv,pvc,pod -n default

# 验证 pvc 是否已经成功挂载
kubectl exec cephfs-static-pod -- df -h /data/pvc

# 查看 ceph 对应的目录数据
tree /mnt/cephfs

static-pod.yaml 示例文件: (参考资料 verify-cephfs-static-pvc)

apiVersion: v1
kind: Pod
metadata:
name: cephfs-static-pod
namespace: default
spec:
containers:
- name: busybox
image: busybox:latest
volumeMounts:
- name: static-pvc
mountPath: /data/pvc
command: ["sleep", "3600"]
volumes:
- name: static-pvc
persistentVolumeClaim:
claimName: cephfs-static-pvc
readOnly: false

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl create -f ./examples/cephfs/static-pod.yaml
pod/cephfs-static-pod created


[bugwz@node03 ceph-csi]$ kubectl get all,pv,pvc -n default
NAME READY STATUS RESTARTS AGE
pod/cephfs-static-pod 1/1 Running 0 38s
pod/csi-cephfsplugin-68knr 3/3 Running 0 68m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 68m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 68m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 68m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 68m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 68m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 77m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 68m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 68m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 68m

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/cephfs-static-pv 1Gi RWX Retain Bound default/cephfs-static-pvc <unset> 9m3s

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/cephfs-static-pvc Bound cephfs-static-pv 1Gi RWX <unset> 2m36s


[bugwz@node03 ceph-csi]$ kubectl exec cephfs-static-pod -- df -h /data/pvc
Filesystem Size Used Available Use% Mounted on
10.10.0.1:6789,10.10.0.2:6789,10.10.0.3:6789:/volumes/cephfsgroup/csisubvolume
189.9G 0 189.9G 0% /data/pvc


[bugwz@node03 ceph-csi]$ tree /mnt/cephfs
/mnt/cephfs
└── volumes
├── cephfsgroup
│   └── csisubvolume
│   └── 7f646a62-f63d-42b7-8b15-7af9c8072788
└── _cephfsgroup:csisubvolume.meta

4 directories, 1 file

5.3、动态配置

5.3.1、创建子卷组

注意: 动态配置的时候,我们需要一个名为 csi 的子卷组,用于后续自动化的创建子卷。

相关命令: (位于 10.10.0.1 节点上执行)

# 创建子卷组
# cephfs 文件系统名称,将在其中创建对应的子卷组
# csi 创建的子卷组名称
ceph fs subvolumegroup create cephfs csi

# 查看文件系统中的子卷组信息
ceph fs subvolumegroup ls cephfs

# 查看文件系统中特定子卷组中的子卷信息
ceph fs subvolume ls cephfs csi

5.3.2、创建StorageClass

相关命令: (位于 10.10.0.3 节点上执行)

# 编辑 ./examples/cephfs/storageclass.yaml
vi ./examples/cephfs/storageclass.yaml

# 应用 ./examples/cephfs/storageclass.yaml
kubectl apply -f ./examples/cephfs/storageclass.yaml

# 查看状态
kubectl get all,storageclass -n default

storageclass.yaml 文件示例: (参考文件 ./examples/cephfs/storageclass.yaml)

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID: 13db9fce-5c90-11f0-8c5e-005056854af3
fsName: cephfs
# pool: <cephfs-data-pool>
# fuseMountOptions: debug
# kernelMountOptions: readdir_max_bytes=1048576,norbytes
csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: default
csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
csi.storage.k8s.io/node-stage-secret-namespace: default
# mounter: kernel
# volumeNamePrefix: "foo-bar-"
# backingSnapshot: "true"
# encrypted: "false"
# encryptionKMSID: <kms-config-id>
reclaimPolicy: Delete
allowVolumeExpansion: true
# mountOptions:
# - context="system_u:object_r:container_file_t:s0:c0,c1"

配置解析:

  • clusterID : Ceph 集群 ID 。确保与 csi-config-map.yaml 中的集群 ID 保持一致。必需参数。
  • fsName : CephFS 文件系统名称,将会在其中创建卷。必需参数。
  • pool : Ceph 池名称,将会在其中存储卷数据。可选参数。
  • fuseMountOptions : Ceph-Fuse 挂载选项字符串,使用逗号分隔。可选参数。
  • kernelMountOptions : Cephfs 内核挂载选项字符串,使用逗号分隔。可选参数。
  • mounter : 挂载方式,可选值为 kernel/fuse 。默认将自动检测使用命令确定。可选参数。
  • volumeNamePrefix : 子卷命名前缀。默认为 csi-vol- 。可选参数。
  • backingSnapshot : 启用时 PVC 将由其数据源中指定的 CephFS 快照支持,这时不应配置 pool 参数。默认为 true 。可选参数。
  • encrypted : 是否加密卷。默认为 false 。可选参数。
  • encryptionKMSID : 通过指定与 KMS ConfigMap 匹配的唯一 ID 来使用外部密钥管理系统进行加密密码。可选参数。

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl apply -f ./examples/cephfs/storageclass.yaml
storageclass.storage.k8s.io/csi-cephfs-sc created


[bugwz@node03 ceph-csi]$ kubectl get all,storageclass -n default
NAME READY STATUS RESTARTS AGE
pod/cephfs-static-pod 1/1 Running 0 7m59s
pod/csi-cephfsplugin-68knr 3/3 Running 0 76m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 76m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 76m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 76m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 76m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 76m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 85m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 76m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 76m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 76m

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storageclass.storage.k8s.io/csi-cephfs-sc cephfs.csi.ceph.com Delete Immediate true 24s
storageclass.storage.k8s.io/standard (default) k8s.io/minikube-hostpath Delete Immediate false 85m

5.3.3、创建PVC

相关命令: (位于 10.10.0.3 节点上执行)

# 修改 ./examples/cephfs/pvc.yaml
vi ./examples/cephfs/pvc.yaml

# 应用 ./examples/cephfs/pvc.yaml
kubectl apply -f ./examples/cephfs/pvc.yaml

# 查看状态
kubectl get all,storageclass,pvc -n default

pvc.yaml 文件示例: (参考文件 ./examples/cephfs/pvc.yaml)

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: csi-cephfs-sc

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl apply -f ./examples/cephfs/pvc.yaml
persistentvolumeclaim/csi-cephfs-pvc created


[bugwz@node03 ceph-csi]$ kubectl get all,storageclass,pvc -n default
NAME READY STATUS RESTARTS AGE
pod/cephfs-static-pod 1/1 Running 1 (25m ago) 85m
pod/csi-cephfsplugin-68knr 3/3 Running 0 153m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 153m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 153m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 153m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 153m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 153m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 162m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 153m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 153m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 153m

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storageclass.storage.k8s.io/csi-cephfs-sc cephfs.csi.ceph.com Delete Immediate true 77m
storageclass.storage.k8s.io/standard (default) k8s.io/minikube-hostpath Delete Immediate false 162m

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/cephfs-static-pvc Bound cephfs-static-pv 1Gi RWX <unset> 87m
persistentvolumeclaim/csi-cephfs-pvc Bound pvc-99d82063-6768-421b-90cb-e0227de6a9b6 1Gi RWX csi-cephfs-sc <unset> 74m

5.3.4、创建Pod

相关命令: (位于 10.10.0.3 节点上执行)

# 修改 ./examples/cephfs/pod.yaml
vi ./examples/cephfs/pod.yaml

# 应用 ./examples/cephfs/pod.yaml
kubectl apply -f ./examples/cephfs/pod.yaml

# 查看状态
kubectl get all,storageclass,pvc,pod -n default

# 验证 pvc 是否已经成功挂载
kubectl exec csi-cephfs-pod -- df -h /var/lib/www

# 查看 ceph 对应的目录数据
tree /mnt/cephfs/volumes/csi

pod.yaml 文件示例: (参考文件 ./examples/cephfs/pod.yaml)

---
apiVersion: v1
kind: Pod
metadata:
name: csi-cephfs-pod
spec:
containers:
- name: web-server
image: docker.io/library/nginx:latest
volumeMounts:
- name: mypvc
mountPath: /var/lib/www
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: csi-cephfs-pvc
readOnly: false

相关操作记录:

[bugwz@node03 ceph-csi]$ kubectl apply -f ./examples/cephfs/pod.yaml
pod/csi-cephfs-pod created


[bugwz@node03 ceph-csi]$ kubectl get all,storageclass,pvc,pod -n default
NAME READY STATUS RESTARTS AGE
pod/cephfs-static-pod 1/1 Running 1 (26m ago) 86m
pod/csi-cephfs-pod 1/1 Running 0 74m
pod/csi-cephfsplugin-68knr 3/3 Running 0 154m
pod/csi-cephfsplugin-provisioner-7968db74cb-2xn6p 5/5 Running 0 154m
pod/csi-cephfsplugin-provisioner-7968db74cb-5d4kn 0/5 Pending 0 154m
pod/csi-cephfsplugin-provisioner-7968db74cb-5dhlm 0/5 Pending 0 154m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/csi-cephfsplugin-provisioner ClusterIP 10.101.130.172 <none> 8080/TCP 154m
service/csi-metrics-cephfsplugin ClusterIP 10.106.150.166 <none> 8080/TCP 154m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 163m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/csi-cephfsplugin 1 1 1 1 1 <none> 154m

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/csi-cephfsplugin-provisioner 1/3 3 1 154m

NAME DESIRED CURRENT READY AGE
replicaset.apps/csi-cephfsplugin-provisioner-7968db74cb 3 3 1 154m

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storageclass.storage.k8s.io/csi-cephfs-sc cephfs.csi.ceph.com Delete Immediate true 78m
storageclass.storage.k8s.io/standard (default) k8s.io/minikube-hostpath Delete Immediate false 163m

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/cephfs-static-pvc Bound cephfs-static-pv 1Gi RWX <unset> 88m
persistentvolumeclaim/csi-cephfs-pvc Bound pvc-99d82063-6768-421b-90cb-e0227de6a9b6 1Gi RWX csi-cephfs-sc <unset> 76m


[bugwz@node03 ceph-csi]$ kubectl exec csi-cephfs-pod -- df -h /var/lib/www
Filesystem Size Used Avail Use% Mounted on
10.10.0.1:6789,10.10.0.2:6789,10.10.0.3:6789:/volumes/csi/csi-vol-0ebde315-c3d8-4410-a5b8-f75fe3d9951c/5bce7da0-3010-478c-9dc6-1321c1ed9b58 1.0G 0 1.0G 0% /var/lib/www


[bugwz@node03 ceph-csi]$ tree /mnt/cephfs/volumes/csi
/mnt/cephfs/volumes/csi
└── csi-vol-0ebde315-c3d8-4410-a5b8-f75fe3d9951c
└── 5bce7da0-3010-478c-9dc6-1321c1ed9b58

2 directories, 0 files

六、CephRBD 对接 CSI

6.1、创建Secret

无论是使用静态配置还是动态配置,都需要创建 Secret ,因此这里统一设置。

相关命令:

# 应用 secret.yaml
# 根据上面创建的 CephFS 的密钥修改对应的参数
kubectl apply -f secret.yaml

secret.yaml 文件示例: (参考文件 ./examples/rbd/secret.yaml)

---
apiVersion: v1
kind: Secret
metadata:
name: csi-rbd-secret
namespace: default
stringData:
userID: csirbduser
userKey: AQDS0mxoG9goNhAAWs514SqUnxY9yKxo95S0aQ==
encryptionPassphrase: test_passphrase

配置解析:

  • userID : 创建的访问 CephFS 的用户名;
  • userKey : 创建的访问 CephFS 的用户密码;
  • encryptionPassphrase : 加密密码;

6.2、静态配置

手动创建的 RBD 映像可以挂载到应用程序或从应用程序中卸载,以下步骤展示了如何创建 RBD 映像、静态 PV、静态 PVC 。

注意: 删除 PV 和 PVC 不会删除后端 RBD 映像,如果需要,用户需要手动删除 RBD 映像。

6.2.1、创建PV

相关命令:

# 创建 pv
kubectl create -f static-pv.yaml

static-pv.yaml 示例文件: (参考资料: create-rbd-static-pv)

apiVersion: v1
kind: PersistentVolume
metadata:
name: rbd-static-pv
spec:
accessModes:
- ReadWriteOnce
capacity:
storage: 1Gi
csi:
driver: rbd.csi.ceph.com
fsType: ext4
nodeStageSecretRef:
name: csi-rbd-secret
namespace: default
volumeAttributes:
clusterID: "60526708-4d10-4dba-b294-6681615f9edc"
pool: "cephrbd"
staticVolume: "true"
imageFeatures: "layering"
# mounter: rbd-nbd
volumeHandle: cephrbdimg01
persistentVolumeReclaimPolicy: Retain
volumeMode: Filesystem

参数解析:

  • fsType :
  • nodeStageSecretRef :
    • name :
    • namespace :
  • volumeAttributes :
    • clusterID : Ceph 集群 ID 。必需参数。
    • pool : 创建 RBD 映像的池名称。必需参数。
    • staticVolume : 必须将值设置为 true 才能挂载和卸载静态 RBD PVC 。必需参数。
    • imageFeatures : CSI RBD 目前支持 layering,journaling,exclusive-lock 功能。如果启用了 journaling ,则还必须启用 exclusive-lock 。必需参数。
    • mounter : 如果设置为 rbd-nbd ,则在具有 rbd-nbd 和 nbd 内核模块的节点上使用 rbd-nbd 来映射 RBD 映像。可选参数。
  • volumeHandle : 对应之前创建的 RBD Image ,这里为 cephrbdimg01 。
  • persistentVolumeReclaimPolicy : Ceph-CSI 不支持删除静态 PV 的 RBD 映像。该参数必须设置为 Retain ,以避免在 csi-provisioner 中尝试删除 PV 。

6.2.2、创建PVC

相关命令:

# 创建 pvc
kubectl create -f static-pvc.yaml

static-pvc.yaml 示例文件: (参考资料: create-rbd-static-pvc)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-static-pvc
namespace: default
spec:
storageClassName: ""
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
volumeMode: Filesystem
volumeName: rbd-static-pv

6.2.3、创建Pod

相关命令:

# 创建 pod
kubectl create -f static-pod.yaml

# 验证 pvc 是否已经在 pod 中挂载
kubectl exec rbd-static-pod -- df -h /data/pvc

static-pod.yaml 示例文件: (参考资料: verify-rbd-static-pvc)

apiVersion: v1
kind: Pod
metadata:
name: rbd-static-pod
namespace: default
spec:
containers:
- name: busybox
image: busybox:latest
volumeMounts:
- name: static-pvc
mountPath: /data/pvc
command: ["sleep", "3600"]
volumes:
- name: static-pvc
persistentVolumeClaim:
claimName: rbd-static-pvc

6.3、动态配置

6.3.1、创建StorageClass

相关命令:

# 更改并应用 storageclass.yaml
kubectl apply -f storageclass.yaml

# 查看状态
kubectl get storageclass

storageclass.yaml 文件示例: (参考文件 ./examples/rbd/storageclass.yaml)

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
# volumeBindingMode: WaitForFirstConsumer
parameters:
clusterID: 60526708-4d10-4dba-b294-6681615f9edc
# dataPool: <ec-data-pool>
pool: cephrbd
imageFeatures: "layering"
# mkfsOptions: "-m0 -Ediscard -i1024"
# tryOtherMounters: false
# mapOptions: "krbd:lock_on_read,queue_depth=1024;nbd:try-netlink"
# unmapOptions: "krbd:force;nbd:force"
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: default
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: default
csi.storage.k8s.io/fstype: ext4
# mounter: rbd-nbd
# cephLogDir: /var/log/ceph
# cephLogStrategy: remove
# volumeNamePrefix: "foo-bar-"
# encrypted: "false"
# encryptionType: "block"
# encryptionKMSID: <kms-config-id>
# topologyConstrainedPools: |
# [
# {
# "poolName":"pool0",
# "dataPool":"ec-pool0" # 可选,用于数据的纠删码池
# "domainSegments": [
# {"domainLabel":"region","value":"east"},
# {"domainLabel":"zone","value":"zone1"}
# ]
# },
# {
# "poolName":"pool1",
# "dataPool":"ec-pool1" # 可选,用于数据的纠删码池
# "domainSegments":[
# {"domainLabel":"region","value":"east"},
# {"domainLabel":"zone","value":"zone2"}
# ]
# },
# {
# "poolName":"pool2",
# "dataPool":"ec-pool2" # 可选,用于数据的纠删码池
# "domainSegments":[
# {"domainLabel":"region","value":"west"},
# {"domainLabel":"zone","value":"zone1"}
# ]
# }
# ]
# stripeUnit: <>
# stripeCount: <>
# objectSize: <>
# BaseReadIops: <>
# BaseWriteIops: <>
# BaseReadBytesPerSecond: <>
# BaseWriteBytesPerSecond: <>
# ReadIopsPerGiB: <>
# WriteIopsPerGiB: <>
# ReadBpsPerGiB: <>
# WriteBpsPerGiB: <>
# BaseVolSizeBytes:<>
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard

配置解析:

  • clusterID : Ceph 集群 ID 。确保与 csi-config-map.yaml 中的集群 ID 保持一致。必需参数。
  • dataPool : 如果要使用带有 RBD 的纠删码池,则需要创建两个池。一个是纠删码池,一个是复制池。该参数用于设置对应的纠删码池。可选参数。
  • pool : Ceph 池名称,将会在其中存储卷数据。如果指定了 dataPool 的值,则该值用于设置对应额复制池,用于存储Image元数据。必需参数。
  • imageFeatures : RBD 图像功能,可选值为 layering,journaling,exclusive-lock,object-map,fast-diff,deep-flatten 。可选参数。
  • mkfsOptions : 在 RBD 设备上创建文件系统时传递给 mkfs 命令的选项。当指定值后将取代默认值。默认选项取决于 csi.storage.k8s.io/fstype 类型。可选参数。
    • ext4 时,默认值为 -m0 -Enodiscard,lazy_itable_init=1,lazy_journal_init=1
    • xfs 时,默认值为 -K
  • tryOtherMounters : 指定是否在当前挂载器无法挂载 rbd 图像时尝试其他挂载器。默认为 false 。可选参数。
  • mapOptions : 以逗号分隔的映射选项列表。默认为空。可选参数。
  • unmapOptions : 以逗号分隔的取消映射选项列表。默认为空。可选参数。
  • csi.storage.k8s.io/fstype : 指定卷的文件系统类型。如果未指定。可选参数。
  • mounter : 设置挂载器。可选参数。
  • cephLogDir : Ceph 客户端日志位置。可选参数。
  • cephLogStrategy : Ceph 客户端日志策略。默认为 remove 。可选参数。
    • remove : 取消映射时删除日志;
    • compress : 取消映射时仅压缩而不删除;
    • preserve : 取消映射时保留日志文件的文本格式;
  • volumeNamePrefix : RBD 映像的前缀。默认为 csi-vol- 。可选参数。
  • encrypted : 是否加密卷。默认为 false 。可选参数。
  • encryptionType : 当启用加密卷时对应的加密类型。默认为 block 。可选参数。
    • file : 在挂载的文件系统上启用文件加密;
    • block : 加密 RBD 块设备;
  • encryptionKMSID : 指定与 KMS ConfigMap 匹配的唯一 ID 使用外部密钥管理系统进行加密密码。可选参数。
  • topologyConstrainedPools : 拓扑约束池配置,如果设置了基于拓扑的池,并且需要拓扑约束供应。可选参数。
  • stripeUnit : 图像条带化,条带单位(以字节为单位)。可选参数。
  • stripeCount : 图像条带化,在循环之前要条带化的对象。可选参数。
  • objectSize : 图像条带化,对象大小(以字节为单位)。可选参数。
  • BaseReadIops : RBD 卷 QoS ,每秒读取操作的基本限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • BaseWriteIops : RBD 卷 QoS ,每秒写入操作的基本限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • BaseReadBytesPerSecond : RBD 卷 QoS ,每秒读取字节的基本限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • BaseWriteBytesPerSecond : RBD 卷 QoS ,每秒写入字节的基本限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • ReadIopsPerGiB : RBD 卷 QoS ,每 GiB 的读取操作限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • WriteIopsPerGiB : RBD 卷 QoS ,每 GiB 的写入操作限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • ReadBpsPerGiB : RBD 卷 QoS ,每 GiB 的读取字节限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • WriteBpsPerGiB : RBD 卷 QoS ,每 GiB 的写入字节限制。仅支持 rbd-nbd 挂载类型。可选参数。
  • BaseVolSizeBytes : RBD 卷 QoS ,用于根据容量计算 qos 的卷的最小大小。仅支持 rbd-nbd 挂载类型。可选参数。

6.3.2、创建PVC

相关命令:

# 应用 pvc.yaml
kubectl apply -f pvc.yaml

# 查看状态
kubectl get storageclass,pvc

pvc.yaml 文件示例: (参考文件 ./examples/rbd/pvc.yaml)

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
labels:
group: test
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc

6.3.3、创建Pod

相关命令:

# 应用 pod.yaml
kubectl apply -f pod.yaml

# 查看状态
kubectl get storageclass,pvc,pod

pod.yaml 文件示例: (参考文件 ./examples/rbd/pod.yaml)

---
apiVersion: v1
kind: Pod
metadata:
name: csi-rbd-pod
spec:
containers:
- name: web-server
image: docker.io/library/nginx:latest
volumeMounts:
- name: mypvc
mountPath: /var/lib/www/html
volumes:
- name: mypvc
persistentVolumeClaim:
claimName: rbd-pvc
readOnly: false

七、参考资料