使用文件存储CFS
所有文档

          容器引擎 CCE

          使用文件存储CFS

          准备工作

          用户做好以下准备,才能在容器中挂载CFS实例。

          创建容器集群

          1. 创建一个容器集群,操作步骤参考创建集群
          2. 下载命令行客户端kubectl,并连接集群,操作步骤参考通过kubectl连接Kubernetes集群

          创建CFS实例和挂载点

          1. 创建CFS实例,操作步骤请参考创建文件系统
          2. 添加CFS挂载点,操作步骤请参考添加挂载点

          注意: 创建的cfs实例和挂载点须和集群节点在同一vpc内。

          1. 获取CFS挂载地址,操作步骤请参考获取挂载地址

          本操作假设CFS挂载点地址为 cfs-test.baidubce.com

          操作指南

          静态PV/PVC方式挂载CFS

          1.在集群中创建PV和PVC资源

          使用kubectl,执行 kubectl create -f pv-cfs.yaml 完成PV的创建

          对应的pv-cfs.yaml文件如下所示:

          apiVersion: v1
          kind: PersistentVolume
          metadata:
            name: pv-cfs
          spec:
            capacity:
              storage: 8Gi
            accessModes:
              - ReadWriteMany
            persistentVolumeReclaimPolicy: Retain
            mountOptions:
              - hard
              - nfsvers=4.1
              - nordirplus
            nfs:
              path: /
              server: cfs-test.baidubce.com

          注意: yaml中server字段对应的是CFS挂载点地址

          注意: yaml中path字段对应的是CFS挂载目录,该目录需要在挂载前预先存在

          创建PV后,输入kubectl get pv可以看见一个available状态的PV,如下所示:

          $ kubectl get pv
          NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
          pv-cfs    8Gi        RWX            Retain           Available                                      3s

          建立一个能够与该PV绑定的PVC

          使用kubectl,执行 kubectl create -f pvc-cfs.yaml完成PVC的创建

          对应的pvc-cfs.yaml文件如下所示:

          kind: PersistentVolumeClaim
          apiVersion: v1
          metadata:
            name: pvc-cfs
          spec:
            accessModes:
              - ReadWriteMany
            resources:
              requests:
                storage: 8Gi

          绑定前,PVC为pending状态

          $ kubectl get pvc
          NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
          pvc-cfs   Pending                                                      2s                                                  2s

          绑定后,PV和PVC状态变为Bound

          $ kubectl get pv
          NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM             STORAGECLASS   REASON    AGE
          pv-cfs    8Gi        RWX            Retain           Bound     default/pvc-cfs                            36s
          $ kubectl get pvc
          NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
          pvc-cfs   Bound     pv-cfs    8Gi        RWX                           1m

          有关PV和PVC的更多设置和字段说明,见k8s官方文档

          2.在Pod内挂载PVC

          在Pod spec内指定相应的PVC名称即可,使用kubectl,执行 kubectl create -f demo-cfs-rc.yaml 完成rc的创建

          对应的demo-cfs-rc.yaml文件如下所示:

          apiVersion: v1
          kind: ReplicationController
          metadata:
            name: nginx
          spec:
            replicas: 20
            selector:
              app: nginx
            template:
              metadata:
                name: nginx
                labels:
                  app: nginx
              spec:
                containers:
                - name: nginx
                  image: nginx
                  ports:
                  - containerPort: 80
                  volumeMounts:
                  - mountPath: "/cfs-volume"
                    name: mycfs
                volumes:
                - name: mycfs
                  persistentVolumeClaim:
                    claimName: pvc-cfs

          Pod创建后,可以读写容器内的/cfs-volume路径来访问相应的CFS存储上的内容。

          由于创建PV和PVC时指定了accessModesReadWriteMany,该PVC可以被多节点上的Pod挂载读写。

          3.释放PV和PVC资源

          完成存储资源的使用后,可以释放PVC和PV资源

          使用以下命令可以释放PVC

          $ kubectl delete -f  pvc-cfs.yaml

          释放PVC后,原来与之绑定的PV状态会变为Release,如下所示:

          NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM             STORAGECLASS   REASON    AGE
          pv-cfs    8Gi        RWX            Retain           Released   default/pvc-cfs                            16m

          输入以下指令释放PV资源

          $ kubectl delete -f  pv-cfs.yaml

          动态PV/PVC方式挂载CFS

          1.创建StorageClass和Provisioner

          dynamic-cfs-template.yaml是一个yaml文件模板,包含了需要创建的集群资源信息。

          dynamic-cfs-template.yaml文件内容如下:

          kind: ClusterRole
          apiVersion: rbac.authorization.k8s.io/v1
          metadata:
            name: nfs-client-provisioner-runner
          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"]
          ---
          kind: ClusterRoleBinding
          apiVersion: rbac.authorization.k8s.io/v1
          metadata:
            name: run-nfs-client-provisioner
          subjects:
            - kind: ServiceAccount
              name: nfs-client-provisioner
              namespace: kube-system
          roleRef:
            kind: ClusterRole
            name: nfs-client-provisioner-runner
            apiGroup: rbac.authorization.k8s.io
          ---
          kind: Role
          apiVersion: rbac.authorization.k8s.io/v1
          metadata:
            name: leader-locking-nfs-client-provisioner
            namespace: kube-system
          rules:
            - apiGroups: [""]
              resources: ["endpoints"]
              verbs: ["get", "list", "watch", "create", "update", "patch"]
          ---
          kind: RoleBinding
          apiVersion: rbac.authorization.k8s.io/v1
          metadata:
            name: leader-locking-nfs-client-provisioner
            namespace: kube-system
          subjects:
            - kind: ServiceAccount
              name: nfs-client-provisioner
              # replace with namespace where provisioner is deployed
              namespace: kube-system
          roleRef:
            kind: Role
            name: leader-locking-nfs-client-provisioner
            apiGroup: rbac.authorization.k8s.io
          
          ---
          apiVersion: v1
          kind: ServiceAccount
          metadata:
            name: nfs-client-provisioner
            namespace: kube-system
          ---
          apiVersion: v1
          kind: PersistentVolume
          metadata:
            name: pv-cfs
          spec:
            capacity:
              storage: 5Gi
            accessModes:
              - ReadWriteMany
            persistentVolumeReclaimPolicy: Retain
            mountOptions:
              - hard
              - nfsvers=4.1
              - nordirplus
            nfs:
              path: {{NFS_PATH}}
              server: {{NFS_SERVER}}
          ---
          kind: PersistentVolumeClaim
          apiVersion: v1
          metadata:
            name: pvc-cfs
            namespace: kube-system
          spec:
            accessModes:
              - ReadWriteMany
            resources:
              requests:
                storage: 5Gi
          ---
          kind: Deployment
          apiVersion: apps/v1
          metadata:
            name: nfs-client-provisioner
            namespace: kube-system
          spec:
            selector:
              matchLabels:
                app: nfs-client-provisioner
            replicas: 1
            strategy:
              type: Recreate
            template:
              metadata:
                labels:
                  app: nfs-client-provisioner
              spec:
                serviceAccountName: nfs-client-provisioner
                containers:
                  - name: nfs-client-provisioner
                    image: hub.baidubce.com/jpaas-public/nfs-client-provisioner:latest
                    imagePullPolicy: Always
                    volumeMounts:
                      - name: nfs-client-root
                        mountPath: /persistentvolumes
                    env:
                      - name: PROVISIONER_NAME
                        value: {{PROVISIONER_NAME}}
                      - name: NFS_SERVER
                        value: {{NFS_SERVER}}
                      - name: NFS_PATH
                        value: {{NFS_PATH}}
                      - name: SHARE_PATH
                        value: "{{SHARE_PATH}}"
                volumes:
                  - name: nfs-client-root
                    persistentVolumeClaim:
                      claimName: pvc-cfs
          
          ---
          apiVersion: storage.k8s.io/v1
          kind: StorageClass
          metadata:
            name: {{STORAGE_CLASS_NAME}}
          provisioner: {{PROVISIONER_NAME}}
          parameters:
            archiveOnDelete: "{{ARCHIVE_ON_DELETE}}"
          mountOptions:
            - hard
            - nfsvers=4.1
            - nordirplus

          dynamic-cfs-template.yaml模板文件中可自定义的选项如下:

          • NFS_SERVER: CFS挂载点地址。
          • NFS_PATH: CFS远程挂载目录,注意该目录在使用前需要预先存在,如果目录不存在会导致provisioner插件启动失败。
          • SHARE_PATH: 不同PVC的CFS挂载目录是否隔离,true-不隔离,false-隔离。若指定隔离,则会在CFS挂载目录下为每个PVC创建一个子目录,对应PVC使用该子目录作为挂载目录;否则所有PVC共享挂载目录。
          • ARCHIVE_ON_DELETE: 删除PVC后是否保留对应数据,仅当PVC挂载目录隔离时生效,true-保留,false-不保留;PVC挂载目录共享时,删除PVC不会删除任何数据。设置为不保留则直接删除对应PVC的子目录,否则仅将原子目录名加上archive-前缀后保留。
          • STORAGE_CLASS_NAME: 创建的StorageClass名称。
          • PROVISIONER_NAME: Provisioner名称。

          支持shell的系统中,可以直接使用下面的replace.sh脚本进行yaml模板中模板变量的替换操作。

          #!/bin/sh
          # user defined vars
          
          NFS_SERVER="cfs-test.baidubce.com"
          NFS_PATH="/cce/shared"
          SHARE_PATH="true" # 不同PVC的挂载目录是否隔离,true-不隔离,false-隔离
          ARCHIVE_ON_DELETE="false" # 删除PVC是否保留对应数据,仅当PVC挂载目录隔离时生效,true-保留,false-不保留
          STORAGE_CLASS_NAME="sharedcfs" # StorageClass名称
          PROVISIONER_NAME="baidubce/$STORAGE_CLASS_NAME" # provisioner名称
          
          YAML_FILE="./dynamic-cfs-template.yaml"
          
          # replace template vars in yaml file
          
          sed -i "s#{{SHARE_PATH}}#$SHARE_PATH#" $YAML_FILE
          sed -i "s#{{ARCHIVE_ON_DELETE}}#$ARCHIVE_ON_DELETE#" $YAML_FILE
          sed -i "s#{{STORAGE_CLASS_NAME}}#$STORAGE_CLASS_NAME#" $YAML_FILE
          sed -i "s#{{PROVISIONER_NAME}}#$PROVISIONER_NAME#" $YAML_FILE
          sed -i "s#{{NFS_SERVER}}#$NFS_SERVER#" $YAML_FILE
          sed -i "s#{{NFS_PATH}}#$NFS_PATH#" $YAML_FILE

          将脚本中前半段中的shell变量替换为期望值,将replace.sh脚本和dynamic-cfs-template.yaml文件放置在同一个目录下,执行sh replace.sh即可。

          或者采用其他方式,将模板yaml文件中的模板变量替换为期望值。

          最后,使用kubectl工具,执行 kubectl create -f dynamic-cfs-template.yaml 完成StorageClass和Provisioner的创建。

          $ kubectl create -f dynamic-cfs-template.yaml
          clusterrole "nfs-client-provisioner-runner" created
          clusterrolebinding "run-nfs-client-provisioner" created
          role "leader-locking-nfs-client-provisioner" created
          rolebinding "leader-locking-nfs-client-provisioner" created
          serviceaccount "nfs-client-provisioner" created
          persistentvolume "pv-cfs" created
          persistentvolumeclaim "pvc-cfs" created
          deployment "nfs-client-provisioner" created
          storageclass "sharedcfs" created
          $ kubectl get pod --namespace kube-system  | grep provisioner
          nfs-client-provisioner-c94494f6d-dlxmj   1/1       Running   0          26s

          如果相应的Pod进入Running状态,则动态绑定PV所需的资源已经建立成功。

          2.创建PVC时动态生成PV并绑定

          在PVC Spec中指定上面创建的StorageClass名称,则在创建PVC时,会自动调用相应StorageClass绑定的的Provisioner生成相应的PV进行绑定。

          使用kubectl,执行 kubectl create -f dynamic-pvc-cfs.yaml 完成PVC的创建。

          假设创建的StorageClass名称为sharedcfs,对应的 dynamic-pvc-cfs.yaml 文件如下所示

          kind: PersistentVolumeClaim
          apiVersion: v1
          metadata:
            name: dynamic-pvc-cfs
          spec:
            accessModes:
              - ReadWriteMany
            storageClassName: sharedcfs
            resources:
              requests:
                storage: 5Gi

          创建PVC后,可以看见相应的PV自动创建,PVC状态变为Bound,即PVC已经与新创建的PV绑定。

          $ kubectl create -f dynamic-pvc-cfs.yaml
          persistentvolumeclaim "dynamic-pvc-cfs" created
          $ kubectl get pvc
          NAME              STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
          dynamic-pvc-cfs   Bound     pvc-6dbf3265-bbe0-11e8-bc54-fa163e08135d   5Gi        RWX            sharedcfs      4s
          $ kubectl get pv
          NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                     STORAGECLASS   REASON    AGE
          pv-cfs                                     5Gi        RWX            Retain           Bound     kube-system/pvc-cfs                                21m
          pvc-6dbf3265-bbe0-11e8-bc54-fa163e08135d   5Gi        RWX            Delete           Bound     default/dynamic-pvc-cfs   sharedcfs                7s

          3.在Pod内挂载PVC

          在Pod spec内指定相应的PVC名称即可,使用kubectl,执行 kubectl create -f dynamic-cfs-pod.yaml 完成资源的创建。

          对应的dynamic-cfs-pod.yaml文件如下所示:

          apiVersion: v1
          kind: Pod
          metadata:
            name: test-pvc-pod
            labels:
              app: test-pvc-pod
          spec:
            containers:
            - name: test-pvc-pod
              image: nginx
              volumeMounts:
                - name: cfs-pvc
                  mountPath: "/cfs-volume"
            volumes:
              - name: cfs-pvc
                persistentVolumeClaim:
                  claimName: dynamic-pvc-cfs

          Pod创建后,可以读写容器内的/cfs-volume路径来访问相应的CFS存储上的内容。

          4.释放PVC时动态销毁绑定PV

          删除PVC时,与之绑定的动态PV会被一同删除,其中的数据则根据用户定义的SHARE_PATHARCHIVE_ON_DELETE选项进行相应的保留或删除处理。

          $ kubectl get pvc
          NAME              STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
          dynamic-pvc-cfs   Bound     pvc-6dbf3265-bbe0-11e8-bc54-fa163e08135d   5Gi        RWX            sharedcfs      9m
          $ kubectl get pv
          NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                     STORAGECLASS   REASON    AGE
          pv-cfs                                     5Gi        RWX            Retain           Bound     kube-system/pvc-cfs                                31m
          pvc-6dbf3265-bbe0-11e8-bc54-fa163e08135d   5Gi        RWX            Delete           Bound     default/dynamic-pvc-cfs   sharedcfs                9m
          $ kubectl delete -f dynamic-pvc-cfs.yaml
          persistentvolumeclaim "dynamic-pvc-cfs" deleted
          $ kubectl get pv
          NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                 STORAGECLASS   REASON    AGE
          pv-cfs    5Gi        RWX            Retain           Bound     kube-system/pvc-cfs                            31m
          $ kubectl get pvc
          No resources found.
          上一篇
          使用云盘CDS
          下一篇
          使用对象存储BOS