Skip to main content

以 Serverless Container 的方式在 ACK 使用 JuiceFS

阿里云 ECI(Elastic Container Instance)是阿里云上 Serverless Container 的实现,类似的基于 Serverless Container 的 Kubernetes 产品代表是 AWS 的 Fargate, 以及 Azure AKS 的 ACIFluid 是一个 Kubernetes 原生的分布式数据集编排和加速引擎,在阿里云 ECI 中可以直接安装和使用。本章介绍如何在 ECI 上通过 Fluid 中使用 JuiceFSRuntime。

架构

Fluid 通过自动识别用户应用中使用的 Fluid PVC(PersistentVolumeClaim),将不同缓存 Runtime 的 FUSE 客户端以 Sidecar 的形式注入到 Serverless Pod 中。JuiceFS 客户端以 Sidecar 容器的方式单独为应用容器提供挂载服务,且与应用容器同生命周期。

Fluid-arch

同时,为了给 JuiceFS 提供稳定的数据缓存服务,建议用 ECS 节点搭建「独立缓存集群」,创建适量 ECS 节点用以运行 Worker Pod,为 Sidecar 提供分布式缓存服务。缓存集群以 StatefulSet 的形式运行在 ECS 节点中,提供分布式缓存服务,而 FUSE 客户端以 Sidecar 的方式运行在业务 Pod 中,业务 Pod 则运行在 ECI 节点上。

Fluid-JuiceFS-arch

环境准备

Fluid 需要在 ACK Pro 版集群(Kubernetes 版本不低于 1.18)上使用。如果尚未创建集群,参考文档进行创建。

安装 Fluid

在 ACK 集群中选择「应用 → 云原生 AI 套件」,点击「一键部署」安装云原生 AI 套件。

Fluid-install

安装时选择「Fluid 数据加速」:

Fluid-install-choose

安装虚拟节点

在 Kubernetes 集群中,ECI 应用会被调度到一个虚拟节点,实际运行在一个临时的 ECS 上。这一步我们需要安装虚拟节点,在集群的「组件管理」中,安装「ACK Virtual Node」:

Fluid-vk

使用 JuiceFS

JuiceFS 采用元数据和数据分离的架构,元数据会被存储在元数据服务引擎中,数据会被存储在用户自己选择的对象存储服务中。目前而言,分布式缓存服务仅在 JuiceFS 云服务版提供,因此本章用云服务进行示范。

开始之前,确保你已经创建了 JuiceFS 文件系统,并且已经成功挂载且验证能够正常读写

创建 Secret

在 ACK 集群中创建保密字典,填写 JuiceFS 文件系统的 Token 和对象存储的认证信息。

Fluid-create-secret

创建 JuiceFSRuntime

在「自定义资源」界面,点击「使用 YAML 创建资源」按钮创建 JuiceFSRuntime,并指定副本数及缓存地址等信息。

Fluid-create-runtime

JuiceFSRuntime 示例如下:

apiVersion: data.fluid.io/v1alpha1
kind: JuiceFSRuntime
metadata:
name: jfsdemo
spec:
# 缓存集群的节点数量
replicas: 5
podMetadata:
labels:
# 如果希望将缓存集群也运行在 ECI 中,则添加下方 label
# alibabacloud.com/eci: "true"
tieredstore:
levels:
- mediumtype: MEM
path: /dev/shm
quota: 40Gi
low: "0.1"
volumeType: emptyDir

使用临时存储空间作为 Worker Pod 的缓存盘

Worker Pod 默认使用 tieredstore 中定义的路径作为缓存目录(即 cache-dir 选项),例如在上面的示例中 Worker Pod 的 cache-dir/dev/shm。为了让 Worker Pod 具有更大的缓存存储空间,可以使用ECI 实例的临时存储空间作为 Worker Pod 的缓存盘。

ECI 实例默认提供 30GiB 的临时存储空间,为了扩展临时存储空间的容量,可以通过给 Worker Pod 增加注解(annotation)的方式来实现:

apiVersion: data.fluid.io/v1alpha1
kind: JuiceFSRuntime
metadata:
name: jfsdemo
spec:
# 缓存集群的节点数量
replicas: 5
podMetadata:
labels:
# 在 ECI 上运行缓存集群
alibabacloud.com/eci: "true"
# Worker Pod 配置
worker:
podMetadata:
annotations:
# 设置 ECI 实例的临时存储空间容量
k8s.aliyun.com/eci-extra-ephemeral-storage: "200Gi"
# 挂载选项
options:
# 缓存盘路径
"cache-dir": "/var/jfsCache"
# 缓存盘大小,单位为 MiB。需要与上面设置的临时存储空间容量匹配。
"cache-size": "204800"
# 缓存盘的最小剩余空间占比
"free-space-ratio": "0.1"
tieredstore:
levels:
- mediumtype: MEM
path: /dev/shm
quota: 40Gi
low: "0.1"
volumeType: emptyDir

创建 Dataset

在「自定义资源」界面,使用 YAML 创建 Dataset。在 options 中填入对象存储的 Bucket,在 encryptOptions 中引用 Secret:

Dataset 示例如下:

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: jfsdemo
spec:
mounts:
- name: <vol-name> # JuiceFS Volume 名称
mountPoint: "juicefs:///"
options:
bucket: <bucket>
encryptOptions:
- name: token
valueFrom:
secretKeyRef:
name: jfs-secret
key: token
- name: access-key
valueFrom:
secretKeyRef:
name: jfs-secret
key: access-key
- name: secret-key
valueFrom:
secretKeyRef:
name: jfs-secret
key: secret-key

创建好后,可以在「容器组」页面予以确认,图中的 5 个 Worker 就组成了一个独立缓存集群,为应用侧 JuiceFS 客户端提供缓存服务:

Fluid-worker

缓存加速

在本文的示例中,已提前在 JuiceFS 中准备好 11G 的数据(文件数 11 万,大小 1M)。缓存集群创建好后,我们可以先进行缓存预热,在自定义资源界面,使用 YAML 创建 DataLoad,指定上一步创建的 Dataset:

apiVersion: data.fluid.io/v1alpha1
kind: DataLoad
metadata:
name: jfs-load
spec:
dataset:
name: jfsdemo
namespace: default

「任务」页面的 jfs-load-loader-job 显示完成,即代表缓存集群预热完成。

创建应用

在应用的数据卷中指定与上方 Dataset 同名的 PVC,创建一个 Job,进行简单的数据拷贝测试:

Fluid-app

给 Pod 设置以下两个 label:

    alibabacloud.com/fluid-sidecar-target: eci
alibabacloud.com/eci: "true"

应用创建好后,我们就可以看到 Pod 中有 Webhook 注入的 fluid-fuse 容器,且运行在虚拟节点上:

Fluid-pod

此时该 Pod 已经运行在 ECI 环境中了。运行完毕后,日志中就会显示其拷贝数据的时间:

Fluid-result-with-cache

缓存加速效果

用无缓存加速的配置运行相同任务:

Fluid-result-without-cache

可以看到,在没有分布式缓存的情况下,拷贝相同的数据时间为 13m19.096s。对比上方有分布式缓存加速时,拷贝时间缩短到了 1m11.16s,速度提升了 13 倍。