在Kubernetes上使用CephFS作为文件存储

2018-04-17 阅读: Kubernetes Ceph

1.PV ReadWriteMany的需求

最近一个正在开发的服务对PersistentVolume的Access Mode有ReadWriteMany的需求。 PersistentVolume持久化卷(即PV)是Kubernetes对存储的抽象,PV可以是网络存储,不属于任何Node,但可以在每个Node上访问。PV有以下三种访问模式(Access Mode):

  • ReadWriteOnce:只可被一个Node挂载,这个Node对PV拥有读写权限
  • ReadOnlyMany: 可以被多个Node挂载,这些Node对PV只有只读权限
  • ReadWriteMany: 可以被多个Node挂载,这些Node对PV拥有读写权限

我们之前使用Ceph RBD作为Kubernetes集群的PV,在使用场景上基于Kubernetes的Dynamic Storage Provision特性,使用provisioner: kubernetes.io/rbd的StorageClass来动态创建PV并由volumeClaimTemplates中声明自动创建的PVC去绑定,当前这种形式很稳定的支撑了我们业务的需求。 但RBD的访问模式是ReadWriteOnce的,面对最近的ReadWriteMany的需求,我们需要引入新的存储类型。在 Persistent Volumes文档中以表格的形式列出了当前Kubernetes个Volume Plugin支持的访问模式:

Volume PluginReadWriteOnceReadOnlyManyReadWriteMany
AWSElasticBlockStore--
AzureFile-
AzureDisk--
CephFS
Cinder--
FC-
FlexVolume-
Flocker--
GCEPersistentDisk-
Glusterfs
HostPath--
iSCSI-
PhotonPersistentDisk--
Quobyte
NFS
RBD-
VsphereVolume--(works when pods are collocated)
PortworxVolume-
ScaleIO-
StorageOS--

选择不是很多,有CephFS、Glusterfs、NFS等。由于我们已经在使用Ceph的块存储RBD和对象存储,而且当前这个正在开发的服务也不是很关键,所以这里选择使用CephFS。

2.在Ceph集群上创建CephFS

CephFS是一个支持POSIX接口的文件系统。文件系统对于客户端来说可以方便的挂载到本地使用。之前整理过一篇《Ceph文件系统存储之Ceph FS》

使用ceph-deploy为集群添加MDS:

ceph-deploy --overwrite-conf mds create node1 node2 node3

Ceph当前的版本还不支持一个集群中创建多个CephFS,会报Error EINVAL: Creation of multiple filesystems is disabled. To enable this experimental feature, use 'ceph fs flag set enable_multiple true'的错误,即正式环境不建议使用多文件系统,改特性当前只能体验。所以这里我们只创建一个名称为cephfs的CephFS。

一个CephFS需要两个pool来存储数据和元数据:

ceph osd pool create cephfs.data 8
ceph osd pool create cephfs.metadata 8

创建CephFS:

ceph fs new cephfs cephfs.metadata cephfs.data

创建一个cephfs.client用户,并授权。cephfs默认不会限制客户端用户对路径的访问权限,可以使用下面的命令设置权限同时创建好用户:

ceph fs authorize cephfs client.cephfs / r /data rw

这里设置cephfs用户对/有读权限,对/data有读写权限。

接下来我们使用admin用户挂载/,并创建好对应的目录:

mkdir /mnt/mycephfs
mount -t ceph node1:6789,node2:6789,node3:6789:/ /mnt/mycephfs -o name=admin,secret=thesecret
cd /mnt/mycephfs
mkdir data
cd data
mkdir myservice

此时cephfs的/data/myservice目录将作为我们正在开发的这个服务的数据目录。

3.在Kubernetes上挂载CephFS

基于使用RBD时使用了Kubernetes的Dynamic Storage Provision特性,在使用CephFS时首先想到了也要使用这个特性。 遗憾的是当前版本的Kubernetes还不支持CephFS作为Internal Provisioner。

Volume PluginInternal Provisioner
AWSElasticBlockStore
AzureFile
AzureDisk
CephFS-
Cinder
FC-
FlexVolume-
Flocker
GCEPersistentDisk
Glusterfs
iSCSI-
PhotonPersistentDisk
Quobyte
NFS-
RBD
VsphereVolume
PortworxVolume
ScaleIO
StorageOS
Local-

所以这里我们手动创建PV和PVC,并在服务的Deployment中使用PVC挂载数据卷。

将client.cephfs的keyring转成base64编码:

ceph auth get-key client.cephfs | base64
QVFBemNZVlo2c2JKTGhBQTdxQ0J5d00raVBSZ0FHOTdGdG9YSXc9PQ==

创建Secret ceph-secret-client-cephfs

apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret-client-cephfs
  namespace: dev
type: kubernetes.io/rbd
data:
  key: QVFBemNZVlo2c2JKTGhBQTdxQ0J5d00raVBSZ0FHOTdGdG9YSXc9PQ==

创建PV和PVC:

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: myservice-pv
  labels:
    name: myservice-pv
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteMany
  cephfs:
    monitors: 
    - node1:6789
    - node2:6789
    - node3:6789
    path: /data/myservice
    user: cephfs
    secretRef:
      name: ceph-secret-client-cephfs
    readOnly: false
  persistentVolumeReclaimPolicy: Retain

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myservice-pvc
  namespace: dev
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 2Gi
  selector:
    matchLabels:
      name: myservice-pv

注意这里的storageClassName要给”“,这是因为我们的集群中已经创建了默认的StorageClass,如果不给”“的话,将会按默认的StorageClass来。

最后在Deployment中使用myservice-pvc这个PVC即可:

---
kind: Deployment
apiVersion: apps/v1beta2
metadata:
  labels:
    app: myservice
  name: myservice
  namespace: dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myservice
  template:
    metadata:
      labels:
        app: myservice
    spec:
      containers:
      - name: myservice
        image: harbor.frognew.com/public/myservice:latest
        imagePullPolicy: Always
        resources:
          requests:
            memory: "2Gi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "500m"
        volumeMounts:
          - name: data
            mountPath: /data
        ports:
          - containerPort: 8080
            protocol: TCP
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: myservice-pvc

参考

标题:在Kubernetes上使用CephFS作为文件存储
本文链接:https://blog.frognew.com/2018/04/kubernetes-pv-cephfs.html
转载请注明出处。

目录