以 Serverless Container 的方式在 ACK 使用 JuiceFS
阿里云 ECI(Elastic Container Instance)是阿里云上 Serverless Container 的实现,类似的基于 Serverless Container 的 Kubernetes 产品代表是 AWS 的 Fargate, 以及 Azure AKS 的 ACI。Fluid 是一个 Kubernetes 原生的分布式数据集编排和加速引擎,在阿里云 ECI 中可以直接安装和使用。本章介绍如何在 ECI 上通过 Fluid 中使用 JuiceFSRuntime。
架构
Fluid 通过自动识别用户应用中使用的 Fluid PVC(PersistentVolumeClaim),将不同缓存 Runtime 的 FUSE 客户端以 Sidecar 的形式注入到 Serverless Pod 中。JuiceFS 客户端以 Sidecar 容器的方式单独为应用容器提供挂载服务,且与应用容器同生命周期。
同时,为了给 JuiceFS 提供稳定的数据缓存服务,建议用 ECS 节点搭建「独立缓存集群」,创建适量 ECS 节点用以运行 Worker Pod,为 Sidecar 提供分布式缓存服务。缓存集群以 StatefulSet 的形式运行在 ECS 节点中,提供分布式缓存服务,而 FUSE 客户端以 Sidecar 的方式运行在业务 Pod 中,业务 Pod 则运行在 ECI 节点上。
环境准备
Fluid 需要在 ACK Pro 版集群(Kubernetes 版本不低于 1.18)上使用。如果尚未创建集群,参考文档进行创建。
安装 Fluid
在 ACK 集群中选择「应用 → 云原生 AI 套件」,点击「一键部署」安装云原生 AI 套件。
安装时选择「Fluid 数据加速」:
安装虚拟节点
在 Kubernetes 集群中,ECI 应用会被调度到一个虚拟节点,实际运行在一个临时的 ECS 上。这一步我们需要安装虚拟节点,在集群的「组件管理」中,安装「ACK Virtual Node」:
使用 JuiceFS
JuiceFS 采用元数据和数据分离的架构,元数据会被存储在元数据服务引擎中,数据会被存储在用户自己选择的对象存储服务中。目前而言,分布式缓存服务仅在 JuiceFS 云服务版提供,因此本章用云服务进行示范。
开始之前,确保你已经创建了 JuiceFS 文件系统,并且已经成功挂载且验证能够正常读写。
创建 Secret
在 ACK 集群中创建保密字典,填写 JuiceFS 文件系统的 Token 和对象存储的认证信息。
创建 JuiceFSRuntime
在「自定义资源」界面,点击「使用 YAML 创建资源」按钮创建 JuiceFSRuntime,并指定副本数及缓存地址等信息。
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 客户端提供缓存服务:
缓存加速
在本文的示例中,已提前在 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,进行简单的数据拷贝测试:
给 Pod 设置以下两个 label:
alibabacloud.com/fluid-sidecar-target: eci
alibabacloud.com/eci: "true"
应用创建好后,我们就可以看到 Pod 中有 Webhook 注入的 fluid-fuse
容器,且运行在虚拟节点上:
此时该 Pod 已经运行在 ECI 环境中了。运行完毕后,日志中就会显示其拷贝数据的时间:
缓存加速效果
用无缓存加速的配置运行相同任务:
可以看到,在没有分布式缓存的情况下,拷贝相同的数据时间为 13m19.096s。对比上方有分布式缓存加速时,拷贝时间缩短到了 1m11.16s,速度提升了 13 倍。