第30讲:Ceph集群RBD块存储通过CSI客户端与K8S StorageClass集成

Jiangxl~ 2024-07-02 08:37:02 阅读 75

文章目录

1.Ceph集群使用CSI客户端与K8S StorageClass集成简介2.RBD块存储与StorageClass集成架构图3.Ceph集群为StorageClass提供块存储设备3.1.在Ceph集群中创建StorageClass使用的资源池3.2.创建K8S集群访问RBD块存储设备的认证用户3.3.获取Ceph集群的集群信息

4.在K8S集群中部署CSI客户端工具4.1.创建CSI客户端使用的Configmap资源4.1.1.CSI连接Ceph集群的Configmap资源4.1.2.KMS密钥管理服务的Configmap资源4.1.3.Ceph配置的Configmap资源

4.2.创建CSI客户端访问K8S集群的RBAC授权4.3.在K8S集群中部署CSI客户端

5.基于Ceph集群RBD块设备创建Storageclass资源并进行使用5.1.将K8S访问RBD块存储的用户信息存储在Secret资源中5.2.创建一个StorageClass资源控制器5.3.创建PVC存储卷从StorageClass中自动分配PV5.4.创建Pod资源挂载PVC存储卷

6.在Statefulset控制器中应用StorageClass为每个Pod分配独立的存储6.1.编写Statefulset控制器资源编排文件6.2.创建资源控制器并观察PV和PVC的状态6.3.查看PV对应的RBD块存储

7.报错合集7.1.PVC使用StorageClass分配PV时报错缺少有效参数7.2.PVC创建一支处于等待中7.3.PVC通过StorageClass无法申请PV报错认证失败7.4.Pod无法挂载PVC报错块存储含有一些特殊featrues

1.Ceph集群使用CSI客户端与K8S StorageClass集成简介

StorageClass与Ceph RBD集成的官方文档:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/#rbd

Ceph对于StorageClass的官方文档:https://docs.ceph.com/en/pacific/rbd/rbd-kubernetes/

2.RBD块存储与StorageClass集成架构图

StorageClass资源可以通过客户端根据用户的需求自动创建出PV以及PVC资源。

StorageClass使用Ceph作为底层存储,为用户自动创建出PV以及PVC资源,使用的客户端工具是csi,首先需要在K8S集群中部署csi客户端工具,由csi客户端中驱动去连接Ceph集群。

image-20220412150549532

3.Ceph集群为StorageClass提供块存储设备

3.1.在Ceph集群中创建StorageClass使用的资源池

RBD块设备对接StorageClass,无需创建块设备,StorageClass连接到资源池后,会自动在里面创建块设备,分配的每一块PV都会在资源池中创建一个块存储设备。

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

pool 'kubernetes_data' created

3.2.创建K8S集群访问RBD块存储设备的认证用户

[root@ceph-node-1 ~]# ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes_data'

[client.kubernetes]

key = AQBlRVRibbqzJRAAD3lacYaxRloTVTio6e+10A==

命令解释可以参考之前的文章。

3.3.获取Ceph集群的集群信息

[root@ceph-node-1 ~]# ceph mon dump

epoch 1

fsid a5ec192a-8d13-4624-b253-5b350a616041#集群的ID,稍后会用到

last_changed 2022-04-02 22:09:57.238072

created 2022-04-02 22:09:57.238072

min_mon_release 14 (nautilus)

0: [v2:192.168.20.20:3300/0,v1:192.168.20.20:6789/0] mon.ceph-node-1

1: [v2:192.168.20.21:3300/0,v1:192.168.20.21:6789/0] mon.ceph-node-2

2: [v2:192.168.20.22:3300/0,v1:192.168.20.22:6789/0] mon.ceph-node-3

dumped monmap epoch 1

4.在K8S集群中部署CSI客户端工具

StorageClass通过CSI客户端与Ceph集群建立连接。

创建出StorageClass客户端所在的Namespace。

[root@k8s-master rbd-csi]# kubectl create ns storage-class

namespace/storage-class created

4.1.创建CSI客户端使用的Configmap资源

4.1.1.CSI连接Ceph集群的Configmap资源

首先来创建第一个Configmap资源,CSI客户端通过这个配置文件去连接Ceph集群,配置文件中包含集群的ID、集群Monitor组件的地址等信息。

