第31讲:K8S StorageClass使用rbd-provisioner驱动与Ceph RBD块存储集成

文章目录

1.rbd-provisioner驱动介绍

rbd-provisioner和csi-provisioner都是StorageClass对接Ceph集群块存储的驱动客户端,CSI客户端部署相对复杂,并且镜像拉取很费力,RBD客户端部署非常简单,相当于开箱即用。

无论使用哪种类型的驱动都可以,不过使用RBD客户端时,会遇到一个大坑,如下所示。

任何配置都正确,Ceph可执行命令也全部安装了,但是使用StorageClass为PVC分配PV时,依旧报以下错误:

sh 复制代码
Events:
  Type     Reason              Age                 From                         Message
  ----     ------              ----                ----                         -------
  Warning  ProvisioningFailed  50s (x15 over 18m)  persistentvolume-controller  Failed to provision volume with StorageClass "rbd-storageclass": failed to create rbd image: executable file not found in $PATH, command output:

提示创建RBD块存储的命令找不到,但是每个节点都安装了Ceph的可执行命令,这是因为K8S创建RBD块设备是通过Kube-controller-manage这组件调用RBD客户端的API来创建RBD块存储的,如果K8S集群是以kubeadm方式部署的,所有的组件都以Pod形式部署,虽然Node节点都安装了Ceph的命令,但是Kube-controller-manage组件是以容器运行的,容器中并没有这个命令,那么就会产生该问题。

解决方法就是手动部署一套外部的rbd-provisioner客户端,在客户端的容器里就包含了RBD的一些可执行命令,从而解决这个问题。

rbd-provisioner项目地址:https://github.com/kubernetes-retired/external-storage/tree/master/ceph/rbd/deploy/rbac

使用外部的rbd-provisioner驱动后,驱动的名称会发生改变,从默认的kubernetes.io/rbd名称修改成了ceph.com/rbd名称,因此在创建StorageClass时,需要明确指定新的rbd-provisioner驱动名称:ceph.com/rbd

这也是一个特别需要注意的地方,很多人都认为外部驱动也会保持默认的名称,其实不然,他也有自己的驱动名称,如果不指定,那么StorageClass依旧会调用Kube-controller-manager组件来创建RBD块存储,也可以从外部的rbd-provisioner Pod日志中看到新的驱动名称,如下图所示。

另外还有一个需要注意的地方,使用外部的rbd-provisioner驱动时,一定要将Ceph集群的/etc/ceph/ceph.client.admin.keyring文件上传到各个节点,否则也会报错,如下图所示

2.在K8S集群中部署外部的rbd-provisioner驱动

2.1.将Ceph集群的认证文件和配置上传到K8S的各个节点

外部的rbd-provisioner驱动容器需要通过Ceph的认证文件和配置文件才能够连接到集群,先将配置文件拷贝到各个K8S Node节点上,然后在驱动的资源编排文件中通过HostPath的方式将配置文件挂载到容器中。

sh 复制代码
[root@ceph-node-1 ~]# scp /etc/ceph/ceph.client.admin.keyring root@192.168.20.10:/etc/ceph/
[root@ceph-node-1 ~]# scp /etc/ceph/ceph.client.admin.keyring root@192.168.20.11:/etc/ceph/
[root@ceph-node-1 ~]# scp /etc/ceph/ceph.client.admin.keyring root@192.168.20.12:/etc/ceph/

[root@ceph-node-1 ~]# scp /etc/ceph/ceph.conf root@192.168.20.10:/etc/ceph/
[root@ceph-node-1 ~]# scp /etc/ceph/ceph.conf root@192.168.20.11:/etc/ceph/
[root@ceph-node-1 ~]# scp /etc/ceph/ceph.conf root@192.168.20.12:/etc/ceph/

2.2.获取外部rbd-provisioner驱动的资源编排文件

外部rbd-provisioner驱动的资源编排文件在GitHub中托管,GitHub地址:https://github.com/kubernetes-retired/external-storage/tree/master/ceph/rbd/deploy/rbac,主要是一些RBAC授权的资源编排文件和资源的Deployment编排文件。

在原有资源编排文件的基础中增加了一些调整,在ClusterRole中增加了endpoints和secrets两种资源的授权,在Deployment资源编排文件中添加了hostPath类型的存储,将Ceph集群的一些配置文件挂载到了容器中。

完整的资源编排文件内容如下:

