当前位置: 代码网 > 服务器>服务器>Linux > 第32讲:K8S集群与Cephfs文件系统集成

第32讲:K8S集群与Cephfs文件系统集成

2024年07月31日 Linux 我要评论
K8S集群连接Cephfs文件系统时,默认情况下是连接的Ceph集群中默认的Cephfs文件系统,也就是数据资源池为cephfs_data和元数据资源池cephfs_metadata的Cephfs文件系统,并且K8S官方的对接Cephfs的文档中,如果Ceph集群中有多个Cephfs文件系统时,中并没有说明使用什么参数可以指定使用某一个的Cephfs文件文件系统。好在功夫不负有心人,再查阅了大量的资料后,终于找到了可以让K8S各种存储卷指定使用某一个Cephfs文件系统的方法。

1.在k8s环境下rbd与cephfs的使用对比

在k8s环境中,大多数情况下都是多个pod资源同时挂载一个存储端,共享存储中的数据,在这个普遍应用场景下,ceph集群的rbd块存储和cephfs文件系统有着非常明显的区别。

  • rbd存储
    • 仅支持同一个node节点中的多个pod共享存储中的数据,不支持跨node节点的pod挂载同一个rbd存储。
    • ceph rbd块存储的读写延迟低,性能强。
    • qkubernetes集群对rbd块存储有专门的驱动程序。
  • cephfs文件系统
    • 支持多个node节点中多个pod同时挂载,实现共享存储。
    • 读写延迟性能略逊于rbd块存储。
    • 需要安装第三方的驱动程序。

无论是rbd还是cephfs与k8s集群集成都没有想象中那么好,rbd不支持跨node节点的pod一起使用,而cephfs则不支持指定使用某个cephfs文件系统,但是在我不懈努力之下,终于研究出了指定某个cephfs文件系统的方法。

cephfs更加友好,起码支持跨节点的pod都可以同时使用,并且可以指定使用哪一个cephfs文件系统,我们可以为k8s集群单独创建一个cephfs文件系统。

cephfs文件系统常用的几种方式:

  • 为不同的客户端创建不同cephfs文件系统,挂载时指定使用不同的cephfs。

  • 集群中只创建一个cephfs,为不同的客户端在cephfs文件系统中创建不同的子目录,挂载时指定不同的子目录路径。

在实际生产者中第二种方式最为常见,但是如果一个ceph集群中要为不同类型的客户端提供存储服务,那么建议创建出多个cephfs文件系统,客户端通过参数分别指定使用哪一个cephfs。

2.cephfs环境介绍

k8s集群连接cephfs文件系统时,默认情况下是连接的ceph集群中默认的cephfs文件系统,也就是数据资源池为cephfs_data和元数据资源池cephfs_metadata的cephfs文件系统,并且k8s官方的对接cephfs的文档中,如果ceph集群中有多个cephfs文件系统时,中并没有说明使用什么参数可以指定使用某一个的cephfs文件文件系统。

好在功夫不负有心人,再查阅了大量的资料后,终于找到了可以让k8s各种存储卷指定使用某一个cephfs文件系统的方法。

我们k8s对接ceph集群的cephfs文件系统的环境如下:

3.在ceph集群中为k8s创建单独cephfs文件系统和认证用户

3.1.创建一个k8s使用的cephfs文件系统

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 14 and data pool 13

3)查看集群中所有的cephfs文件系统

发型当前集群有两个cephfs文件系统,后面会通过具体的参数,指定存储卷使用某一个cephfs文件系统。

[root@ceph-node-1 ~]# ceph fs ls
name: kubernetes_cephfs, metadata pool: kubernetes_cephfs_metadata, data pools: [kubernetes_cephfs_data ]
name: cephfs-storage, metadata pool: cephfs2_data, data pools: [cephfs2_metadata ]

4)查看cephfs文件系统的状态