1)编写资源编排文件

注意:不要在configmap资源编排文件中写注释。

[root@k8s-master rbd-csi]# vim csi-configmap.yaml

apiVersion: v1

kind: ConfigMap

data:

config.json: |-

[

{

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

"monitors": [#ceph集群monitor组件的地址

"192.168.20.20:6789",

"192.168.20.21:6789",

"192.168.20.22:6789"

]

}

]

metadata:

name: ceph-csi-config

2)创建Confimap资源

[root@k8s-master rbd-csi]# kubectl apply -f csi-configmap.yaml -n storage-class

configmap/ceph-csi-config created

[root@k8s-master rbd-csi]# kubectl get cm -n storage-class

NAME DATA AGE

ceph-csi-config 1 45s

4.1.2.KMS密钥管理服务的Configmap资源

新版本的CSI客户端还需要一个额外的Configmap资源,来定义KMS提供者的信息。

1)编写资源编排文件

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

apiVersion: v1

kind: ConfigMap

data:

config.json: |-

{

"vault-test": {

"encryptionKMSType": "vault",

"vaultAddress": "http://vault.default.svc.cluster.local:8200",

"vaultAuthPath": "/v1/auth/kubernetes/login",

"vaultRole": "csi-kubernetes",

"vaultPassphraseRoot": "/v1/secret",

"vaultPassphrasePath": "ceph-csi/",

"vaultCAVerify": "false"

}

}

metadata:

name: ceph-csi-encryption-kms-config

2)创建Confimap资源

[root@k8s-master rbd-csi]# kubectl apply -f csi-kms-config-map.yaml -n storage-class

configmap/ceph-csi-encryption-kms-config created

[root@k8s-master rbd-csi]# kubectl get cm -n storage-class

NAME DATA AGE

ceph-csi-config 1 78m

ceph-csi-encryption-kms-config 1 30m

4.1.3.Ceph配置的Configmap资源

新版的CSI客户端还需要再定义一个Configmap资源,来保存Ceph的配置。

1)编写资源编排文件

[root@k8s-master rbd-csi]# vim ceph-config-map.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

2)创建Confimap资源

[root@k8s-master rbd-csi]# kubectl apply -f ceph-config-map.yaml -n storage-class

configmap/ceph-config created

[root@k8s-master rbd-csi]# kubectl get cm -n storage-class

NAME DATA AGE

ceph-config 2 10m

ceph-csi-config 1 78m

ceph-csi-encryption-kms-config 1 30m

4.2.创建CSI客户端访问K8S集群的RBAC授权

CSI会在K8S集群中部署两个组件,分别是csi-provisioner和csi-nodeplugin,两个组件都需要配置RBAC授权。

1)下载CSI客户端的RBAC资源编排文件

[root@k8s-master rbd-csi]# wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-provisioner-rbac.yaml

[root@k8s-master rbd-csi]# wget https://raw.githubusercontent.com/ceph/ceph-csi/master/deploy/rbd/kubernetes/csi-nodeplugin-rbac.yaml

2)在K8S集群中创建RBAC资源

创建之前先将资源编排文件中写死的Namespace替换成你的Namespace。

:%s/namespace: default/namespace: storage-class/g

[root@k8s-master rbd-csi]# kubectl apply -f csi-provisioner-rbac.yaml -n storage-class

serviceaccount/rbd-csi-provisioner created

clusterrole.rbac.authorization.k8s.io/rbd-external-provisioner-runner configured

clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role configured

role.rbac.authorization.k8s.io/rbd-external-provisioner-cfg created

rolebinding.rbac.authorization.k8s.io/rbd-csi-provisioner-role-cfg created

[root@k8s-master rbd-csi]# kubectl apply -f csi-nodeplugin-rbac.yaml -n storage-class

serviceaccount/rbd-csi-nodeplugin created

clusterrole.rbac.authorization.k8s.io/rbd-csi-nodeplugin configured

clusterrolebinding.rbac.authorization.k8s.io/rbd-csi-nodeplugin configured

4.3.在K8S集群中部署CSI客户端

1)下载CSI客户端部署的资源编排文件

[root@k8s-master rbd-csi]# wget csi-rbdplugin-provisioner.yaml -n storage-class

[root@k8s-master rbd-csi]# wget csi-rbdplugin.yaml -n storage-class

