当前位置:   article > 正文

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

ceph csi

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
  • 1
  • 2

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==
  • 1
  • 2
  • 3

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

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

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

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

[root@k8s-master rbd-csi]# kubectl create ns storage-class
namespace/storage-class created
  • 1
  • 2

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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
  • 1
  • 2

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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 
  • 1
  • 2

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

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

image-20220412225921181

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

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

替换完如下所示。

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
  • 1

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
  • 1
  • 2

存在污点会报下面的错,并且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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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

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

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

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

yum -y install ceph-common
  • 1

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==
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2)创建资源

[root@k8s-master rbd-csi]# kubectl apply -f csi-rbd-secret.yaml -n storage-class 
secret/csi-rbd-secret created
  • 1
  • 2

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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分配存储空间
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

可以看到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
  • 1
  • 2
  • 3
  • 4

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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存储数据
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

从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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

原因: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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

原因: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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/792809
推荐阅读
相关标签
  

闽ICP备14008679号