初试 Kubernetes 集群使用 CephFS 文件存储

目录

  • Kubernetes PersistentVolumes 介绍
  • 环境、软件准备
  • 单节点使用 CephFS
  • Kubernetes PV & PVC 方式使用 CephFS
  • 测试跨节点使用 CephFS

1、Kubernetes PersistentVolumes 介绍

Kubernetes PersistentVolumes 持久化存储方案中,提供两种 API 资源方式: PersistentVolume(简称PV) 和 PersistentVolumeClaim(简称PVC)。PV 可理解为集群资源,PVC 可理解为对集群资源的请求,Kubernetes 支持很多种持久化卷存储类型。Ceph 是一个开源的分布式存储系统,支持对象存储、块设备、文件系统,具有可靠性高、管理方便、伸缩性强等特点。在日常工作中,我们会遇到使用 k8s 时后端存储需要持久化,这样不管 Pod 调度到哪个节点,都能挂载同一个卷,从而很容易读取或存储持久化数据,我们可以使用 Kubernetes 结合 Ceph 完成。

2、环境、软件准备

本次演示环境,我是在虚拟机 Linux Centos7 上操作,通过虚拟机完成 Ceph 存储集群搭建以及 Kubernetes 集群的搭建,以下是安装的软件及版本:

  1. Centos:release 7.4.1708 (Core)
  2. Ceph:jewel-10.2.10
  3. Kubernetes:v1.6.2
  4. Docker:v1.12.6

注意:这里我们着重描述一下 Kubernetes 集群如何使用 CephFS 来实现持久化存储,所以需要提前搭建好 Kubernetes 集群和 Ceph 存储集群,具体搭建过程可参考之前文章 国内使用 kubeadm 在 Centos 7 搭建 Kubernetes 集群初试 Centos7 上 Ceph 存储集群搭建,这里就不在详细讲解了。同时由于本机内存限制,共开启了 3 个虚拟机节点,每个节点既是 Ceph 集群节点又是 Kubernetes 集群节点,所以功能节点图如下:

这里写图片描述

3、单节点使用 CephFS

有上一篇 初试 Kubernetes 集群使用 Ceph RBD 块存储 操作的基础,这次就更加轻车熟路了!首先我们单节点使用 CephFS,先只使用 admin 和 node0,这样就将所有的 Pod 都调度到 node0 上执行。

k8s 集群单节点使用 CephFS,我们可以使用 Kubernetes Examples Github 官方示例代码,稍加修改即可。

$ cd /home/wanyang3/k8s
$ git clone https://github.com/kubernetes/examples.git
# tree examples/staging/volumes/cephfs
|-- cephfs-with-secret.yaml
|-- cephfs.yaml
|-- README.md
`-- secret
    `-- ceph-secret.yaml

跟之前使用 Ceph RBD 类似,也提供了两种方式供 k8s 集群使用 CephFS,在搭建 Ceph 集群时,默认开启了 cephx 安全认证的,所以在 k8s 集群使用 CephFS 时,也是要配置认证信息的,下边分别演示一下吧!

3.1 创建 cephfs

在正式开始演示之前,我们先在 admin 节点创建一个 cephfs,测试下 cephfs 是否可用吧!详细操作过程可参考文章 初试 Ceph 存储之块设备、文件系统、对象存储 中文件系统部分,贴下操作代码。

# 创建元数据服务器 MDS
$ ceph-deploy mds create admin node0 node1
...
$ ceph mds stat
e5: 1/1/1 up {0=node0=up:active}, 1 up:standby

# 创建 cephfs
$ ceph osd pool create cephfs_data 128
pool 'cephfs_data' created
$ ceph osd pool create cephfs_metadata 128
pool 'cephfs_metadata' created
$ ceph fs new cephfs cephfs_metadata cephfs_data
new fs with metadata pool 2 and data pool 1
$ ceph fs ls
name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ]

