控制台指南

最佳实践

开发者指南

API 文档

SDK 文档

填写文档满意度调查问卷,赢取缤纷好礼> HOT

使用 placement 在同个集群上部署多个 dataset

最近更新时间:2022-06-10 10:31:13

通过 GooseFS 和 Fuse,Fluid 为用户提供了一种更为简单的文件访问接口,使得任意运行在 Kubernetes 集群上的程序能够像访问本地文件一样轻松访问存储在远程文件系统中的文件。Fluid 针对数据集进行全生命周期的管理和隔离,尤其对于短生命周期应用(例如数据分析任务、机器学习任务),用户可以在集群中大规模部署。

前提条件

在运行该示例之前,请参考 安装 文档完成安装,并检查 Fluid 各组件正常运行:

$ kubectl get pod -n fluid-system
NAME                                  READY   STATUS    RESTARTS   AGE
goosefsruntime-controller-5b64fdbbb-84pc6   1/1     Running   0          8h
csi-nodeplugin-fluid-fwgjh                  2/2     Running   0          8h
csi-nodeplugin-fluid-ll8bq                  2/2     Running   0          8h
dataset-controller-5b7848dbbb-n44dj         1/1     Running   0          8h

通常来说,您会看到一个名为 dataset-controller 的 Pod、一个名为 goosefsruntime-controller的 Pod 和多个名为 csi-nodeplugin 的 Pod 正在运行。其中 csi-nodeplugin 这些 Pod 的数量取决于您的 Kubernetes 集群中结点的数量。

运行示例

对某个节点打标签

$ kubectl  label node 192.168.0.199 fluid=multi-dataset

说明:

在接下来的步骤中,我们将使用 NodeSelector 来管理 Dataset 调度的节点,这里仅做测试使用。

查看待创建的 Dataset 资源对象

  • dataset.yaml
    apiVersion: data.fluid.io/v1alpha1
    kind: Dataset
    metadata:
    name: hbase
    spec:
    mounts:
    - mountPoint: https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/stable/
    name: hbase
    nodeAffinity:
    required:
    nodeSelectorTerms:
    - matchExpressions:
    - key: fluid
    operator: In
    values:
    - "multi-dataset"
    placement: "Shared" // 设置为 Exclusive 或者为空则为独占节点数据集
  • dataset1.yaml
    apiVersion: data.fluid.io/v1alpha1
    kind: Dataset
    metadata:
    name: spark
    spec:
    mounts:
    - mountPoint: https://mirrors.bit.edu.cn/apache/spark/
    name: spark
    nodeAffinity:
    required:
    nodeSelectorTerms:
    - matchExpressions:
    - key: fluid
    operator: In
    values:
    - "multi-dataset"
    placement: "Shared"
说明:

为了方便用户进行测试,mountPoint 这里使用的是 Web UFS,使用 COS 作为 UFS 可见 使用 GooseFS 挂载 COS(COSN)

创建 Dataset 资源对象

$ kubectl apply -f dataset.yaml
dataset.data.fluid.io/hbase created
$ kubectl apply -f dataset1.yaml
dataset.data.fluid.io/spark created

查看 Dataset 资源对象状态

$ kubectl get dataset
NAME    UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE      AGE
hbase                                                                  NotBound   6s
spark                                                                  NotBound   4s
如上所示,status中的phase属性值为NotBound,这意味着该Dataset资源对象目前还未与任何GooseFSRuntime资源对象绑定,接下来,我们将创建一个GooseFSRuntime资源对象。

查看待创建的 GooseFSRuntime 资源对象

  • runtime.yaml
    apiVersion: data.fluid.io/v1alpha1
    kind: GooseFSRuntime
    metadata:
    name: hbase
    spec:
    replicas: 1
    tieredstore:
    levels:
    - mediumtype: SSD
    path: /mnt/disk1
    quota: 2G
    high: "0.8"
    low: "0.7"
  • runtime-1.yaml
    apiVersion: data.fluid.io/v1alpha1
    kind: GooseFSRuntime
    metadata:
    name: spark
    spec:
    replicas: 1
    tieredstore:
    levels:
    - mediumtype: SSD
    path: /mnt/disk2/
    quota: 4G
    high: "0.8"
    low: "0.7"

创建 GooseFSRuntime 资源对象

$ kubectl create -f runtime.yaml
goosefsruntime.data.fluid.io/hbase created


# 等待 Dataset hbase 全部组件 Running 
$ kubectl get pod -o wide | grep hbase
NAME                              READY   STATUS    RESTARTS   AGE   IP              NODE                       NOMINATED NODE   READINESS GATES
hbase-fuse-jl2g2           1/1     Running   0          2m24s   192.168.0.199   192.168.0.199   <none>           <none>
hbase-master-0             2/2     Running   0          2m55s   192.168.0.200   192.168.0.200   <none>           <none>
hbase-worker-g89p8         2/2     Running   0          2m24s   192.168.0.199   192.168.0.199   <none>           <none>

$ kubectl create -f runtime1.yaml
goosefsruntime.data.fluid.io/spark created

检查 GooseFSRuntime 资源对象是否已经创建

