美文网首页
cephfs目录共享给多个pod使用

cephfs目录共享给多个pod使用

作者: 要厉害的 | 来源:发表于2021-12-30 21:07 被阅读0次

    本篇文章将介绍如何将cephfs的一个目录共享给多个pod使用,更进一步,多个pod之间虽共享一个目录,但可以隔离使用。

    写这篇文章的起因是业务部门有多个云原生应用同时产生日志。这些日志放到一个大的目录下管理比如logs/,并且不同的应用所产生的日志存放在不同的目录下。

    静态方式 VS 动态方式

    k8s访问cephfs的方式之一便是通过ceph-csi访问。ceph-csi提供了动态和静态的方式。

    静态方式由存储管理员显式地创建pv,开发者通过pvc获得符合容量要求和访问模式的pv,并和pod关联,达到使用存储的要求。但这样存在一些弊端,比如需要使用不同的pv时,管理员要分别手动构建pv。

    动态方式存储管理员不需要显式地创建pv,而是创建storageClass。由开发者声明pvc,由storageClass生成合适的pv。但是pv关联的路径使用uuid规则创建,如需将后台存储的目录和pod对应并不是很直观。

    实验环境

    搭建了一个minikube的k8s系统环境(版本V1.21.0)和ceph存储(版本16.2.4),完成ceph-csi的配置。


    k8s+ceph

    一、静态方式

    不需要配置storageClass。只需要配置一个pv、一个pvc和两个pod。

    1、创建cephfs的子卷

    在cephfs后端创建一个可使用的子卷,实质上是在cephfs内的/volumes(该目录是ceph-csi默认使用的目录)下面创建一系列子目录用来共享。

    首先创建一个子卷的组(相当于创建一个上层目录,后面的子卷都是该目录下的子目录)。命令如下:

    ceph fs subvolumegroup create cephfs data
    

    该命令的源格式为:

    ceph fs subvolumegroup create <文件系统名称> <子卷使用组>
    

    这条命令简单的效果是在cephfs后台会创建一个/volumes/data的路径。以后所有属于该组的子卷都在该目录下。

    创建子卷组

    然后创建一个子卷名称为data,该卷的大小为1GB大小,size的单位是bytes。命令如下:

    ceph fs subvolume create cephfs logs data --size=1073741824
    

    该命令的源格式为:

    ceph fs subvolume create <文件系统名称> <子卷名称> <子卷组> --size=<大小>
    

    文件系统后台实际创建 /volumes/data/logs/dda798fb-2160-4aca-b810-3bbf7bbdd394,即在子卷下面还有一个子目录,目录使用uuid命名。该uuid命名的目录配置了和size一致的配额。即pv的大小。

    创建子卷

    2、创建pv

    该pv文件名称为cephfs-static-pv1.yaml。pv里的内容:

    ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: cephfs-static-pv1
     spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 1Gi
      storageClassName: standard
      csi:
        driver: cephfs.csi.ceph.com
        nodeStageSecretRef:
          name: csi-cephfs-secret
          namespace: default
        volumeAttributes:
          "clusterID": "9b5661df-078e-448c-a97a-c8264a595623"
          "fsName": "cephfs"
          "staticVolume": "true"
          "rootPath": /volumes/data/logs/dda798fb-2160-4aca-b810-3bbf7bbdd394
          "mounter": fuse
          "fuseMountOptions": debug
        volumeHandle: cephfs-static-pv1
      persistentVolumeReclaimPolicy: Retain
      volumeMode: Filesystem
    

    参数说明

    名称 说明 一般取值
    clusterID ceph集群的ID 通过ceph -s获取
    fsName 文件系统名称 通过ceph fs ls获取
    staticVolume 是否为静态的卷 true为是
    rootPath ceph集群中的实际路径 通过getpath命令获取
    mounter 使用何种方式挂载 有fuse和kernel方式,对应fuse客户端和kernel客户端

    需要说明的几点

    1、storageClassName: standard,如果不加该句,pvc在apply之后会一直处于pending状态,通过describe pvc 可以看到“Cannot bind to requested volume storageClassName: does not match”的消息。官方文档少了这条说明。
    2、persistentVolumeReclaimPolicy: Retain,当pvc被释放后,PV将会被保留(不清理和删除)。
    3、rootPath可以通过getpath命令获取:ceph fs subvolume getpath cephfs logs data ,源命令格式为ceph fs subvolume getpath <文件系统名称> <子卷名称> <子卷组>。获取命令的结果带来uuid的子目录,这个uuid目录是带配额的,该配额和pv中描述的大小一致。
    4、删除pv和pvc不会删除文件系统后台的子卷,需要额外执行命令删除。

    应用该静态pv

    minikube kubectl -- apply -f  cephfs-static-pv1.yaml
    

    结果


    pv列表

    3、创建PVC

    在pod创建前创建pvc,该pvc名称为cephfs-static-pvc1.yaml。volumeName和以上创建的pv相对应。

    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: cephfs-static-pvc1
      namespace: default
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      volumeMode: Filesystem
      # volumeName should be same as PV name
      volumeName: cephfs-static-pv1
    

    应用该pvc

    minikube kubectl -- apply -f  cephfs-static-pvc.yaml
    

    查看所创建的pvc


    pvc列表

    4、创建pod

    创建两个pod分别使用logs/data/dda798fb-2160-4aca-b810-3bbf7bbdd394目录下面的dir4目录和dir5目录。每次在创建pod的时候需要指定一个subPath。

    第一个pod配置,指定使用dir4目录。

    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: csi-cephfs-demo-pod4
    spec:
      containers:
        - name: web-server1
          image: quay.io/jitesoft/nginx:1.20.0 
          volumeMounts:
            - name: myfs1 
              mountPath: /var/lib/www
              subPath: dir4
      volumes:
        - name: myfs1 
          persistentVolumeClaim:
            claimName: cephfs-static-pvc1
            readOnly: false
    

    使用volumeMounts中的参数subPathsubPath在实际存储后端会建立一个子目录,可以使容器在挂载数据卷时指向数据卷内部的一个子路径,而不是直接指向数据卷的根路径。第二个pod配置。指定使用dir5目录。

    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: csi-cephfs-demo-pod5
    spec:
      containers:
        - name: web-server1
          image: quay.io/jitesoft/nginx:1.20.0 
          volumeMounts:
            - name: myfs1 
              mountPath: /var/lib/www
              subPath: dir5
      volumes:
        - name: myfs1 
          persistentVolumeClaim:
            claimName: cephfs-static-pvc1
            readOnly: false
    

    两个pod创建后,在ceph后台可以看到路径如下

    存储后端关联目录

    查看挂载情况

    minikube kubectl -- exec -it csi-cephfs-demo-pod2 -- /bin/sh -c "df"
    

    在两个pod内各创建一个文件

    minikube kubectl -- exec -it csi-cephfs-demo-pod4 -- /bin/sh -c "touch /var/lib/www/a.txt"
    minikube kubectl -- exec -it csi-cephfs-demo-pod5 -- /bin/sh -c "touch /var/lib/www/b.txt"
    

    使用查看命令,可以看到每个pod的/var/lib/www中只有自己创建的内容。

    pod操作

    cephfs文件系统后端也分别在两个目录内创建了对应的文件


    文件存储结构

    二、动态方式

    创建一个storageClass和pvc,这里省去两个pod的创建过程。

    1、storageClass配置

    动态的storageClass配置如下:

    ---
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: csi-cephfs-sc
    provisioner: cephfs.csi.ceph.com
    parameters:
      clusterID: 9b5661df-078e-448c-a97a-c8264a595623
      fsName: cephfs
      pool: cephfs_data
      csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
      csi.storage.k8s.io/provisioner-secret-namespace: default
      csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
      csi.storage.k8s.io/controller-expand-secret-namespace: default
      csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
      csi.storage.k8s.io/node-stage-secret-namespace: default
    reclaimPolicy: Delete
    allowVolumeExpansion: true
    mountOptions:
      - discard
    
    名称 说明 一般取值
    clusterID ceph集群的ID 通过ceph -s获取
    fsName 文件系统名称 通过ceph fs ls获取
    pool 所使用的数据池 不同的池对应不同的存储规则,比如存储介质或故障域
    volumeNamePrefix 动态卷的前缀 一般是csi-开头
    mounter 使用何种方式挂载 有fuse和kernel方式,对应fuse客户端和kernel客户端
    kernelMountOptions 内核挂载的参数 readdir_max_bytes=1048576,norbytes

    2、pvc的配置

    pvc的配置

    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: csi-cephfs-pvc
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 1Gi
      storageClassName: csi-cephfs-sc
    

    在底层文件系统中展现的结构/volumes/csi/csi-vol-<uuid>/<uuid>两次uuid的值不相同。

    3、pod创建

    pod创建过程类似,修改claimName内的pvc内容。

    三、写在最后

    动态的方式使用uuid分配,底层路径和pod之间的关系不那么明显,使用静态卷+subPath的方式能够预知到所使用的路径,也做到了应用之间的隔离。

    目前发现的一个问题是无论用kernel方式还是fuse方式挂载,在一个Node上对应某个卷的挂载点只有一个,多个pod会同时访问一个客户端程序。可能造成caps过多,性能竞争的问题。(以下是通过ceph daemon session ls查看到的结果。在我的例子中两个pod共用一个ceph-fuse客户端)

    "client_metadata": {
        "features": "0x000000000000ffff",
        "ceph_sha1": "3cbe25cde3cfa028984618ad32de9edc4c1eaed0",
        "ceph_version": "ceph version 16.2.4 (3cbe25cde3cfa028984618ad32de9edc4c1eaed0) pacific (stable)",
        "entity_id": "admin",
        "hostname": "minikube",
        "mount_point": "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/cephfs-static-pv1/globalmount",
        "pid": "24452",
        "root": "/volumes/data/logs"
    }
    

    相关文章

      网友评论

          本文标题:cephfs目录共享给多个pod使用

          本文链接:https://www.haomeiwen.com/subject/qymiqrtx.html