[root@ceph-node-1 ~]# ceph fs status kubernetes_cephfs
kubernetes_cephfs - 0 clients
=================
+------+--------+-------------+---------------+-------+-------+
| rank | state  |     mds     |    activity   |  dns  |  inos |
+------+--------+-------------+---------------+-------+-------+
|  0   | active | ceph-node-2 | reqs:    0 /s |    0  |    0  |
+------+--------+-------------+---------------+-------+-------+
+----------------------------+----------+-------+-------+
|            pool            |   type   |  used | avail |
+----------------------------+----------+-------+-------+
| kubernetes_cephfs_metadata | metadata | 1728k | 17.9g |
|   kubernetes_cephfs_data   |   data   |    0  | 17.9g |
+----------------------------+----------+-------+-------+
+-------------+
| standby mds |
+-------------+
| ceph-node-1 |
+-------------+
+-----------------------------------------------------------------------------------+-------------+
|                                      version                                      |   daemons   |
+-----------------------------------------------------------------------------------+-------------+
|                                        none                                       | ceph-node-2 |
| ceph version 14.2.22 (ca74598065096e6fcbd8433c8779a2be0c889351) nautilus (stable) | ceph-node-1 |
+-----------------------------------------------------------------------------------+-------------+

3.2.将创建的cephfs文件系统挂载到本地路径

挂载到本地路径的原因是为了给k8s集群不同类型的存储卷,提供一个子目录,不同的存储卷挂载不同的子目录来存储持久化文件。

使用mount命令中的mds_namespace参数指定要将哪个cephfs文件系统挂载到本地路径。

[root@ceph-node-1 ~]# mount -t ceph  192.168.20.20:6789,192.168.20.21:6789,192.168.20.22:6789:/nginx_conf /nginx_conf/ -o name=admin,mds_namespace=kubernetes_cephfs

[root@ceph-node-1 kubernetes_cephfs]# df -ht /kubernetes_cephfs/
文件系统                                                   类型  容量  已用  可用 已用% 挂载点
192.168.20.20:6789,192.168.20.21:6789,192.168.20.22:6789:/ ceph   18g     0   18g    0% /kubernetes_cephfs

3.3.创建k8s连接ceph集群使用的认证用户

[root@ceph-node-1 ~]# ceph auth get-or-create client.kubernetes_cephfs mon "allow r" mds "allow rw" osd "allow rw pool=kubernetes_cephfs_data, allow rw pool=kubernetes_cephfs_metadata"
[client.kubernetes_cephfs]
	key = aqavmfpi1gm6gbaarrjdtxsxyqwgia1d7h2jhw==

4.k8s pv存储卷使用cephfs文件系统

4.1.在cephfs文件系统中为pv挂载创建子目录

在cephfs文件系统中为pv类型的存储卷创建独立的子目录,来持久化容器的数据。

现在属于实验环境,如果是线上环境时,还要在子子目录下为不同应用程序挂载分别创建三级目录。

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

4.2.将k8s连接cephfs的认证用户信息存储在secret中

我们在前面创建了一个专门用于k8s访问cephfs文件系统的认证用户,将该用户的key通过base64进行加密,然后保存在secret资源中,最后在创建存储卷的资源编排文件中,引用这个secret资源。

1)将认证用户的key进行base64加密

[root@ceph-node-1 ~]# ceph auth get-key client.kubernetes_cephfs | base64
qvfbvk1gcgkxz202r0jbqvjysmruwhn4wvf3r2lbmuq3adjqshc9pq==

2)将加密后的用户认证key存储在secret资源中

[root@k8s-master volumes]# vim cephfs-volumes-secret.yaml
apiversion: v1
kind: secret
metadata:
  name: cephfs-secret
data:
  key: qvfbvk1gcgkxz202r0jbqvjysmruwhn4wvf3r2lbmuq3adjqshc9pqo=

3)创建secret并查看资源的状态

[root@k8s-master volumes]# kubectl apply -f cephfs-volumes-secret.yaml
secret/cephfs-secret created

[root@k8s-master volumes]# kubectl get secret
name                  type                                  data   age
cephfs-secret         opaque                                1      3m30s

4.3.创建pv存储卷对接cephfs文件系统

创建一个pv资源采用cephfs文件系统作为底层存储端。

1)编写资源编排文件

pv指定使用某个cephfs文件系统主要是通过mountoptions参数来实现的,这个参数是为挂载存储卷时设置一些挂载参数,在宿主机使用mount挂载cephfs时有参数可以指定挂载哪一个cephfs,同理在pv中也提供了这种参数,通过这个参数,我们就可以指定使用哪一个cephfs文件系统了。