$ kubectl get goosefsruntime
NAME    MASTER PHASE   WORKER PHASE   FUSE PHASE   AGE
hbase   Ready          Ready          Ready        2m14s
spark   Ready          Ready          Ready        58s

GooseFSRuntime是另一个 Fluid 定义的 CRD。一个 GooseFSRuntime 资源对象描述了在 Kubernetes 集群中运行一个 GooseFS 实例所需要的配置信息。

等待一段时间,让 GooseFSRuntime 资源对象中的各个组件得以顺利启动,您会看到类似以下状态:

$ kubectl get pod -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP              NODE                       NOMINATED NODE   READINESS GATES
hbase-fuse-jl2g2     1/1     Running   0          2m24s   192.168.0.199   192.168.0.199   <none>           <none>
hbase-master-0       2/2     Running   0          2m55s   192.168.0.200   192.168.0.200   <none>           <none>
hbase-worker-g89p8   2/2     Running   0          2m24s   192.168.0.199   192.168.0.199   <none>           <none>
spark-fuse-5z49p     1/1     Running   0          19s     192.168.0.199   192.168.0.199   <none>           <none>
spark-master-0       2/2     Running   0          50s     192.168.0.200   192.168.0.200   <none>           <none>
spark-worker-96ksn   2/2     Running   0          19s     192.168.0.199   192.168.0.199   <none>           <none>
注意上面不同的 Dataset 的 worker 和 fuse 组件可以正常的调度到相同的节点 192.168.0.199

再次查看 Dataset 资源对象状态

$ kubectl get dataset 
NAME    UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
hbase   443.89MiB        0.00B    2.00GiB          0.0%                Bound   11m
spark   1.92GiB          0.00B    4.00GiB          0.0%                Bound   9m38s

因为已经与一个成功启动的 GooseFSRuntime 绑定,该 Dataset 资源对象的状态得到了更新,此时 PHASE 属性值已经变为 Bound 状态。通过上述命令可以获知有关资源对象的基本信息

查看 GooseFSRuntime 状态

$ kubectl get goosefsruntime -o wide
NAME    READY MASTERS   DESIRED MASTERS   MASTER PHASE   READY WORKERS   DESIRED WORKERS   WORKER PHASE   READY FUSES   DESIRED FUSES   FUSE PHASE   AGE
hbase   1               1                 Ready          1               1                 Ready          1             1               Ready        11m
spark   1               1                 Ready          1               1                 Ready          1             1               Ready        9m52s

说明:

GooseFSRuntime 资源对象的 status 中包含了更多更详细的信息。

查看与远程文件关联的 PersistentVolume 以及 PersistentVolumeClaim

$ kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM           STORAGECLASS   REASON   AGE
hbase   100Gi      RWX            Retain           Bound    default/hbase                           4m55s
spark   100Gi      RWX            Retain           Bound    default/spark                           51s

$ kubectl get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
hbase   Bound    hbase    100Gi      RWX                           4m57s
spark   Bound    spark    100Gi      RWX                           53s

Dataset资源对象准备完成后(即与 GooseFS 实例绑定后),与该资源对象关联的 PV,PVC 已经由 Fluid 生成,应用可以通过该 PVC 完成远程文件在 Pod 中的挂载,并通过挂载目录实现远程文件访问。

远程文件访问

查看待创建的应用

  • nginx.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: nginx-hbase
    spec:
    containers:
    - name: nginx
    image: nginx
    volumeMounts:
    - mountPath: /data
    name: hbase-vol
    volumes:
    - name: hbase-vol
    persistentVolumeClaim:
    claimName: hbase
    nodeName: 192.168.0.199
  • nginx1.yaml
    apiVersion: v1
    kind: Pod
    metadata:
    name: nginx-spark
    spec:
    containers:
    - name: nginx
    image: nginx
    volumeMounts:
    - mountPath: /data
    name: hbase-vol
    volumes:
    - name: hbase-vol
    persistentVolumeClaim:
    claimName: spark
    nodeName: 192.168.0.199

启动应用进行远程文件访问

$ kubectl create -f nginx.yaml
$ kubectl create -f nginx1.yaml

登录 Nginx hbase Pod:

$ kubectl exec -it nginx-hbase -- bash

查看远程文件挂载情况:

$ ls -lh /data/hbase
total 444M
-r--r----- 1 root root 193K Sep 16 00:53 CHANGES.md
-r--r----- 1 root root 112K Sep 16 00:53 RELEASENOTES.md
-r--r----- 1 root root  26K Sep 16 00:53 api_compare_2.2.6RC2_to_2.2.5.html
-r--r----- 1 root root 211M Sep 16 00:53 hbase-2.2.6-bin.tar.gz
-r--r----- 1 root root 200M Sep 16 00:53 hbase-2.2.6-client-bin.tar.gz
-r--r----- 1 root root  34M Sep 16 00:53 hbase-2.2.6-src.tar.gz

登录 Nginx spark Pod:

$ kubectl exec -it nginx-spark -- bash

查看远程文件挂载情况:

$ ls -lh /data/spark/
total 1.0K
dr--r----- 1 root root 7 Oct 22 12:21 spark-2.4.7
dr--r----- 1 root root 7 Oct 22 12:21 spark-3.0.1
$ du -h /data/spark/
999M    /data/spark/spark-3.0.1
968M    /data/spark/spark-2.4.7
2.0G    /data/spark/

登出 Nginx Pod:

$ exit

正如您所见,WebUFS 上所存储的全部文件像本地文件一样无区别地存在于某个 Pod 中,并且可以被该 Pod 十分方便地访问。

远程文件访问加速

为了演示在访问远程文件时,您能获得多大的加速效果,我们提供了一个测试作业的样例:

查看待创建的测试作业

  • app.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: fluid-copy-test-hbase
    spec:
    template:
    spec:
    restartPolicy: OnFailure
    containers:
    - name: busybox
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "set -x; time cp -r /data/hbase ./"]
    volumeMounts:
    - mountPath: /data
    name: hbase-vol
    volumes:
    - name: hbase-vol
    persistentVolumeClaim:
    claimName: hbase
    nodeName: 192.168.0.199
  • app1.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: fluid-copy-test-spark
    spec:
    template:
    spec:
    restartPolicy: OnFailure
    containers:
    - name: busybox
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "set -x; time cp -r /data/spark ./"]
    volumeMounts:
    - mountPath: /data
    name: spark-vol
    volumes:
    - name: spark-vol
    persistentVolumeClaim:
    claimName: spark
    nodeName: 192.168.0.199

启动测试作业

$ kubectl create -f app.yaml
job.batch/fluid-copy-test-hbase created
$ kubectl create -f app1.yaml
job.batch/fluid-copy-test-spark created

hbase 任务程序会执行 time cp -r /data/hbase ./ 的 shell 命令,其中 /data/hbase 是远程文件在 Pod 中挂载的位置,该命令完成后会在终端显示命令执行的时长。

spark 任务程序会执行 time cp -r /data/spark ./ 的 shell 命令,其中 /data/spark 是远程文件在 Pod 中挂载的位置,该命令完成后会在终端显示命令执行的时长。

等待一段时间,待该作业运行完成,作业的运行状态可通过以下命令查看:

$ kubectl get pod -o wide | grep copy 
fluid-copy-test-hbase-r8gxp   0/1     Completed   0          4m16s   172.29.0.135    192.168.0.199   <none>           <none>
fluid-copy-test-spark-54q8m   0/1     Completed   0          4m14s   172.29.0.136    192.168.0.199   <none>           <none>

如果看到如上结果,则说明该作业已经运行完成。

注意:

fluid-copy-test-hbase-r8gxp 中的 r8gxp 为作业生成的标识,在您的环境中,这个标识可能不同,接下来的命令中涉及该标识的地方请以您的环境为准。

查看测试作业完成时间

$ kubectl  logs fluid-copy-test-hbase-r8gxp
+ time cp -r /data/hbase ./
real    3m 34.08s
user    0m 0.00s
sys     0m 1.24s
$ kubectl  logs fluid-copy-test-spark-54q8m
+ time cp -r /data/spark ./
real    3m 25.47s
user    0m 0.00s
sys     0m 5.48s

可见,第一次远程文件读取 hbase 耗费了接近3分34秒的时间,读取 spark 耗费接近3分25秒的时间。

查看 Dataset 资源对象状态

$ kubectl get dataset
NAME    UFS TOTAL SIZE   CACHED      CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
hbase   443.89MiB        443.89MiB   2.00GiB          100.0%              Bound   30m
spark   1.92GiB          1.92GiB     4.00GiB          100.0%              Bound   28m

现在,所有远程文件都已经被缓存在了 GooseFS 中。

再次启动测试作业

$ kubectl delete -f app.yaml
$ kubectl create -f app.yaml
$ kubectl delete -f app1.yaml
$ kubectl create -f app1.yaml

由于远程文件已经被缓存,此次测试作业能够迅速完成:

$ kubectl get pod -o wide| grep fluid
fluid-copy-test-hbase-sf5md   0/1     Completed   0          53s   172.29.0.137    192.168.0.199   <none>           <none>
fluid-copy-test-spark-fwp57   0/1     Completed   0          51s   172.29.0.138    192.168.0.199   <none>           <none>

$ kubectl  logs fluid-copy-test-hbase-sf5md
+ time cp -r /data/hbase ./
real    0m 0.36s
user    0m 0.00s
sys     0m 0.36s
$ kubectl  logs fluid-copy-test-spark-fwp57
+ time cp -r /data/spark ./
real    0m 1.57s
user    0m 0.00s
sys     0m 1.57s

同样的文件访问操作,hbase 仅耗费了0.36秒,spark仅耗费了1.57秒。

这种大幅度的加速效果归因于 GooseFS 所提供的强大的缓存能力,这种缓存能力意味着,只要您访问某个远程文件一次,该文件就会被缓存在 GooseFS 中,您的所有接下来的重复访问都不再需要读取远程文件,而是从 GooseFS 中直接获取数据。

环境清理

$ kubectl delete -f .
$ kubectl label node 192.168.0.199 fluid-

目录