2)调整资源编排文件中的镜像地址

将资源编排文件中的镜像地址全部替换成我给出的DockerHub地址,否则无法成功部署CSI客户端,镜像都在国外,拉取会超时。

image-20220412225921181

我在DockerHub中放了一套CSI的Docker镜像,只需要将资源编排文件中的镜像地址前缀修改即可,其余都不需要动,替换命令如下。

:%s#k8s.gcr.io/sig-storage#jiangxlrepo#g :%s#quay.io/cephcsi#jiangxlrepo#g

替换完如下所示。

image-20220420110220897

3)将客户端资源编排文件中的oidc-token卷注释掉

在客户端的两个资源编排文件中都有名称为oidc-token的存储卷,具体这个卷中是什么内容,官方也没有明确表示,因此不注释的话,在部署资源控制器的时候就会报错找不到这个卷,有没有这个卷对后面的使用没有任何影响。

image-20220420110251509

不注释掉此卷的话将来会报这个错误。

Warning FailedMount 38s (x8 over 102s) kubelet MountVolume.SetUp failed for volume "oidc-token" : failed to fetch token: the API server does not have TokenRequest endpoints enabled

3)去除Master节点配置的污点

csi-rbdplugin组件的是以DaemonSet控制器部署的,会在K8S集群中每一个节点中都部署一个Pod资源,由于我们的K8S集群是以Kubeadmin方式搭建的,因此需要将Master节点的污点去除,否则运行在Master节点的Pod将会一直处于pending状态。

[root@k8s-master rbd-csi]# kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule-

node/k8s-master untainted

存在污点会报下面的错,并且Pod一直处于Pending状态,去除污点配置即可。

image-20220413140216120

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

[root@k8s-master rbd-csi]# kubectl apply -f csi-rbdplugin-provisioner.yaml -n storage-class

service/csi-rbdplugin-provisioner created

deployment.apps/csi-rbdplugin-provisioner created

[root@k8s-master rbd-csi]# kubectl apply -f csi-rbdplugin.yaml -n storage-class

daemonset.apps/csi-rbdplugin created

service/csi-metrics-rbdplugin created

5)查看部署的资源

[root@k8s-master rbd-csi]# kubectl get all -n storage-class

NAME READY STATUS RESTARTS AGE

pod/csi-rbdplugin-brkn7 3/3 Running 0 10m

pod/csi-rbdplugin-gqvwl 3/3 Running 0 10m

pod/csi-rbdplugin-provisioner-68f8797c8c-44fwd 7/7 Pending 0 32m

pod/csi-rbdplugin-provisioner-68f8797c8c-9qfj7 7/7 Running 0 32m

pod/csi-rbdplugin-provisioner-68f8797c8c-vdx9z 7/7 Running 0 32m

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE

service/csi-metrics-rbdplugin ClusterIP 10.107.244.13 <none> 8080/TCP 10m

service/csi-rbdplugin-provisioner ClusterIP 10.109.233.129 <none> 8080/TCP 32m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE

daemonset.apps/csi-rbdplugin 2 2 2 2 2 <none> 10m

NAME READY UP-TO-DATE AVAILABLE AGE

deployment.apps/csi-rbdplugin-provisioner 3/3 3 2 32m

NAME DESIRED CURRENT READY AGE

replicaset.apps/csi-rbdplugin-provisioner-68f8797c8c 3 3 2 32m

5.基于Ceph集群RBD块设备创建Storageclass资源并进行使用

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

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

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

yum -y install ceph-common

5.1.将K8S访问RBD块存储的用户信息存储在Secret资源中

创建一个Secret资源,用于存储CSI客户端连接RBD的认证用户信息,由于使用的stringData保存用户的Key,因此用户的key在这里无需使用Base64加密。

在旧版本的CSI中,CSI客户端连接Ceph集群必须使用admin用户,CSI与Ceph认证存在Bug,如果使用的是新版本的CSI,则可以使用在Ceph中创建的普通用户进行连接,没有任何问题。

1)编写资源编排文件

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

apiVersion: v1

kind: Secret

metadata:

name: csi-rbd-secret

stringData:

userID: kubernetes

userKey: AQBlRVRibbqzJRAAD3lacYaxRloTVTio6e+10A==

2)创建资源