[root@k8s-master pv]# cat cephfs-pv.yaml
apiversion: v1
kind: persistentvolume
metadata:
  name: cephfs-pv
spec:
  capacity:
    storage: 10gi
  accessmodes:
  - readwritemany
  mountoptions: 								#指定使用哪一个cephfs文件系统
  - mds_namespace=kubernetes_cephfs					#cephfs文件系统的名称
  cephfs:										#存储源使用cephfs类型
    monitors:									#monitor组件的地址
    - 192.168.20.20:6789
    - 192.168.20.21:6789
    - 192.168.20.22:6789
    path: /pv_storage								#挂载cephfs文件系统中的哪一个子目录
    user: kubernetes_cephfs							#使用cephfs文件系统的认证用户
    readonly: false
    secretref:									   #认证用户的secret
      name: cephfs-secret
  persistentvolumereclaimpolicy: recycle

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

[root@k8s-master pv]# kubectl apply -f cephfs-pv.yaml 
persistentvolume/cephfs-pv created

[root@k8s-master pv]# kubectl get pv
name            capacity   access modes   reclaim policy   status      claim                    storageclass   reason   age
cephfs-pv       10gi       rwx            recycle          available                                                    5m12s

4.4.创建pvc资源从pv中获取存储空间

pv已经创建完成了,下面来创建pvc资源,关联pv,从pv中分配存储空间给pod资源使用。

1)编写资源编排文件

[root@k8s-master pv]# cat cephfs-pvc.yaml 
apiversion: v1
kind: persistentvolumeclaim
metadata:
  name: cephfs-pvc
spec:
  accessmodes:
    - readwritemany
  resources:
    requests:
      storage: 10gi

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

[root@k8s-master pv]# kubectl apply -f cephfs-pvc.yaml
persistentvolumeclaim/cephfs-pvc created

[root@k8s-master pv]# kubectl get pvc
name             status   volume          capacity   access modes   storageclass   age
cephfs-pvc       bound    cephfs-pv       10gi       rwx                           3s

pvc已经与pv资源进行了绑定,下面就可以给pod资源使用了。

4.5.创建pod资源将数据持久化到cephfs中

使用cephfs文件系统作为存储源的pv和pvc资源都已经准备就绪了,下面来创建一个pod资源,挂载pvc,将数据持久化到cephfs文件系统中。

1)编写资源编排文件

[root@k8s-master pv]# cat cephfs-pv-pod.yaml 
apiversion: v1
kind: pod
metadata:
  name: cephfs-pod
spec:
  containers:
    - image: nginx:1.15
      name: cephfs-pod
      ports:
      - name: web
        containerport: 80
        protocol: tcp
      volumemounts:
      - name: data
        mountpath: /data						#将pvc挂载到/data目录
  volumes:	
    - name: data
      persistentvolumeclaim:
        claimname: cephfs-pvc					#关联pvc的名称

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

[root@k8s-master pv]# kubectl apply -f cephfs-pv-pod.yaml
pod/cephfs-pod created

[root@k8s-master pv]# kubectl get pod
name         ready   status    restarts   age
cephfs-pod   1/1     running   0          11s

4.6.验证pod资源持久化数据导cephfs

pod资源已经创建完成,下面进入到pod中创建一些文件,看看是否能持久化到cephfs文件系统中。

1)在pod资源中写入数据文件

[root@k8s-master pv]# kubectl exec -it cephfs-pod bash 
root@cephfs-pod:/# cd /data/
root@cephfs-pod:/data# touch file{1..10}.txt

2)查看cephfs文件系统中是否有pod持久化的数据文件

到查看这一步,就要尽显当初将cephfs文件系统的根目录挂载到本地路径的好处了,我们可以直接进入到挂载的目录中,查看来自客户端写入的数据。

[root@ceph-node-1 ~]# cd /kubernetes_cephfs/
[root@ceph-node-1 kubernetes_cephfs]# tree pv_storage/
pv_storage/
├── aa
├── file10.txt
├── file1.txt
├── file2.txt
├── file3.txt
├── file4.txt
├── file5.txt
├── file6.txt
├── file7.txt
├── file8.txt
└── file9.txt

0 directories, 11 files

pod数据持久化成功。

5.k8s storageclass存储类使用cephfs文件系统

