第33讲:K8S集群StorageClass使用Ceph CSI供应商与Cephfs文件系统集成

Jiangxl~ 2024-07-12 11:07:04 阅读 94

文章目录

1.Ceph CSI供应商简介2.创建Cephfs文件系统为StorageCLass提供底层存储端2.1.创建Cephfs文件系统2.2.在Cephfs文件系统中为Storageclass创建子目录2.3.在Cephfs文件系统中创建一个子卷

3.在K8S集群中部署Cephfs-CSI供应商客户端3.1.下载Cephfs-CSI客户端的资源编排文件3.2.配置CSI连接Ceph集群的ConfigMap资源3.3.将Ceph的配置文件保存在Configmap中3.4.调整资源编排文件的命名空间以及镜像地址3.5.部署CSI客户端

4.基于Cephfs文件系统创建Storageclass资源并进行使用4.1.将K8S访问Cephfs文件系统的用户信息存储在Secret资源中4.2.创建一个StorageClass资源控制器4.3.创建PVC存储卷从StorageClass中自动分配PV4.4.创建Pod资源挂载PVC存储卷4.5.进入Pod资源进行数据持久化操作4.6.查看由StorageClass分配的PV与Cephfs文件存储中子目录的对应关系4.7.观察Cephfs文件系统中是否有Pod产生的数据

5.Statefulset控制器结合Storageclass为每个Pod分配独立存储5.1.编写Statefulset控制器资源编排文件5.2.创建资源控制器并观察PV和PVC的状态5.3.查看PV对应在Cephfs文件系统中的目录结构

1.Ceph CSI供应商简介

K8S StorageClass对接Ceph集群的Cephfs文件系统有两种方法,一种是cephfs-provisioner另一种是cephfs-csi。

Cephfs-csi是第三方的客户端程序,部署简单,只需要拉取下来镜像就可以部署成功,而cephfs-provisioner则有很多的故障,相对于对接RBD的存储时,rbd-provisioner非常简单,rbd-csi则有很多故障。

Cephfs-csi官方文档:https://github.com/ceph/ceph-csi/blob/devel/docs/deploy-cephfs.md

2.创建Cephfs文件系统为StorageCLass提供底层存储端

2.1.创建Cephfs文件系统

Cephfs类型的CSI提供了指定使用哪一个Cephfs文件系统的参数,我们可以在Ceph集群中再创建一个Cephfs文件系统,专门为Storageclass使用。

<code>1.创建Cephfs使用的资源池

[root@ceph-node-1 ~]# ceph osd pool create kubernetes_cephfs_data 16 16

pool 'kubernetes_cephfs_data' created

[root@ceph-node-1 ~]# ceph osd pool create kubernetes_cephfs_metadata 16 16

pool 'kubernetes_cephfs_metadata' created

2.创建cephfs文件系统

[root@ceph-node-1 ~]# ceph fs new kubernetes_cephfs kubernetes_cephfs_metadata kubernetes_cephfs_data

new fs with metadata pool 24 and data pool 23

2.2.在Cephfs文件系统中为Storageclass创建子目录

这一步无需做,在2.3中说明。

我们可以将这一个Cephfs文件系统仅针对K8S集群进行使用,所有的K8S持久化数据都存在这个Cephfs文件系统中,在这个文件系统里可以针对不同的应用程序,创建出不同的子目录,然后将子目录挂载到具体的应用程序上。ll

[root@ceph-node-1 ~]# mkdir /kubernetes_cephfs/k8s_data/storageclass_storage

cephfs文件系统就相当于系统中的一块磁盘,按照目录结构创建即可。

2.3.在Cephfs文件系统中创建一个子卷

StorageClass使用Cephfs-CSI客户端将数据持久化到Cephfs文件系统时,无法指定Cephfs文件系统中现有的子目录进行挂载,只能将数据写在文件系统的/目录中,这是Cephfs-CSI程序内部写死的,无法进行配置,除非修改源代码。

如下图所示,StorageClass分配PV时,会通过Cephfs-CSI在Cephfs文件系统中/目录中创建一个volumes的子目录,在volumes中再创建一个子目录叫做csi,在csi目录中存放的都是PV持久化的数据,每个PV都会对应生成一个目录。

image-20220419171140172