[root@k8s-master rbd-csi]# kubectl apply -f csi-rbd-secret.yaml -n storage-class

secret/csi-rbd-secret created

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

1)编写资源编排文件

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

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

name: rbd-storageclass

provisioner: rbd.csi.ceph.com #csi的驱动名称

parameters:

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

pool: kubernetes_data #块存储设备所在的资源池

csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret #csi客户端连接ceph需要用到认证用户的凭据,之前将用户凭据写在了secret资源中,这里填写secret的名称即可

csi.storage.k8s.io/provisioner-secret-namespace: storage-class #secret资源所在的命名空间

csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret#node节点挂载块存储也需要使用认证信息,也需要指定secret

csi.storage.k8s.io/node-stage-secret-namespace: storage-class#secret资源所在的命名空间

imageFormat: "2"#指定rbd块设备features某个特性的ID,默认为1

imageFeatures: "layering" #指定块设备的features类型

reclaimPolicy: Delete#回收策略设置的是Delete,当PVC删除时,在资源池中的块设备文件也会被删除

mountOptions:

- discard

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

[root@k8s-master storageclass]# kubectl apply -f rbd-storageclass.yaml

storageclass.storage.k8s.io/rbd-storageclass created

[root@k8s-master storageclass]# kubectl get sc

NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE

rbd-storageclass rbd.csi.ceph.com Delete Immediate false 4m30s

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

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

[root@k8s-master storageclass]# vim rbd-sc-pvc.yaml

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: rbd-sc-pvc

spec:

accessModes:

- ReadWriteOnce#必须使用这个访问模式,否则会报错

volumeMode: Filesystem

resources:

requests:

storage: 1Gi

storageClassName: rbd-storageclass#使用刚刚创建的storageclass为pv分配存储空间

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

[root@k8s-master storageclass]# kubectl apply -f rbd-sc-pvc.yaml

persistentvolumeclaim/rbd-sc-pvc created

[root@k8s-master storageclass]# kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

rbd-sc-pvc Bound pvc-9f4e2523-c812-4f0a-a801-4000d318fd10 1Gi RWX rbd-storageclass 31s

[root@k8s-master storageclass]# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

pvc-9f4e2523-c812-4f0a-a801-4000d318fd10 1Gi RWX Delete Bound default/rbd-sc-pvc rbd-storageclass 43s

可以看到PVC已经通过StorageClass为其自动创建了一个PV,并进行了绑定。

3)查看StorageClass是否在资源池中创建了块存储

通过StorageClass自动创建的每一个PV,在资源池中都会生成一个块存储设备。

[root@ceph-node-1 ~]# rbd -p kubernetes_data ls

csi-vol-e3e11cae-bb06-11ec-ac57-225651f4b5c9

rbd_pv_data.img

rbd_volume_data.img

4)查看块设备的信息

由于在StorageClass中已经配置了块设备的features类型,因此自动创建出来的块设备就不会含有不支持的features了。

[root@ceph-node-1 ~]# rbd info kubernetes_data/csi-vol-e3e11cae-bb06-11ec-ac57-225651f4b5c9

rbd image 'csi-vol-e3e11cae-bb06-11ec-ac57-225651f4b5c9':

size 1 GiB in 256 objects

order 22 (4 MiB objects)

snapshot_count: 0

id: d4ca14b70f09

block_name_prefix: rbd_data.d4ca14b70f09

format: 2

features: layering

op_features:

flags:

create_timestamp: Wed Apr 13 16:51:21 2022

access_timestamp: Wed Apr 13 16:51:21 2022

modify_timestamp: Wed Apr 13 16:51:21 2022

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

1)编写资源文件

和传统使用pvc的方式一样。

[root@k8s-master storageclass]# vim rbd-sc-pvc-pod.yaml

apiVersion: v1

kind: Pod

metadata:

name: rbd-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: rbd-sc-pvc

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

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

pod/rbd-sc-pvc-pod created

[root@k8s-master storageclass]# kubectl get pod

NAME READY STATUS RESTARTS AGE

rbd-sc-pvc-pod 1/1 Running 0 69s

3)进入Pod中使用PVC存储数据

[root@k8s-master storageclass]# kubectl exec -it rbd-sc-pvc-pod bash

root@rbd-sc-pvc-pod:/# df -hT /var/www/html