5.1.cephfs-provisioner客户端简介

storagecclass存储类动态分配pv,需要依赖第三方的客户端插件,通过客户端插件连接到cephfs文件系统,从而自动分配pv资源。

由于k8s没有内置cephfs的provisioner,故需要安装第三方的provisioner客户端

cephfs-provisioner主要组件:

  • cephfs-provisioner.go:是cephfs-provisioner(cephfs的storageclass)的核心,主要是watch kubernetes中pvc资源的curd事件,然后以命令行方式调用cephfs_provisor.py脚本创建pv。
  • cephfs_provisioner.py:python 脚本实现的与cephfs交互的命令行工具。cephfs-provisioner对cephfs端volume的创建都是通过该脚本实现。里面封装了volume的增删改查等功能。

5.2.在k8s集群中部署cephfs-provisioner客户端

cephfs-provisioner客户端在github的地址:https://github.com/kubernetes-retired/external-storage/tree/master/ceph/cephfs/deploy/rbac

完整的cephfs-provisioner客户端资源编排文件内容:

[root@k8s-master cephfs-provisioner]# cat cephfs-provisioner.yaml 
kind: clusterrole
apiversion: rbac.authorization.k8s.io/v1
metadata:
  name: cephfs-provisioner
  namespace: kube-system
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"]

---

kind: clusterrolebinding
apiversion: rbac.authorization.k8s.io/v1
metadata:
  name: cephfs-provisioner
subjects:
  - kind: serviceaccount
    name: cephfs-provisioner
    namespace: kube-system
roleref:
  kind: clusterrole
  name: cephfs-provisioner
  apigroup: rbac.authorization.k8s.io


---

apiversion: rbac.authorization.k8s.io/v1
kind: role
metadata:
  name: cephfs-provisioner
  namespace: kube-system
rules:
  - apigroups: [""]
    resources: ["secrets"]
    verbs: ["create", "get", "delete"]
  - apigroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]

---

apiversion: rbac.authorization.k8s.io/v1
kind: rolebinding
metadata:
  name: cephfs-provisioner
  namespace: kube-system
roleref:
  apigroup: rbac.authorization.k8s.io
  kind: role
  name: cephfs-provisioner
subjects:
- kind: serviceaccount
  name: cephfs-provisioner

---

apiversion: v1
kind: serviceaccount
metadata:
  name: cephfs-provisioner
  namespace: kube-system

---

apiversion: apps/v1
kind: deployment
metadata:
  name: cephfs-provisioner
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchlabels:
      app: cephfs-provisioner
  strategy:
    type: recreate
  template:
    metadata:
      labels:
        app: cephfs-provisioner
    spec:
      containers:
      - name: cephfs-provisioner
        image: "quay.io/external_storage/cephfs-provisioner:latest"
        env:
        - name: provisioner_name
          value: ceph.com/cephfs
        - name: provisioner_secret_namespace
          value: cephfs
        command:
        - "/usr/local/bin/cephfs-provisioner"
        args:
        - "-id=cephfs-provisioner-1"
      serviceaccount: cephfs-provisioner

在集群中部署cephfs-provisioner客户端。

[root@k8s-master cephfs-provisioner]# kubectl apply -f cephfs-provisioner.yaml
clusterrole.rbac.authorization.k8s.io/cephfs-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/cephfs-provisioner created
role.rbac.authorization.k8s.io/cephfs-provisioner created
rolebinding.rbac.authorization.k8s.io/cephfs-provisioner created
serviceaccount/cephfs-provisioner created
deployment.apps/cephfs-provisioner created

当看到cephfs-provisioner客户端的pod资源处于running状态就表示部署成功了。

[root@k8s-master cephfs-provisioner]# kubectl get pod -n kube-system | grep cephfs
cephfs-provisioner-67dd56fb57-l7xxm         1/1     running   0          21m

5.3.失败了。。。。。。。

6.k8s volumes存储卷使用cephfs文件系统

volumes类型的存储卷无法像pv、pvc等通过mountoptions参数指定要使用的cephfs文件系统,因此volumes存储卷只能使用默认的cephfs文件系统,基于这种场景,我们可以在默认的cephfs文件系统中创建出多个子目录供不同的客户端去使用,这也是cephfs文件系统最常用的方法。

