其他分享
首页 > 其他分享> > k8s集群对接cephfs

k8s集群对接cephfs

作者:互联网

cephfs简介

CephFS是个与POSIX标准兼容的文件系统,坐于基于对象的 Ceph 存储集群之上,其内的文件被映射到 Ceph 存储集群内的对象。客户端可以把此文件系统挂载在内核对象或用户空间文件系统( FUSE )上。文件目录和其他元数据存储在ceph的RADOS中,而MDS缓存元信息和文件目录信息。
主要特点如下:

cephfs架构图如下:
k8s集群对接cephfs

在k8s环境下使用ceph rbd和cephfs的对比

1,多client挂载
ceph rbd支持同一个node下多pod的挂载;
cephfs支持跨node的多pod的挂载,实现共享;
2,性能
ceph rbd读取写入延迟低,I/O带宽表现良好;
cephfs读取延迟低,写入延迟差一点,I/O带宽表现良好,尤其是block size较大一些的文件;存储空间使用过大可能出现性能瓶颈;
3,配额管理
ceph rbd支持;
cephfs有条件支持;

环境准备

需要提前部署好ceph集群,见:https://blog.51cto.com/leejia/2499684

创建cephfs

cephfs需要至少一个mds(Ceph Metadata Server)服务用来存放cepfs服务依赖元数据信息,有条件的可以创建2个会自动成为主备。在ceph1上创建mds服务:

# ceph-deploy mds create ceph1 ceph2

一个cephfs需要至少两个RADOS存储池,一个用于数据、一个用于元数据。配置这些存储池时需考虑:

把cephfs用户对应的key访问如文件,并使用mount命令来挂载。卸载的话,通过umount命令直接卸载即可:

# echo "AQD1LfVffTlMHBAAove2EgMyJ8flMNYZG9VbTA==" >> /tmp/lee.secret
# mount -t ceph 172.18.2.172:6789,172.18.2.178:6789,172.18.2.189:6789:/ /mnt -o name=admin,secretfile=/tmp/lee.secret

# df -h|grep mnt
172.18.2.172:6789,172.18.2.178:6789,172.18.2.189:6789:/  586G   98G  488G  17% /mnt

通过storageclass动态创建基于cephfs的pv

现在cephfs已经部署完成,现在需要考虑k8s对接cephfs使用的问题了。k8s使用cephfs进行数据持久化时,主要有三种方式:

我们接下来介绍通过storageclass资源来动态分配pv的方法。

storageclass资源介绍

storageclass一般由管理员创建,它作为存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节操作,一方面减少了用户对于存储资源细节的关注,另一方面减轻了管理员手工管理PV的工作,由系统根据spec自动完成PV的创建和绑定,实现了动态的资源供应。并且,storageclass是不受namespace限制的。
storageclass的关键组成:

动态创建流程图(来源于kubernetes in action):
k8s集群对接cephfs

安装cephfs-provisioner

由于k8s没有内置cephfs的provisioner,故需要安装第三方的。我们先来简单看下此provisioner的架构:
k8s集群对接cephfs
主要有两部分:

安装

# git clone https://github.com/kubernetes-retired/external-storage.git
# cd external-storage/ceph/cephfs/deploy/
# NAMESPACE=kube-system
# sed -r -i "s/namespace: [^ ]+/namespace: $NAMESPACE/g" ./rbac/*.yaml
# sed -i "/PROVISIONER_SECRET_NAMESPACE/{n;s/value:.*/value: $NAMESPACE/;}" rbac/deployment.yaml
# kubectl -n $NAMESPACE apply -f ./rbac

过几分钟检查是否安装成功

# kubectl get pods -n kube-system|grep 'cephfs-provisioner'
cephfs-provisioner-6c4dc5f646-swncq        1/1     Running   0          1h

为cephfs创建stoageclass资源

我们复用ceph rdb存储的secret作为cephfs的secret:

# vim sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: cephfs
provisioner: ceph.com/cephfs
parameters:
    monitors: 172.18.2.172:6789,172.18.2.178:6789,172.18.2.189:6789
    adminId: admin
    adminSecretNamespace: "kube-system"
    adminSecretName: ceph-secret

# kubectl apply -f sc.yaml
# kubectl get storageclass
NAME                 PROVISIONER                  RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
ceph-rbd (default)   ceph.com/rbd                 Delete          Immediate           false                  216d
cephfs               ceph.com/cephfs              Delete          Immediate           false                  2h

跨不同node的pod之间存储共享

创建pvc并配置对应的storageclass,并确保pvc的status为Bound,代表storageclass创建和绑定pv成功:

# vim pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: claim-local
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: "cephfs"

# kubectl apply -f pvc.yaml
# kubectl get pvc|grep claim-local
NAME                                                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
claim-local                                           Bound    pvc-d30fda86-acfd-48e2-b7bc-568f6148332f   1Gi        RWX            cephfs            25s

创建一个绑定此pvc的pod,名字为cephfs-pv-pod1:

# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: cephfs-pv-pod1
spec:
  containers:
  - name: cephfs-pv-busybox1
    image: busybox
    command: ["sleep", "60000"]
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs-vol1
      readOnly: false
  volumes:
  - name: cephfs-vol1
    persistentVolumeClaim:
      claimName: claim-local

# kubectl apply -f pod.yaml
# kubectl get pods -o wide
NAME                                  READY   STATUS             RESTARTS   AGE    IP               NODE    NOMINATED NODE   READINESS GATES
cephfs-pv-pod1                        1/1     Running            0          33s    10.101.26.40     work4   <none>           <none>

我们发现cephfs-pv-pod1被调度到了work4,故我们给work1添加一个label,然后创建一个cephfs-pv-pod2并设置label把此pod调度到work1:

# kubectl label nodes work1 type=test
# kubectl get nodes --show-labels|grep work1
work1     Ready    <none>   237d   v1.18.2   app=dashboard,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=work1,kubernetes.io/os=linux,type=test

# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: cephfs-pv-pod2
spec:
  containers:
  - name: cephfs-pv-busybox1
    image: busybox
    command: ["sleep", "60000"]
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs-vol1
      readOnly: false
  volumes:
  - name: cephfs-vol1
    persistentVolumeClaim:
      claimName: claim-local
  nodeSelector:
    type: test

# kubectl apply -f pod.yaml
# kubectl get pods -o wide|grep cephfs
cephfs-pv-pod1                        1/1     Running     0          8m39s   10.101.26.40     work4   <none>           <none>
cephfs-pv-pod2                        1/1     Running     0          34s     10.99.1.167      work1   <none>           <none>

我们看到两个被调度到不同node的pod已经运行正常了,现在我们在cephfs-pv-pod1的存储写入数据,然后查看cephfs-pv-pod2的存储是否正常同步:

# kubectl exec -it cephfs-pv-pod1 sh
/ # echo "test" >> /mnt/cephfs/1.txt

# kubectl exec -it cephfs-pv-pod2 sh
/ # cat /mnt/cephfs/1.txt
test

我们发现cephfs存储已经正常挂载和使用了,至此k8s对接cephfs完成。

参考资料

https://docs.ceph.com/en/latest/cephfs/quota/
https://www.twblogs.net/a/5baf8cda2b7177781a0f2989
https://github.com/kubernetes-retired/external-storage/tree/master/ceph/cephfs

标签:kubectl,cephfs,pv,ceph,集群,storageclass,provisioner,k8s
来源: https://blog.51cto.com/leejia/2583380