# 创建认证文件 admin.secret
$ cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
    key = AQD01VVaVvzzLRAAaTURyUZwI9Ad3uYYFRL+VA==
    caps mds = "allow *"
    caps mon = "allow *"
    caps osd = "allow *"
$ vim /etc/ceph/admin.secret
AQD01VVaVvzzLRAAaTURyUZwI9Ad3uYYFRL+VA==

$ mkdir /mnt/cephfs
$ mount -t ceph 10.222.78.12:6789:/ /mnt/cephfs -o name=admin,secretfile=/etc/ceph/admin.secret
$ df -h
...
10.222.78.12:6789:/   66G   32G   34G   49% /mnt/cephfs

从上边看到在 admin 节点已经成功将 cephfs 挂载到 /mnt/cephfs 啦!说明整个存储集群是没有问题的,接下来演示的时候,就不需要在各个节点再次创建 cephfs 了,pod 容器内部挂载即可。当然也创建不成功,因为目前 一个 Ceph 存储集群只支持创建一个 cephfs。

3.2 使用 cephfs.yaml

$ cat cephfs.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: cephfs1
spec:
  containers:
  - name: cephfs-rw
    image: kubernetes/pause
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs
  volumes:
  - name: cephfs
    cephfs:
      monitors:
      - 10.222.78.12:6789
      user: admin
      secretFile: "/etc/ceph/admin.secret"
      readOnly: true

修改完的配置如上,这里我们要挂载 /mnt/cephfs 目录到 Pod 容器内。在创建之前,我们要去 node0 节点生成 admin.secret (因为现在是单节点测试,Pod 只会被调度到 node0,后续加入node1 时也需要生成 admin.secret),同时这里 node0 既是 Ceph 集群 osd 节点又是 k8s 节点,所以已存在该文件,取出 Key 值即可。

$ cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
    key = AQD01VVaVvzzLRAAaTURyUZwI9Ad3uYYFRL+VA==
    caps mds = "allow *"
    caps mon = "allow *"
    caps osd = "allow *"
$ vim /etc/ceph/admin.secret
AQD01VVaVvzzLRAAaTURyUZwI9Ad3uYYFRL+VA==

好了,现在可以创建使用 CephFS 作为后端存储的 Pod 了。

$ kubectl create -f cephfs.yaml 
pod "cephfs1" created

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
cephfs1   1/1       Running   0          12s

接下来我们去 node0 上验证一下是否正确启动并挂载该 CephFS 吧!

# node0 上操作
$ docker ps
CONTAINER ID        IMAGE                                                                                                COMMAND                  CREATED             STATUS              PORTS               NAMES
b9f2bac921d1        docker.io/kubernetes/pause@sha256:2088df8eb02f10aae012e6d4bc212cabb0ada93cb05f09e504af0c9811e0ca14   "/pause"                 28 seconds ago      Up 27 seconds                           k8s_cephfs-rw_cephfs1_default_5cc74af6-f5ea-11e7-be96-080027ee5979_0

$ mount
...
10.222.78.12:6789:/ on /var/lib/kubelet/pods/5cc74af6-f5ea-11e7-be96-080027ee5979/volumes/kubernetes.io~cephfs/cephfs type ceph (ro,relatime,name=admin,secret=<hidden>,acl)