volumes目录是无法修改的,只能修改volumes目录中的子目录csi,Cephfs-CSI会在Ceph集群指定的Cephfs文件系统中创建一个子卷,这个目录就对应的就是子卷的名称。

下面我们来创建一个子卷。

命令格式:<code>ceph fs subvolumegroup create {cephfs文件系统名称} {子卷名称}

1.创建子卷

[root@ceph-node-1 ~]# ceph fs subvolumegroup create kubernetes_cephfs k8s-storageclass-volumes

2.查看文件系统下所有的子卷

[root@ceph-node-1 ~]# ceph fs subvolumegroup ls kubernetes_cephfs

[

{

"name": "k8s-storageclass-volumes"

}

]

3.删除子卷的命令:

[root@ceph-node-1 ~]# ceph fs subvolumegroup create kubernetes_cephfs k8s-storageclass-volumes

3.在K8S集群中部署Cephfs-CSI供应商客户端

3.1.下载Cephfs-CSI客户端的资源编排文件

[root@k8s-master cephfs-csi]# git clone https://github.com/ceph/ceph-csi.git -b release-v3.4

[root@k8s-master cephfs-csi]# cd ceph-csi/deploy/cephfs/kubernetes

3.2.配置CSI连接Ceph集群的ConfigMap资源

[root@k8s-master kubernetes]# vim csi-config-map.yaml

apiVersion: v1

kind: ConfigMap

data:

config.json: |-

[

{

"clusterID": "a5ec192a-8d13-4624-b253-5b350a616041",

"monitors": [

"192.168.20.20:6789",

"192.168.20.21:6789",

"192.168.20.22:6789"

],

"cephFS": {

"subvolumeGroup": "k8s-storageclass-volumes"

}

}

]

metadata:

name: ceph-csi-config

clusterID:集群的ID号

monitors:Monitor组件的地址

subvolumeGroup:Cephfs文件系统中的子卷名称,StorageClass分配的PV,产生的持久化数据都会存储在这里。

3.3.将Ceph的配置文件保存在Configmap中

需要将Ceph的基础配置文件写入到Configmap资源中,CSI客户端的两个容器都需要挂载。

[root@k8s-master kubernetes]# vim ceph-config.yaml

apiVersion: v1

kind: ConfigMap

data:

ceph.conf: |

[global]

auth_cluster_required = cephx

auth_service_required = cephx

auth_client_required = cephx

# keyring is a required key and its value should be empty

keyring: |

metadata:

name: ceph-config

3.4.调整资源编排文件的命名空间以及镜像地址

CSI的镜像在国外,拉取会超时,需要替换成DockerHub上的地址。

[root@k8s-master kubernetes]# NAMESPACE=cephfs-storage

[root@k8s-master kubernetes]# sed -ri "s/namespace: [^ ]+/namespace: $NAMESPACE/g" *.yaml

[root@k8s-master kubernetes]# sed -ri 's/k8s.gcr.io\/sig-storage/jiangxlrepo/' *.yaml

[root@k8s-master kubernetes]# sed -ri 's/quay.io\/cephcsi/jiangxlrepo/' *.yaml

3.5.部署CSI客户端

1)在K8S集群中部署CSI客户端

1.创建CSI客户端所在的Namespace

[root@k8s-master kubernetes]# kubectl create ns cephfs-storage

namespace/cephfs-storage created

2.部署所有的CSI资源控制器

[root@k8s-master kubernetes]# kubectl apply -f ./ -n cephfs-storage

configmap/ceph-config created

service/csi-cephfsplugin-provisioner created

deployment.apps/csi-cephfsplugin-provisioner created

daemonset.apps/csi-cephfsplugin created

service/csi-metrics-cephfsplugin created

configmap/ceph-csi-config created

podsecuritypolicy.policy/cephfs-csi-nodeplugin-psp created

role.rbac.authorization.k8s.io/cephfs-csi-nodeplugin-psp created

rolebinding.rbac.authorization.k8s.io/cephfs-csi-nodeplugin-psp created

serviceaccount/cephfs-csi-nodeplugin created

clusterrole.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created

clusterrolebinding.rbac.authorization.k8s.io/cephfs-csi-nodeplugin created

podsecuritypolicy.policy/cephfs-csi-provisioner-psp created

role.rbac.authorization.k8s.io/cephfs-csi-provisioner-psp created

rolebinding.rbac.authorization.k8s.io/cephfs-csi-provisioner-psp created

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