Filesystem Type Size Used Avail Use% Mounted on

/dev/rbd0 ext4 976M 2.6M 958M 1% /var/www/html

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

root@rbd-sc-pvc-pod:/var/www/html# echo "123" > index.html

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

index.html lost+found

root@rbd-sc-pvc-pod:/var/www/html# curl 127.0.0.1

123

6.在Statefulset控制器中应用StorageClass为每个Pod分配独立的存储

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

每个Pod都会通过StorageClass创建出一个PVC,每个PVC都会对应一个PV,每个PV都会在资源池中创建一个块存储设备。

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

资源编排文件的内容无任何差别,注意要设置一个访问模式。

[root@k8s-master storageclass]# vim ceph-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:

accessModes: [ "ReadWriteOnce" ]#访问模式设置成单主机可读可写

storageClassName: "rbd-storageclass"

resources:

requests:

storage: 1Gi

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

1.创建statefulset控制器

[root@k8s-master storageclass]# kubectl apply -f ceph-statefulset.yaml

statefulset.apps/nginx created

2.查看创建的资源

nginx-0 1/1 Running 0 8m39s

nginx-1 1/1 Running 0 8m23s

nginx-2 1/1 Running 0 8m

3.查看PV和PVC

[root@k8s-master storageclass]# kubectl get pv

NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE

pvc-65cfd953-f131-4b94-9c6b-a4916b5281d3 1Gi RWO Delete Bound default/web-data-nginx-0 rbd-storageclass 12m

pvc-74551433-767c-439e-8ce8-a5f93b68a1e0 1Gi RWO Delete Bound default/web-data-nginx-1 rbd-storageclass 12m

pvc-f46cce3e-0875-4045-b0b8-3b16f6def18e 1Gi RWO Delete Bound default/web-data-nginx-2 rbd-storageclass 12m

[root@k8s-master storageclass]# kubectl get pvc

NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE

web-data-nginx-0 Bound pvc-65cfd953-f131-4b94-9c6b-a4916b5281d3 1Gi RWO rbd-storageclass 13m

web-data-nginx-1 Bound pvc-74551433-767c-439e-8ce8-a5f93b68a1e0 1Gi RWO rbd-storageclass 13m

web-data-nginx-2 Bound pvc-f46cce3e-0875-4045-b0b8-3b16f6def18e 1Gi RWO rbd-storageclass 12m

#每一个Pod都有独立的PVC存储数据

6.3.查看PV对应的RBD块存储

每一个PV都会对应一个PVC。

[root@ceph-node-1 ~]# rbd -p kubernetes_data ls

csi-vol-1a423881-bba7-11ec-ac57-225651f4b5c9

csi-vol-66004615-bbc0-11ec-ac57-225651f4b5c9

csi-vol-6fb32417-bbc0-11ec-ac57-225651f4b5c9

csi-vol-7d94aaa2-bbc0-11ec-ac57-225651f4b5c9

csi-vol-e3e11cae-bb06-11ec-ac57-225651f4b5c9

rbd_pv_data.img

rbd_storageclass_data.img

rbd_volume_data.img

7.报错合集

7.1.PVC使用StorageClass分配PV时报错缺少有效参数

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Normal Provisioning 19s (x8 over 83s) rbd.csi.ceph.com_csi-rbdplugin-provisioner-68f8797c8c-vdx9z_da4228be-a2c9-44cd-ad7a-0c125c0322c6 External provisioner is provisioning volume for claim "default/rbd-sc-pvc"

Warning ProvisioningFailed 19s (x8 over 83s) rbd.csi.ceph.com_csi-rbdplugin-provisioner-68f8797c8c-vdx9z_da4228be-a2c9-44cd-ad7a-0c125c0322c6 failed to provision volume with StorageClass "rbd-storageclass": rpc error: code = InvalidArgument desc = missing required parameter imageFeatures

Normal ExternalProvisioning 13s (x6 over 83s) persistentvolume-controller waiting for a volume to be created, either by external provisioner "rbd.csi.ceph.com" or manually created by system administrator

从pvc的详细信息中可以看到一些报错内容,注意观察这句话: failed to provision volume with StorageClass "rbd-storageclass":rpc error: code = InvalidArgument desc = missing required parameter imageFeatures,大概意思就是说在rbd-storageclass资源中缺少了必要的参数,这个参数就是imageFeatures。