yaml 复制代码
[root@k8s-master rbd-provisioner]# vim rbd-provisioner.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rbd-provisioner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["kube-dns", "coredns"]
    verbs: ["list", "get"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]												#增加了endpoints资源的授权
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]												
    resources: ["secrets"]													#增加了secrets资源的授权
    verbs: ["get", "list", "watch", "create", "update", "patch"]
 
---
 
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rbd-provisioner
subjects:
  - kind: ServiceAccount
    name: rbd-provisioner
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: rbd-provisioner
  apiGroup: rbac.authorization.k8s.io
 
---
 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: rbd-provisioner
  namespace: kube-system
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
- apiGroups: [""]
  resources: ["endpoints"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
 
---
 
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rbd-provisioner
  namespace: kube-system
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: rbd-provisioner
subjects:
- kind: ServiceAccount
  name: rbd-provisioner
  namespace: kube-system
 
---
 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: rbd-provisioner
  namespace: kube-system
  labels:
    app: rbd-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rbd-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: rbd-provisioner
    spec:
      containers:
      - name: rbd-provisioner
        image: "quay.io/external_storage/rbd-provisioner:latest"
        volumeMounts:									#挂载到容器的/etc/ceph目录中
        - name: ceph-conf			
          mountPath: /etc/ceph
        env:
        - name: PROVISIONER_NAME
          value: ceph.com/rbd
      serviceAccount: rbd-provisioner
      volumes:											#添加一个数据卷,将ceph的配置文件挂载到容器中
      - name: ceph-conf
        hostPath:
          path: /etc/ceph
 
---
 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: rbd-provisioner
  namespace: kube-system

2.3.在集群中部署rbd-provisioner驱动程序

1)创建rbd-provisioner驱动的所有资源控制器

sh 复制代码
[root@k8s-master rbd-provisioner]# kubectl apply -f rbd-provisioner.yaml
serviceaccount/rbd-provisioner created
clusterrole.rbac.authorization.k8s.io/rbd-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/rbd-provisioner created
role.rbac.authorization.k8s.io/rbd-provisioner created
rolebinding.rbac.authorization.k8s.io/rbd-provisioner created
deployment.apps/rbd-provisioner created

2)查看资源的状态

一定要确保rbd容器的状态是Running,否则后续一切不可用

sh 复制代码
[root@k8s-master rbd-provisioner]# kubectl get pod -n kube-system | grep rbd
rbd-provisioner-596454b778-8p648            1/1     Running   0          88m

rbd启动成功后,日志输出如下所示,可以看到驱动的名称和启动信息。

2.4.进入rbd-provisioner容器中查看Ceph的配置文件是否挂载

容器一定要能读到Ceph的配置文件,否则是无法连接到集群创建RBD块存储的。

sh 复制代码
[root@k8s-master rbd-provisioner]# kubectl exec -it rbd-provisioner-596454b778-8p648 bash -n kube-system 
[root@rbd-provisioner-596454b778-8p648 /]# ll /etc/ceph/
total 12
-rw-r--r-- 1 root root  151 Apr 14 14:08 ceph.client.admin.keyring
-rw-r--r-- 1 root root  623 Apr 14 14:17 ceph.conf
-rwxr-xr-x 1 root root 2910 Oct 30  2018 rbdmap

2.5.查看rbd-provisioner容器中Ceph相关命令的版本

这一步很关键,如果rbd-provisioner容器中的Ceph相关命令版本与物理机Ceph集群的版本不同的话,也是无法连接到Ceph集群创建RBD块存储的。

1)查看物理机上Ceph的版本

sh 复制代码
[root@ceph-node-1 ~]# ceph -v
ceph version 14.2.22 (ca74598065096e6fcbd8433c8779a2be0c889351) nautilus (stable)

2)查看rbd-provisioner容器中Ceph的版本

sh 复制代码
[root@k8s-master rbd-provisioner]# kubectl exec -it rbd-provisioner-596454b778-8p648 bash -n kube-system 
[root@rbd-provisioner-596454b778-8p648 /]# ceph -v
ceph version v13.2.1 (564bdc4ae87418a232fc901524470e1a0f76d641) nautilus (stable)

发现rbd-provisioner容器中Ceph的版本与物理机中Ceph集群的版本并不吻合,这也会产生问题,导致无法正常连接Ceph集群,需要将容器中Ceph相关命令的版本进行升级。

3)升级rbd-provisioner容器中Ceph的版本

sh 复制代码
1.进入到rbd-provisioner容器中
[root@k8s-master rbd-provisioner]# kubectl exec -it rbd-provisioner-596454b778-8p648 bash -n kube-system 