csidriver.storage.k8s.io/cephfs.csi.ceph.com created

2)查看部署的CSI客户端Pod资源

[root@k8s-master kubernetes]# kubectl get pod -n cephfs-storage

NAME READY STATUS RESTARTS AGE

csi-cephfsplugin-bfdvj 3/3 Running 0 39s

csi-cephfsplugin-ngv84 3/3 Running 0 39s

csi-cephfsplugin-provisioner-7bffb54f69-d26ms 6/6 Running 0 38s

csi-cephfsplugin-provisioner-7bffb54f69-q2wsn 6/6 Running 0 38s

csi-cephfsplugin-provisioner-7bffb54f69-q6hw9 6/6 Running 0 38s

csi-cephfsplugin-qlj4k 3/3 Running 0 39s

全部处于Running状态,下面可以来创建StorageClass存储类,将数据持久化到Cephfs文件系统了。

4.基于Cephfs文件系统创建Storageclass资源并进行使用

Cephfs的CSI客户端驱动已经在集群中部署完成了,下面可以创建一个StorageClass资源通过CSI驱动连接Ceph集群的块存储设备。

创建完StorageClass后,可以创建一个PVC存储卷,观察PV是否会自动创建,最后在Pod中使用PVC。

使用CSI之前,先在每一个K8S节点中安装Ceph的相关命令。

yum -y install ceph-common

4.1.将K8S访问Cephfs文件系统的用户信息存储在Secret资源中

将用户信息的Secret资源固定存放在一个Namespace下,然后在StorageClass中引用即可。

1)编写资源编排文件

[root@k8s-master cephfs-csi]# vim cephfs-sc-secret.yaml

apiVersion: v1

kind: Secret

metadata:

name: cephfs-sc-secret

namespace: kube-system

stringData:

userID: admin

userKey: AQBIWUhiEmaFOBAA6Jr6itUeHiLVVOeYFVpRog==

adminID: admin

adminKey: AQBIWUhiEmaFOBAA6Jr6itUeHiLVVOeYFVpRog==

2)创建Secret资源

[root@k8s-master cephfs-csi]# kubectl apply -f cephfs-sc-secret.yaml

secret/csi-cephfs-secret created

4.2.创建一个StorageClass资源控制器

1)编写资源编排文件

[root@k8s-master cephfs-csi]# vim cephfs-storageclass.yaml

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

name: cephfs-storageclass

provisioner: cephfs.csi.ceph.com#cephfs csi客户端的驱动名称

parameters:

clusterID: a5ec192a-8d13-4624-b253-5b350a616041#集群的ID

fsName: kubernetes_cephfs#使用Ceph集群的哪一个Cephfs文件系统

pool: kubernetes_cephfs_data#Cephfs文件系统的数据资源池名称

#rootPath: /k8s_data/storageclass_storage #无需指定Cephfs文件系统中的子目录,CSi会自动在/下的volumes目录中存储,无法修改

csi.storage.k8s.io/provisioner-secret-name: cephfs-sc-secret

csi.storage.k8s.io/provisioner-secret-namespace: kube-system

csi.storage.k8s.io/controller-expand-secret-name: cephfs-sc-secret

csi.storage.k8s.io/controller-expand-secret-namespace: kube-system

csi.storage.k8s.io/node-stage-secret-name: cephfs-sc-secret

csi.storage.k8s.io/node-stage-secret-namespace: kube-system

reclaimPolicy: Delete

allowVolumeExpansion: true

2)创建StorageClass并查看资源的状态

[root@k8s-master cephfs-csi]# kubectl apply -f cephfs-sc-secret.yaml

secret/cephfs-sc-secret created

[root@k8s-master cephfs-csi]# kubectl get sc

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE

cephfs-storageclass cephfs.csi.ceph.com Delete Immediate true 3s

4.3.创建PVC存储卷从StorageClass中自动分配PV

1)编写PVC的资源编排文件

[root@k8s-master cephfs-csi]# vim cephfs-sc-pvc.yaml

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: cephfs-sc-pvc

spec:

accessModes:

- ReadWriteMany

resources:

requests:

storage: 1Gi

storageClassName: cephfs-storageclass

2)创建资源并查看资源的状态

[root@k8s-master cephfs-csi]# kubectl apply -f cephfs-sc-pvc.yaml