$ docker inspect b9f2bac921d1
...
"Mounts": [
            {
                "Source": "/var/lib/kubelet/pods/5cc74af6-f5ea-11e7-be96-080027ee5979/containers/cephfs-rw/80747a86",
                "Destination": "/dev/termination-log",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Source": "/var/lib/kubelet/pods/5cc74af6-f5ea-11e7-be96-080027ee5979/volumes/kubernetes.io~cephfs/cephfs",
                "Destination": "/mnt/cephfs",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            },
            {
                "Source": "/var/lib/kubelet/pods/5cc74af6-f5ea-11e7-be96-080027ee5979/volumes/kubernetes.io~secret/default-token-jg3f8",
                "Destination": "/var/run/secrets/kubernetes.io/serviceaccount",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            },
            {
                "Source": "/var/lib/kubelet/pods/5cc74af6-f5ea-11e7-be96-080027ee5979/etc-hosts",
                "Destination": "/etc/hosts",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

3.3 使用 cephfs-with-secret & ceph-secret

接下来使用 cephfs-with-secret 和 ceph-secret 方式,这种方式跟上边直接使 admin.secret 文件认证最大的区别就是使用 k8s secret 对象,该 secret 对象用于 k8s volume 插件通过 cephx 认证访问 ceph 存储集群。不过要提一下的是,k8s secret 认证 key 需要使用 base64 编码。

# 获取 Ceph ceph.client.admin.keyring 并生成 secret key
$ ceph auth get-key client.admin |base64
QVFEMDFWVmFWdnp6TFJBQWFUVVJ5VVp3STlBZDN1WVlGUkwrVkE9PQ==

修改 ceph-secret.yaml 文件中,key 字段替换成上边生成的字符串。

$ cat ceph-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: ceph-secret
data:
  key: QVFEMDFWVmFWdnp6TFJBQWFUVVJ5VVp3STlBZDN1WVlGUkwrVkE9PQ==

创建名称为 ceph-secret 的 Secret。

$ kubectl create -f ceph-secret.yaml 
secret "ceph-secret" created
$ kubectl get secret
NAME                  TYPE                                  DATA      AGE
ceph-secret           Opaque                                1         11s
default-token-jg3f8   kubernetes.io/service-account-token   3         28m

接下来,需要修改一下 cephfs-with-secret.yaml 文件,主要修改 cephfs 相关信息,修改完成后如下。

# cat cephfs-with-secret.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: cephfs2
spec:
  containers:
  - name: cephfs-rw
    image: kubernetes/pause
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs
  volumes:
  - name: cephfs
    cephfs:
      monitors:
      - 10.222.78.12:6789
      user: admin
      secretRef:
        name: ceph-secret
      readOnly: true

配置跟上边类似,唯一区别就是 secretRef 换成刚创建的 ceph-secret 对象,接下来创建该 Pod 啦!

$ kubectl create -f cephfs-with-secret.yaml 
pod "cephfs2" created
$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
cephfs1   1/1       Running   0          11m
cephfs2   1/1       Running   0          25s

跟上边示例一样,妥妥没问题,可以去 node0 上查看 mount 信息验证一下,这里就不在演示了。

4、Kubernetes PV & PVC 方式使用 CephFS

上一篇文章中指出,k8s 支持的 PV 类型有很多,其中就有我们熟悉的 Ceph RBD 和 CephFS,接下来就演示一下如何使用 PV & PVC 结合 CephFS 完成上边演示操作。这里使用上边创建的同一个 cephfs,因为一个 Cephfs 存储集群只支持创建一个 cephfs。还有就是,这里我们可以加入 node1 了,组成一个多节点的 k8s 集群,测试跨节点使用 CephFS。

4.1 创建 PV

还记得上边提过 Ceph 认证的 secret,这里也是需要的,这次就不用再创建了,直接复用上边的即可。新建 PV 文件 rbd-pv.yaml 如下:

$ vim cephfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: cephfs-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  cephfs:
    monitors:
      - 10.222.78.12:6789
    user: admin
    secretRef:
      name: ceph-secret
    readOnly: false
  persistentVolumeReclaimPolicy: Recycle

注意,这里我们使用的 accessModes 模型为 ReadWriteMany,kubernetes 官网 Persistent Volumes 文档中指出 CephFS 文件存储对三种 Mode 方式都支持,CephFS 支持读写多次,也是实际工作中需要的。接下来创建 PV。

$ kubectl create -f cephfs-pv.yaml 
persistentvolume "cephfs-pv" created
$ kubectl get pv
NAME        CAPACITY   ACCESSMODES   RECLAIMPOLICY   STATUS      CLAIM     STORAGECLASS   REASON    AGE
cephfs-pv   1Gi        RWX           Recycle         Available     

4.2 创建 PVC

好了,上边 PV 资源已经创建好了,接下来创建对资源的请求 PVC,新建 PVC 文件 cephfs-pv-claim.yaml 如下:

$ cat cephfs-pv-claim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: cephfs-pv-claim
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

这里提一下的是,因为接下来验证测试需要跨节点读取和写入文件,所以使用 ReadWriteMany 模型,接下来创建 PVC。

$ kubectl create -f cephfs-pv-claim.yaml 
persistentvolumeclaim "cephfs-pv-claim" created
$ kubectl get pvc
NAME              STATUS    VOLUME      CAPACITY   ACCESSMODES   STORAGECLASS   AGE
cephfs-pv-claim   Bound     cephfs-pv   1Gi        RWX                          10s

4.3 创建挂载 CephFS 的 Pod

PV 和 PVC 都创建好了,接下来就需要创建挂载该 CephFS 的 Pod 了,这里我使用官方示例中的 busybox 容器测试吧!新建 Pod 文件 cephfs-pvc-pod1.yaml 如下:

# vim cephfs-pvc-pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: cephfs-pvc-pod
  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: cephfs-pv-claim

从文件可以看出,我们要将上边创建的 cephfs-pv-claim 请求的资源挂载到容器的 /mnt/cephfs 目录。接下来创建一下该 Pod,看是否能够正常运行吧!创建之前,我们先造点数据到 /mnt/cephfs 目录,方便后边读取测试。

# 提前写入数据
$ vim /mnt/cephfs/test.txt 
This is cephfs test file.

# 创建 cephfs-pv-pod1
$ kubectl create -f cephfs-pvc-pod.yaml 
pod "cephfs-pv-pod1" created
$ kubectl get pod
NAME             READY     STATUS    RESTARTS   AGE
cephfs-pv-pod1   1/1       Running   0          47s
$ kubectl get pod --all-namespaces -o wide
NAMESPACE     NAME                            READY     STATUS    RESTARTS   AGE       IP              NODE
default       cephfs-pv-pod1                  1/1       Running   0          26s       10.96.2.2       node1
...

我们看到 Pod 能够正常启动,并且分配到了 node1,接下来我们去 node1 验证一下吧!

# node1 上操作
$ docker ps
CONTAINER ID        IMAGE                                                                                       COMMAND                  CREATED             STATUS              PORTS               NAMES
3cc605bed890        docker.io/busybox@sha256:436bbf48aa1198ebca8eac0ad9a9c80c8929d9242e02608f76ce18334e0cfe6a   "sleep 60000"            12 seconds ago      Up 12 seconds                           k8s_cephfs-pv-busybox1_cephfs-pv-pod1_default_a2397f5d-f677-11e7-be96-080027ee5979_0

$ docker exec -it 3cc605bed890 /bin/sh
/ # df -h
Filesystem                Size      Used Available Use% Mounted on
10.222.78.12:6789:/      65.4G     34.1G     31.3G  52% /mnt/cephfs
...

/ # ls  /mnt/cephfs
test.txt
/ # cat /mnt/cephfs/test.txt
This is cephfs test file.

# 创建一个新文件,测试下边跨节点看能否挂载的上,并且能够读取出来吧。
/ # vi /mnt/cephfs/cephfs-pv-pod1.txt
/ # cat /mnt/cephfs/cephfs-pv-pod1.txt
This message write by cephfs-pv-pod1 pod.

OK 我们看到 Pod 容器内能够正确挂载 CephFS 并成功读取到之前创建的文件。

5、测试跨节点使用 CephFS

上一篇文中 K8s 集群跨节点使用 Ceph RBD 存在 rbd: image ceph-rbd-pv-test is locked by other nodes 错误信息,说明 Ceph RBD 仅能被 k8s 中的一个 node 挂载,也就是不支持跨节点挂载同一 Ceph RBD。那么 CephFS 也会存在这个问题吗?接下来我们验证一下。

我们再在另外一个 node 上创建挂载同一个 CephFS 的 Pod,看是否可以跨节点挂载吧!

# 创建挂载 cephfs 的 pod2,配置同 pod1
$ vim cephfs-pvc-pod2.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: cephfs-pvc-pod
  name: cephfs-pv-pod2
spec:
  containers:
  - name: cephfs-pv-busybox2
    image: busybox
    command: ["sleep", "60000"]
    volumeMounts:
    - mountPath: "/mnt/cephfs"
      name: cephfs-vol2
      readOnly: false
  volumes:
  - name: cephfs-vol2
    persistentVolumeClaim:
      claimName: cephfs-pv-claim

接下来创建一下该 Pod,看能够创建成功吧!

$ kubectl create -f cephfs-pvc-pod2.yaml 
pod "cephfs-pv-pod2" created

$ kubectl get pods --all-namespaces -o wide
NAMESPACE     NAME                            READY     STATUS    RESTARTS   AGE       IP              NODE
default       cephfs-pv-pod1                  1/1       Running   0          9m        10.96.2.3       node1
default       cephfs-pv-pod2                  1/1       Running   0          16s       10.96.1.4       node0

OK 我们看到 cephfs-pv-pod2 被分配到了 node0 并且正常运行起来了。说明 K8s 支持 CephFS 跨节点挂载。接下来,我们去 node0 验证一下是否正确挂载该 CephFS 吧!

# node0 上操作
$ docker ps
CONTAINER ID        IMAGE                                                                                       COMMAND                  CREATED              STATUS              PORTS               NAMES
f8e544e9f497        docker.io/busybox@sha256:436bbf48aa1198ebca8eac0ad9a9c80c8929d9242e02608f76ce18334e0cfe6a   "sleep 60000"            About a minute ago   Up About a minute                       k8s_cephfs-pv-busybox2_cephfs-pv-pod2_default_faf6f3fd-f678-11e7-be96-080027ee5979_0

$ docker exec -it f8e544e9f497 /bin/sh
/ # df -h
Filesystem                Size      Used Available Use% Mounted on
10.222.78.12:6789:/      65.4G     34.1G     31.3G  52% /mnt/cephfs
...

/ # ls -l /mnt/cephfs
total 1
-rw-r--r--    1 root     root            42 Jan 11 02:36 cephfs-pv-pod1.txt
-rw-r--r--    1 root     root            26 Jan 10 09:39 test.txt

/ # cat /mnt/cephfs/cephfs-pv-pod1.txt
This message write by cephfs-pv-pod1 pod.

OK 一切正常,Pod 容器内能够正确挂载同一 CephFS 并成功读取到 pod1 创建的文件。下边我们在pod2 中写入文件,看下 pod1 中是否能够读取的到吧!

# node0 pod2 中写入文件
$ docker exec -it f8e544e9f497 /bin/sh
/ # vi /mnt/cephfs/cephfs-pv-pod2.txt 
/ # cat /mnt/cephfs/cephfs-pv-pod2.txt 
this message write by cephfs-pv-pod2 pod from node0.

# node1 pod1 读取文件
$ docker exec -it 3cc605bed890 /bin/sh
/ # ls /mnt/cephfs/
cephfs-pv-pod1.txt  cephfs-pv-pod2.txt  test.txt

依旧妥妥没问题哒!再次说明,k8s 集群支持跨节点挂载 CephFS 文件存储。同时 kubernetes 官网 Persistent Volumes 文档 中指出,当静态 PV 都不匹配用户的 PVC 请求时,k8s 集群还支持 Dynamic 动态提供 Volume 给 PVC,不过这种方式需要配置 StorageClasses,查看 Kubernetes 官网 Storage Classes 文档 Provisioner 部分指出支持 Ceph RBD,下一篇我们继续研究 Kubernetes 集群使用 RBD 作为 StorageClass PVC,来实现分布式存储。

参考资料

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值