2.准备Ceph的yum源
[root@rbd-provisioner-596454b778-8p648 /]# vim /etc/yum.repos.d/ceph.repo 
[noarch]
name=noarch
baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/noarch/
enabled=1
gpgcheck=0

[x86_64]
name=x86_64
baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/x86_64/
enabled=1
gpgcheck=0

3.清理yum缓存
[root@rbd-provisioner-596454b778-8p648 /]# yum clean all
[root@rbd-provisioner-596454b778-8p648 /]# yum makecache

4.更新Ceph的版本
[root@rbd-provisioner-596454b778-8p648 /]# yum -y update

到此为止,rbd-provisioner驱动程序在集群中就真正部署完成了。

3.在Ceph集群中创建资源池以及认证用户

1)创建资源池

sh 复制代码
[root@ceph-node-1 ~]# ceph osd pool create kubernetes_data 16 16
pool 'kubernetes_data' created

2)创建认证用户

sh 复制代码
[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==

4.在K8S集群中创建一个StorageClass资源

rbd-provisioner驱动程序和Ceph资源池已经准备就绪,下面来创建一个StorageClass资源使用Ceph的RBD块存储作为底层存储系统。

4.1.将Ceph集群认证用户的信息存储在Secret中

StorageClass连接Ceph集群时,会用到两个认证用户,当然都使用同一个也没有问题,连接集群使用admin用户,操作资源池使用kubernetes用户,admin用户的Secret资源会存放在kube-system命名空间下,kubernetes用户的Secret资源会存放在于StorageClass相同的命名空间下,当然也可以将kubernetes用户的Secret资源存放在kube-system命名空间中,StorageClass引用Secret时可以指定命名空间。

1)将认证用户的Key进行Base64加密

如果不进行Base64加密也会报错。

sh 复制代码
1.admin用户加密
[root@ceph-node-1 ~]# ceph auth  get-key  client.admin | base64
QVFCSVdVaGlFbWFGT0JBQTZKcjZpdFVlSGlMVlZPZVlGVnBSb2c9PQ==

2.kubernetes用户加密
[root@ceph-node-1 ~]# ceph auth get-key client.kubernetes | base64
QVFCbFJWUmliYnF6SlJBQUQzbGFjWWF4UmxvVFZUaW82ZSsxMEE9PQ==

2)编写Secret资源编排文件

将两个Secret都存放在kube-system命名空间下,创建StorageClass时,指定Secret的命名空间即可,无需频繁创建Secret。

yaml 复制代码
[root@k8s-masterrbd-provisioner-yaml]# vim rbd-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: ceph-admin-secret
  namespace: kube-system
type: "kubernetes.io/rbd"
data:
  key: QVFCSVdVaGlFbWFGT0JBQTZKcjZpdFVlSGlMVlZPZVlGVnBSb2c9PQo=

---
apiVersion: v1
kind: Secret
metadata:
  name: ceph-kubernetes-secret
  namespace: kube-system  
type: "kubernetes.io/rbd"
data:
  key: QVFCbFJWUmliYnF6SlJBQUQzbGFjWWF4UmxvVFZUaW82ZSsxMEE9PQo=

3)创建Secret资源

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# kubectl apply -f rbd-secret.yaml 
secret/ceph-admin-secret created
secret/ceph-kubernetes-secret created

4.2.创建一个StorageClass存储资源

创建一个StorageClass存储类资源,使用Ceph集群的RBD作为底层存储。

特别需要注意的一点,在指定provisioner驱动名称时,一定要填写对外部rbd-provisioner的驱动名称,否则是有问题的。

1)编写资源编排文件

yaml 复制代码
[root@k8s-masterrbd-provisioner-yaml]# vim rbd-storageclass.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rbd-storageclass
  annotations:
     storageclass.beta.kubernetes.io/is-default-class: "true"
provisioner: ceph.com/rbd				#指定外部rbd-provisioner驱动的名称
reclaimPolicy: Retain
parameters:
  monitors: 192.168.20.20:6789,192.168.20.21:6789,192.168.20.22:6789			#monitor组件的地址	
  adminId: admin							#连接集群使用的用户凭据,使用amdin用户
  adminSecretName: ceph-admin-secret		  #admin用户的Secret资源名称
  adminSecretNamespace: kube-system			  #Secret资源所在的命名空间
  pool: kubernetes_data						 #资源池的名称
  userId: kubernetes						 #访问资源池的用户名称,使用kubernetes用户
  userSecretName: ceph-kubernets-secret		   #kubernetes用户的Secret资源名称
  userSecretNamespace: kube-system			   #资源所在的命名空间
  fsType: ext4
  imageFormat: "2"
  imageFeatures: "layering"

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

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# kubectl apply -f rbd-storageclass.yaml
storageclass.storage.k8s.io/rbd-storageclass created