persistentvolumeclaim/cephfs-sc-pvc created

[root@k8s-master cephfs-csi]# kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

cephfs-sc-pvc Bound pvc-9fcb0460-6547-4e9f-8efe-6e2266bc4aab 1Gi RWX cephfs-storageclass 68s

可以看到PVC已经与pvc-f5ce8114-088e-41fa-91da-63d759f1dd9c这个PV进行了绑定,这个PV就是由Storageclass自动创建的。

[root@k8s-master cephfs-csi]# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

pvc-9fcb0460-6547-4e9f-8efe-6e2266bc4aab 1Gi RWX Delete Bound default/cephfs-sc-pvc cephfs-storageclass 69s

4.4.创建Pod资源挂载PVC存储卷

PVC已经准备就绪了,下面创建一个Pod资源,将PVC挂载到Pod资源中,持久化Pod资源的数据。

1)编写资源编排文件

[root@k8s-master cephfs-csi]# vim cephfs-sc-pvc-pod.yaml

apiVersion: v1

kind: Pod

metadata:

name: cephfs-sc-pvc-pod

spec:

containers:

- image: nginx:1.15

name: nginx

ports:

- name: web

containerPort: 80

protocol: TCP

volumeMounts:

- name: data

mountPath: /var/www/html

volumes:

- name: data

persistentVolumeClaim:

claimName: cephfs-sc-pvc

2)创建资源并观察资源的状态

[root@k8s-master cephfs-csi]# kubectl apply -f cephfs-sc-pvc-pod.yaml

pod/cephfs-sc-pvc-pod created

[root@k8s-master cephfs-csi]# kubectl get pod

NAME READY STATUS RESTARTS AGE

cephfs-sc-pvc-pod 1/1 Running 0 42s

4.5.进入Pod资源进行数据持久化操作

进入的Pod容器的PVC挂载路径,写入一些数据文件。

[root@k8s-master cephfs-csi]# kubectl exec -it cephfs-sc-pvc-pod bash

root@cephfs-sc-pvc-pod:/# cd /var/www/html/

root@cephfs-sc-pvc-pod:/var/www/html# touch web{1..5}.index

root@cephfs-sc-pvc-pod:/var/www/html# mkdir code login admin

root@cephfs-sc-pvc-pod:/var/www/html# ls

admin code login web1.indexweb2.index web3.indexweb4.index web5.index

4.6.查看由StorageClass分配的PV与Cephfs文件存储中子目录的对应关系

由StorageClass动态创建的PV,生成的名称都是随机的,没有什么含义,盲目的在Cephfs文件系统中找不一定能找的对。

可以通过kubectl describe pv {pv_name}目录看到PV持久化的数据存储在Cephfs文件系统的哪个路径中,

image-20220419215743773

主要看这一行:

<code>subvolumePath=/volumes/k8s-storageclass-volumes/csi-vol-2f7d25c6-bfe8-11ec-8b4e-d65c041d72e2/50b7e45b-a48d-4d0f-be36-86812c8367e8

/volumes目录:是CSI客户端从代码部分就指定好的,无法变更。

/volumes/k8s-storageclass-volumes目录:k8s-storageclass-volumes目录对应的就是在Cephfs文件系统中创建的子卷名称

/volumes/k8s-storageclass-volumes/csi-vol-2f7d25c6-bfe8-11ec-8b4e-d65c041d72e2目录:第三级si-vol-2f7d25c6-bfe8-11ec-8b4e-d65c041d72e2目录是由CSI创建的子卷,PV会保存在这一级目录中,也是一个目录。

/volumes/k8s-storageclass-volumes/csi-vol-2f7d25c6-bfe8-11ec-8b4e-d65c041d72e2/50b7e45b-a48d-4d0f-be36-86812c8367e8:第四级50b7e45b-a48d-4d0f-be36-86812c8367e8目录就是PV的目录,也是Pod数据持久化落盘的位置。

每当StorageClass分配一个PV,都会在文件系统中/volumes/目录下生产一个元数据文件,并且在创建的子卷目录下为每一个PV创建一个csi的子卷,最后在创建一个目录来存放PV的数据。

我们可以再创建一个PVC,由Storageclass为其分配PV,查看目录结构,如下图所示。

image-20220419220743029