6.1.在默认的cephfs文件系统中为volumes创建子目录

所谓默认的cephfs文件系统指的是数据资源池为cephfs_data、元数据资源池为cephfs_metadata的cephfs文件系统。

在cephfs文件系统中为volumes类型的存储卷创建独立的子目录,来持久化容器的数据。

1)默认的cephfs文件系统的创建方法

1.创建元数据资源池
[root@ceph-node-1 ~]# ceph osd pool create cephfs_metadata 16 16
pool 'cephfs_metadata' created

2.创建数据资源池
[root@ceph-node-1 ~]# ceph osd pool create cephfs_data 16 16
pool 'cephfs_data' created

3.创建cephfs文件系统
[root@ceph-node-1 ~]# ceph fs new cephfs-storage cephfs_metadata cephfs_data
new fs with metadata pool 8 and data pool 9

2)挂载cephfs文件系统

[root@ceph-node-1 ceph-deploy]# mount -t ceph  192.168.20.20:6789,192.168.20.21:6789,192.168.20.22:6789:/ /kubernetes_cephfs/ -o name=admin

3)为volumes存储创建子目录

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

6.2.将k8s连接cephfs的认证用户信息存储在secret中

可以直接使用admin用户连接ceph集群,也可以专门创建一个。

1)将认证用户的key进行base64加密

[root@ceph-node-1 ~]# ceph auth get-key client.admin | base64
qvfcsvdvaglfbwfgt0jbqtzkcjzpdfvlsglmvlzpzvlgvnbsb2c9pq==

2)将加密后的用户认证key存储在secret资源中

[root@k8s-master volumes]# vim cephfs-volumes-secret.yaml
apiversion: v1
kind: secret
metadata:
  name: cephfs-volumes-secret
data:
  key: qvfcsvdvaglfbwfgt0jbqtzkcjzpdfvlsglmvlzpzvlgvnbsb2c9pq==

3)创建secret并查看资源的状态

[root@k8s-master volumes]# kubectl apply -f cephfs-volumes-secret.yaml
secret/cephfs-secret created

[root@k8s-master volumes]# kubectl get secret
name                  type                                  data   age
cephfs-secret         opaque                                1      3m30s

6.3.volumes存储卷对接cephfs文件系统

创建一个pod资源使用volumes存储卷,将pod资源的数据持久化到cephfs文件系统中的子目录里。

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

[root@k8s-master volumes]# vim cephfs-volumes-pod.yaml
apiversion: v1
kind: pod
metadata:
  name: cephfs-pod-volumes
spec:
  containers:
  - name: cephfs-pod-volumes
    image: nginx:1.15
    volumemounts:
    - mountpath: "/data"
      name: cephfs-volume
  volumes:
  - name: cephfs-volume
    cephfs:									#使用cephfs类型
      monitors:								 #monitor集群的地址
      - 192.168.20.21:6789
      - 192.168.20.22:6789
      - 192.168.20.23:6789
      path: /volumes_storage					#挂载文件系统中的哪一个子目录
      user: admin								#连接ceph集群的用户
      secretref: 								#用户的secret资源名称
        name: cephfs-volumes-secret

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

[root@k8s-master volumes]# kubectl apply -f cephfs-volumes-pod.yaml
pod/cephfs-pod-volumes created

[root@k8s-master volumes]# kubectl get pod
name                 ready   status    restarts   age
cephfs-pod-volumes   1/1     running   0          4m18s

6.4.进入pod中产生数据验证数据持久化效果

1)产生数据

[root@k8s-master volumes]# kubectl exec -it cephfs-pod-volumes bash
root@cephfs-pod-volumes:/# cd /data/
root@cephfs-pod-volumes:/data# touch web{1..5}.index
root@cephfs-pod-volumes:/data# ls
web1.index  web2.index	web3.index  web4.index	web5.index

2)查看cephfs文件系统中的数据持久化结构

之前已经将文件系统挂载到本地路径了,可以直接看到一级一级目录的数据内容。

[root@ceph-node-1 ~]# tree /kubernetes_cephfs/
/kubernetes_cephfs/
└── volumes_storage
    ├── web1.index
    ├── web2.index
    ├── web3.index
    ├── web4.index
    └── web5.index

1 directory, 5 files
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com