[root@k8s-masterrbd-provisioner-yaml]# kubectl get sc
NAME                		PROVISIONER    RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
rbd-storageclass (default)   ceph.com/rbd   Retain          Immediate           false                  6m59s

5.创建PVC资源并使用StorageClass为其自动分配PV

5.1.创建一个PVC资源

1)编写资源编排文件

yaml 复制代码
[root@k8s-masterrbd-provisioner-yaml]# vim rbd-sc-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-sc-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: rbd-storageclass			#使用各个创建的Storageclass为其分配PV

2)创建PVC并观察状态

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# kubectl apply -f rbd-sc-pvc.yaml
persistentvolumeclaim/rbd-sc-pvc created

[root@k8s-masterrbd-provisioner-yaml]# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   		    AGE
rbd-sc-pvc    Bound    pvc-d5adca45-8593-4925-89f7-2347aab92e51   1Gi        RWO            rbd-storageclass        32m

可以看到已经是Bound状态了,已经为其自动的分配了PV。

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM   
pvc-d5adca45-8593-4925-89f7-2347aab92e51   1Gi        RWO            Retain           Bound      default/rbd-sc-pvc   rbd-storageclass                 32m

5.2.观察分配的PV与Ceph资源池中RBD块设备的关联关系

在PV的详细信息中就可以看到PV对应在Ceph资源池中的RBD块设备。

在资源池中查看块设备列表,与PV中显示的块设备名称一一对应。

5.3.观察rbd-provisioner容器日志现象

在rbd-provisioner容器的日志中也可以看到看到PVC使用StorageClass分配PV的过程,也可以看到创建RBD的过程。

6.创建Pod资源挂载PVC

PVC已经准备就绪了,下面可以创建一个Pod资源,去挂载PVC,验证数据存储是否存在问题。

1)编写资源编排文件

yaml 复制代码
[root@k8s-masterrbd-provisioner-yaml]# 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)创建资源并查看资源的状态

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# kubectl apply -f rbd-sc-pvc-pod.yaml 
pod/rbd-sc-pvc-pod created

[root@k8s-masterrbd-provisioner-yaml]# kubectl get pod
NAME              READY   STATUS    RESTARTS   AGE
rbd-sc-pvc-pod    1/1     Running   0          2m41s

3)Pod已经启动成功进入容器中验证数据持久化

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# 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/rbd1      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# touch file{1..10}.txt
root@rbd-sc-pvc-pod:/var/www/html# ls
file1.txt  file10.txt  file2.txt  file3.txt  file4.txt	file5.txt  file6.txt  file7.txt  file8.txt  file9.txt  lost+found

7.创建Statefulset控制器使用StorageClass为每个Pod分配独立的存储

创建一个Statefulset资源控制器使用StorageClass为每个Pod分配独立的存储,创建完成后,在Ceph资源池中观察RBD块存储。

7.1.创建一个Statefulset资源

1)编写资源编排文件

要声明StorageClass创建的PVC的访问模式是单主机可读可写。

yaml 复制代码
[root@k8s-masterrbd-provisioner-yaml]# vim rbd-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"				#使用StorageClass
      resources:
        requests:
          storage: 1Gi

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

sh 复制代码
[root@k8s-masterrbd-provisioner-yaml]# kubectl apply -f rbd-statefulset.yaml
statefulset.apps/nginx created

[root@k8s-masterrbd-provisioner-yaml]# kubectl get pod,statefulset
NAME                  READY   STATUS    RESTARTS   AGE
pod/rbd-sc-pvc-pod   ·1/1     Running   0          8m29s
pod/nginx-0           1/1     Running   0          2m40s
pod/nginx-1           1/1     Running   0          2m21s
pod/nginx-2           1/1     Running   0          2m1s

NAME                     READY   AGE
statefulset.apps/nginx   3/3     2m40s

7.2.查看PV与PVC以及RBD块设备

一一对应。

8.使用外部的rbd-provisioner故障拍错锦囊

8.1.报错一:无法找到可执行命令

报错内容如下所示:

sh 复制代码
Events:
  Type     Reason              Age   From                         Message
  ----     ------              ----  ----                         -------
  Warning  ProvisioningFailed  4s    persistentvolume-controller  Failed to provision volume with StorageClass "rbd-storageclass": failed to create rbd image: executable file not found in $PATH, command output:

报错内容提示创建RBD块存储的命令找不到,但是每个节点都安装了Ceph的可执行命令,这是因为K8S创建RBD块设备是通过Kube-controller-manage这组件调用RBD客户端的API来创建RBD块存储的,如果K8S集群是以kubeadm方式部署的,所有的组件都以Pod形式部署,虽然Node节点都安装了Ceph的命令,但是Kube-controller-manage组件是以容器运行的,容器中并没有这个命令,那么就会产生该问题。

解决方案:部署外部的rbd-provisioner驱动。

如果部署了外部的rbd-provisioner驱动依旧有此报错,那么就检查一下StorageClass中有没有指定rbd-provisioner驱动的名称。

8.2.报错二:PVC的详情中报错找不到Ceph配置文件无法连接集群

报错内容如下所示:

sh 复制代码
Events:
  Type     Reason              Age    From                                                                                Message
  ----     ------              ----   ----                                                                                -------
  Warning  ProvisioningFailed  7m17s  ceph.com/rbd_rbd-provisioner-76f6bc6669-hqpn5_eae0df48-bc00-11ec-84a4-ee385ddf95f6  failed to provision volume with StorageClass "cete rbd image: exit status 13, command output: did not load config file, using default settings.
2022-04-14 15:12:54.468 7f9baf613900 -1 Errors while parsing config file!
2022-04-14 15:12:54.468 7f9baf613900 -1 parse_file: cannot open /etc/ceph/ceph.conf: (2) No such file or directory
2022-04-14 15:12:54.468 7f9baf613900 -1 parse_file: cannot open /root/.ceph/ceph.conf: (2) No such file or directory
2022-04-14 15:12:54.468 7f9baf613900 -1 parse_file: cannot open ceph.conf: (2) No such file or directory
2022-04-14 15:12:54.470 7f9baf613900 -1 Errors while parsing config file!
2022-04-14 15:12:54.470 7f9baf613900 -1 parse_file: cannot open /etc/ceph/ceph.conf: (2) No such file or directory
2022-04-14 15:12:54.470 7f9baf613900 -1 parse_file: cannot open /root/.ceph/ceph.conf: (2) No such file or directory
2022-04-14 15:12:54.470 7f9baf613900 -1 parse_file: cannot open ceph.conf: (2) No such file or directory
2022-04-14 15:12:54.517 7f9baf613900 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bor directory
2022-04-14 15:12:57.522 7f9baf613900 -1 monclient: get_monmap_and_config failed to get config
2022-04-14 15:12:57.522 7f9baf613900 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bor directory
rbd: couldn't connect to the cluster!

根据报错内容可以看到在/etc/ceph/这个目录下,一些Ceph的配置文件不存在导致的该报错。

解决方法:将Ceph集群的ceph.client.admin.keyringceph.conf两个文件拷贝到所有的K8S Node节点中。

如果已经将配置文件拷贝到所有的K8S Node节点,问题依旧还在,无法解决,那么可能就不是Node节点需要这些配置文件,而是rbd-provisioner驱动的容器里需要这些文件,将配置文件使用kubectl cp的方式拷贝到Pod里就可以解决该问题,但是Pod是会被删除的,总不能每次都收到拷贝。

最终解决方案是在rbd-provisioner驱动的Deployment资源编排文件中增加一个hostPath类型的挂载,将Node节点的/etc/ceph目录挂载到Pod中。

yaml 复制代码
    spec:
      containers:
      - name: rbd-provisioner
        image: "quay.io/external_storage/rbd-provisioner:latest"
        volumeMounts:
        - name: ceph-conf
          mountPath: /etc/ceph
        env:
        - name: PROVISIONER_NAME
          value: ceph.com/rbd
      serviceAccount: rbd-provisioner
      volumes:
      - name: ceph-conf
        hostPath:
          path: /etc/ceph
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"

8.3.报错三:rbd-provisioner无法读取Secret资源

报错内容如下所示:

sh 复制代码
Events:
  Type     Reason                Age               From                                                                                Message
  ----     ------                ----              ----                                                                                -------
  Normal   Provisioning          8s (x2 over 23s)  ceph.com/rbd_rbd-provisioner-76f6bc6669-mz9wb_84f6f514-bc00-11ec-894b-fe2157f7b168  External provisioner is provisioning volume for claim "default/rbd-sc-pvc"
  Warning  ProvisioningFailed    8s (x2 over 23s)  ceph.com/rbd_rbd-provisioner-76f6bc6669-mz9wb_84f6f514-bc00-11ec-894b-fe2157f7b168  failed to provision volume with StorageClass "rbd-storageclass": failed to get admin secret from ["default"/"rbd-secret"]: secrets "rbd-secret" is forbidden: User "system:serviceaccount:kube-system:rbd-provisioner" cannot get resource "secrets" in API group "" in the namespace "default"
  Normal   ExternalProvisioning  1s (x4 over 23s)  persistentvolume-controller                                                         waiting for a volume to be created, either by external provisioner "ceph.com/rbd" or manually created by system administrator

由于RBAC授权导致的,rbd-provisioner资源位于kube-system命名空间下,而Secret资源在default命名空间下,故而无法读取。

解决方法:在rbd-provisioner驱动的ClusterRole资源编排文件中增加上以下配置即可解决。

sh 复制代码
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

8.4.报错四:rbd-provisioner获取集群配置失败

报错内容如下所示:

sh 复制代码
Events:
  Type     Reason              Age   From                                                                                Message
  ----     ------              ----  ----                                                                                -------
  Normal   Provisioning        17s   ceph.com/rbd_rbd-provisioner-596454b778-vtvp2_cfe5a372-bc89-11ec-8245-dec0ad1cd55d  External provisioner is provisioning volume for claim "default/rbd-sc-pvc"
  Warning  ProvisioningFailed  14s   ceph.com/rbd_rbd-provisioner-596454b778-vtvp2_cfe5a372-bc89-11ec-8245-dec0ad1cd55d  failed to provision volume with StorageClass "rbd-storageclass": failed to create rbd image: exit status 13, command output: 2022-04-15 07:28:08.232 7f5c3ef0c900 -1 monclient: get_monmap_and_config failed to get config
rbd: couldn't connect to the cluster!
  Normal  ExternalProvisioning  3s (x2 over 17s)  persistentvolume-controller  waiting for a volume to be created, either by external provisioner "ceph.com/rbd" or manually created by system administrator

获取集群配置失败,配置文件都准备好了,理论上不可能再出现这种情况,遇到这种情况后,先查看配置文件的权限,可以执行chmod +r ceph.client.admin.keyring这条命令给文件加一个读取权限。

如果依旧存在问题,那么很有可能是rbd-provisioner驱动容器中Ceph相关的命令与Ceph集群的版本不同导致,如果版本不同的话,将Ceph相关命令升级一下版本即可解决。

1)查看物理机上Ceph的版本

sh 复制代码
[root@ceph-node-1 ~]# ceph -v
ceph version 14.2.22 (ca74598065096e6fcbd8433c8779a2be0c889351) nautilus (stable)

2)查看rbd-provisioner容器中Ceph的版本

sh 复制代码
[root@k8s-master rbd-provisioner]# kubectl exec -it rbd-provisioner-596454b778-8p648 bash -n kube-system 
[root@rbd-provisioner-596454b778-8p648 /]# ceph -v
ceph version v13.2.1 (564bdc4ae87418a232fc901524470e1a0f76d641) nautilus (stable)

3)升级rbd-provisioner容器中Ceph的版本

sh 复制代码
1.进入到rbd-provisioner容器中
[root@k8s-master rbd-provisioner]# kubectl exec -it rbd-provisioner-596454b778-8p648 bash -n kube-system 

2.准备Ceph的yum源
[root@rbd-provisioner-596454b778-8p648 /]# vim /etc/yum.repos.d/ceph.repo 
[noarch]
name=noarch
baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/noarch/
																																																																																																																													enabled=1
																																																																																																																													gpgcheck=0
																																																																																																																													
																																																																																																																													[x86_64]
name=x86_64
baseurl=https://mirrors.aliyun.com/ceph/rpm-nautilus/el7/x86_64/
enabled=1
gpgcheck=0

3.清理yum缓存
[root@k8s-master rbd-provisioner]# yum clean all
[root@k8s-master rbd-provisioner]# yum makecache

4.更新Ceph的版本
[root@k8s-master rbd-provisioner]# yum -y update
相关推荐
AlfredZhao13 小时前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户97183563346619 小时前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪21 小时前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux
小宇宙Zz2 天前
Maven依赖冲突
java·服务器·maven
网络研究院2 天前
2026年网络安全
网络·安全·法律·法规·趋势·发展
酣大智2 天前
ARP代理--工作原理
运维·网络·arp·arp代理