解决方案就是在StorageClass中将这个必要参数配置上即可,K8S的官方文档中也有说明。

image-20220413163149699

imageFeatures这个参数是来指定块存储的一些特性的,块设备的一些特性在很多的场景下是不支持的,因此需要在StorageClass中来指定自动创建的块存储的一些特性,避免不支持的特性产生其他的影响。

apiVersion: storage.k8s.io/v1

kind: StorageClass

metadata:

name: rbd-storageclass

provisioner: rbd.csi.ceph.com

parameters:

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

pool: kubernetes_data

csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret

csi.storage.k8s.io/provisioner-secret-namespace: storage-class

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

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

imageFormat: "2"

imageFeatures: "layering"

reclaimPolicy: Delete

mountOptions:

- discard

7.2.PVC创建一支处于等待中

报错内容如下:

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Normal ExternalProvisioning 6s (x6 over 67s) persistentvolume-controller waiting for a volume er "rbd.csi.ceph.com" or manually created by system administrator

Normal Provisioning 3s (x8 over 67s) rbd.csi.ceph.com_csi-rbdplugin-provisioner-68f8797c8c-42nlv_ff1dda12-9e5f-4d23-8aa0-7115c54c84d1 External provisioner eph-sc-pvc"

Warning ProvisioningFailed 3s (x8 over 67s) rbd.csi.ceph.com_csi-rbdplugin-provisioner-68f8797c8c-42nlv_ff1dda12-9e5f-4d23-8aa0-7115c54c84d1 failed to provision vass": rpc error: code = InvalidArgument desc = multi node access modes are only supported on rbd `block` type volumes

原因:PVC使用storageclass创建PV时,如果使用的是文件系统类型的PVC,那么访问模式必须设置成ReadWriteOnce,否则就会产生以上报错。

解决方法:要么将访问模式改成ReadWriteOnce,要么使用会Block块类型的PVC。

7.3.PVC通过StorageClass无法申请PV报错认证失败

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Normal ExternalProvisioning 10s (x3 over 20s) persistentvolume-controller

waiting for a volume to be created,either by external provisioner "rbd.csi.ceph.com" or manually created by system administrator

Normal Provisioning 4s (x5 over 20s)rbd.csi.ceph.com_csi-rbdplugin-provisioner-7b4b98b96f-6gcs 5dd21d9d-2c20-4657-9725-876383c7b04b External provisioner is provisioning volume for claim "default/rbd-pvc"

Warning ProvisioningFailed3s (x5over 15s) rbd.csi.ceph.com_csi-rbdplugin-provisioner-7b4b98b96f-6gqcs _5dd21d9d-2c20-4657-9725-876383c7b04b failed to provision volume with StorageClass "csi-rbd-sc" :rpc error: code = Internal desc = failed to get IOContext: failed to get connection: connecting failed:rados: ret=1, Operation not permitted

原因:CSI早期版本的Bug,必须使用admin才能认证成功,新版已经没有该问题了。

7.4.Pod无法挂载PVC报错块存储含有一些特殊featrues

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Normal Scheduled 80s default- scheduler Successfully assigned default/csi- rbd-demo-pod to node-3

Normal SuccessfulAttachVolume 80s attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-514448dd-f261-4095-a25c-c959dff7667e"

Warning FailedMount 31s (x7 over 67s) kubelet, node-3 MountVolume . MountDevice failed for volume "pvc-514448dd-f261-4095-a25c-959dff7667e" : rpc error: code = Internal desc = rbd: map failed exit status 6,rbd output: rbd: sysfs write failed

RBD image feature set mismatch. You can disable features unsupported by the kernel with "rbd feature disable kubernetes_data/csi-vol-159d233b-83e6-llea-8064- d24dd24330b3 object-map fast-diff deep- flatten".

In some cases useful info is found in syslog - try "dmesg| tail".

rbd: map failed: (6) No such device or address

这是StorageClass在Ceph资源池中默认创建的块存储包含了一些系统不支持的特性导致,执行rbd feature disable kubernetes_data/csi-vol-159d233b-83e6-llea-8064- d24dd24330b3 object-map fast-diff deep- flatten这条命令将不支持的特性删除即可解决。



声明

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