千万不要删除volumes这个目录,一旦这个目录删除,使用Cephfs的StorageCLass再次分配PV时就会产生问题,此时只需要将CSI客户端重新部署即可解决问题。

4.7.观察Cephfs文件系统中是否有Pod产生的数据

Pod产生的数据都会存储在/volumes/{子卷}/{CSI子卷}/{PV目录}这个路径下。

<code>[root@ceph-node-1 ~]# tree /kubernetes_cephfs/

/kubernetes_cephfs/

└── volumes

├── _deleting

├── k8s-storageclass-volumes

│ └── csi-vol-2f7d25c6-bfe8-11ec-8b4e-d65c041d72e2

│ └── 50b7e45b-a48d-4d0f-be36-86812c8367e8

│ ├── admin

│ ├── login

│ ├── web

│ ├── web1.txt

│ ├── web2.txt

│ ├── web3.txt

│ ├── web4.txt

│ └── web5.txt

└── _k8s-storageclass-volumes:csi-vol-2f7d25c6-bfe8-11ec-8b4e-d65c041d72e2.meta

8 directories, 6 files

5.Statefulset控制器结合Storageclass为每个Pod分配独立存储

现在StorageClass已经对接好了Ceph集群的Cephfs文件系统,下面在Statefulset控制器使用StorageClass为每个Pod分配独立的存储源。

每个Pod都会通过StorageClass创建出一个PVC和PV,每个PVC都会对应一个PV,每个PV都会在文件系统中创建一组目录。

5.1.编写Statefulset控制器资源编排文件

[root@k8s-master cephfs-csi]# vim cephfs-statefulset.yaml

apiVersion: apps/v1

kind: StatefulSet

metadata:

name: nginx

spec:

selector:

matchLabels:

app: nginx

serviceName: "nginx"

replicas: 3

template:

metadata:

labels:

app: nginx

spec:

containers:

- name: nginx

image: nginx:1.15

volumeMounts:

- name: web-data

mountPath: /var/www/html

volumeClaimTemplates:

- metadata:

name: web-data

spec:

storageClassName: "cephfs-storageclass"

accessModes:

- ReadWriteMany

resources:

requests:

storage: 1Gi

5.2.创建资源控制器并观察PV和PVC的状态

1.创建statefulset控制器

[root@k8s-master cephfs-csi]# kubectl apply -f cephfs-statefulset.yaml

statefulset.apps/nginx created

2.查看创建的资源

[root@k8s-master cephfs-csi]# kubectl get pod

NAME READY STATUS RESTARTS AGE

cephfs-sc-pvc-pod 1/1 Running 0 80m

nginx-0 1/1 Running 0 8m35s

nginx-1 1/1 Running 0 8m24s

nginx-2 1/1 Running 0 8m15s

3.查看PV和PVC

[root@k8s-master cephfs-csi]# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

pvc-0350926b-1933-411b-8eb4-ba583e272c08 1Gi RWX Delete Bound default/web-data-nginx-1 cephfs-storageclass 9m4s

pvc-49747cef-46b0-4f83-976d-039020b679c4 1Gi RWX Delete Bound default/web-data-nginx-0 cephfs-storageclass 9m15s

pvc-93fcf7bf-b593-4b7c-8a04-717d49685c93 1Gi RWX Delete Bound default/web-data-nginx-2 cephfs-storageclass 8m55s

pvc-9fcb0460-6547-4e9f-8efe-6e2266bc4aab 1Gi RWX Delete Bound default/cephfs-sc-pvc cephfs-storageclass 81m

[root@k8s-master cephfs-csi]# kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

cephfs-sc-pvc Bound pvc-9fcb0460-6547-4e9f-8efe-6e2266bc4aab 1Gi RWX cephfs-storageclass 81m

web-data-nginx-0 Bound pvc-49747cef-46b0-4f83-976d-039020b679c4 1Gi RWX cephfs-storageclass 9m36s

web-data-nginx-1 Bound pvc-0350926b-1933-411b-8eb4-ba583e272c08 1Gi RWX cephfs-storageclass 9m25s

web-data-nginx-2 Bound pvc-93fcf7bf-b593-4b7c-8a04-717d49685c93 1Gi RWX cephfs-storageclass 9m16s

5.3.查看PV对应在Cephfs文件系统中的目录结构

每一个PV都对应一个子目录和数据文件。

image-20220419232042628



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。