Skip to main content

运行其他 JuiceFS 应用

严格来说,本章内容与 JuiceFS CSI 驱动没有关联,而是通用的 Kubernetes 应用,因此下方介绍的各种部署方式,也完全可以脱离 CSI 驱动、独立使用。比方说:

  • juicefs sync 在 Kubernetes 中定时同步数据
  • 在 Kubernetes 中运行 juicefs webdav 或者 juicefs gateway(S3 网关)
  • 私有部署 在 Kubernetes 中部署分布式缓存组

JuiceFS 客户端还有诸多强大的其他功能,我们无法囊括所有的用例,因此如果你有更多需求希望能获得部署示范,也应当可以参考下方的案例,自行开发属于你的场景的部署配置。如果本章内容帮助你撰写了新的场景的部署配置,欢迎给文档贡献内容,将你的示范补充到这里。

juicefs sync 定时同步数据

juicefs sync 是非常好用的数据迁移方案,你可以用 CronJob 搭建定时同步机制。

下方示范以企业版为例,并且假定了用户需要与 JuiceFS 文件系统进行交互,因此需要在容器中运行 auth 命令,如果不需要的话,可以对多余配置进行裁剪。

apiVersion: batch/v1
kind: CronJob
metadata:
# 名称、命名空间可自定义
name: juicefs-sync
namespace: default
spec:
# 根据实际需求更改
schedule: "5 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: Never
containers:
- name: juicefs-sync
command:
- sh
- -c
- |
# 下面的 shell 代码仅在私有部署需要,作用是将 envs 这一 JSON 进行展开,将键值设置为环境变量
for keyval in $(echo $ENVS | sed -e 's/": "/=/g' -e 's/{"//g' -e 's/", "/ /g' -e 's/"}//g' ); do
echo "export $keyval"
eval export $keyval
done

# 如果 sync 命令需要直接读取或写入 JuiceFS 文件系统,推荐使用 jfs:// 协议头
# 此方式需要提前认证、获取配置文件
/usr/bin/juicefs auth --token=${TOKEN} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${VOL_NAME}

# 具体的 sync 命令需要根据实际需求更改
# 参考文档:https://juicefs.com/docs/zh/cloud/guide/sync/
/usr/bin/juicefs sync oss://${ACCESS_KEY}:${SECRET_KEY}@myjfs-bucket.oss-cn-hongkong.aliyuncs.com/chaos-ee-test/juicefs_uuid jfs://$VOL_NAME
env:
# 存放文件系统认证信息的 Secret,必须在同一个命名空间下
# 参考文档:https://juicefs.com/docs/zh/csi/guide/pv#cloud-service
- name: VOL_NAME
valueFrom:
secretKeyRef:
key: name
name: juicefs-secret
- name: ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: juicefs-secret
- name: SECRET_KEY
valueFrom:
secretKeyRef:
key: secret-key
name: juicefs-secret
- name: TOKEN
valueFrom:
secretKeyRef:
key: token
name: juicefs-secret
# 仅在私有部署需要
- name: ENVS
valueFrom:
secretKeyRef:
key: envs
name: juicefs-secret
# 使用 Mount Pod 的容器镜像
# 参考文档:https://juicefs.com/docs/zh/csi/guide/custom-image
image: juicedata/mount:ee-5.0.14-a38b96d
# 按照实际情况调整资源请求和约束
# 参考文档:https://juicefs.com/docs/zh/csi/guide/resource-optimization#mount-pod-resources
resources:
requests:
memory: 500Mi

部署分布式缓存集群

为了在 Kubernetes 集群部署一个稳定的缓存集群,可以参考以下示范,在集群内指定的节点挂载 JuiceFS 客户端,形成一个稳定的缓存组。

下方介绍两种部署方式,分别是 StatefulSet 和 DaemonSet。功能上并无区别,但是在升级或修改配置的时候,StatefulSet 默认会按照从低到高位依次重启,这种方式对缓存组消费端的服务冲击更小。而 DaemonSet 方式则会根据其 updateStrategy 设置来执行更新,如果规模巨大,需要仔细设置更新策略,避免冲击服务。

除此之外,两种部署方式没有显著不同,根据喜好选择即可。

DaemonSet 方式

apiVersion: apps/v1
kind: DaemonSet
metadata:
# 名称、命名空间可自定义
name: juicefs-cache-group
namespace: default
spec:
selector:
matchLabels:
app: juicefs-cache-group
juicefs-role: cache
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: juicefs-cache-group
juicefs-role: cache
spec:
# 使用 hostNetwork,让 Pod 以固定 IP 运行,避免容器重建更换 IP,导致缓存数据失效
hostNetwork: true
containers:
- name: juicefs-cache
command:
- sh
- -c
- |
# 下面的 shell 代码仅在私有部署需要,作用是将 envs 这一 JSON 进行展开,将键值设置为环境变量
for keyval in $(echo $ENVS | sed -e 's/": "/=/g' -e 's/{"//g' -e 's/", "/ /g' -e 's/"}//g' ); do
echo "export $keyval"
eval export $keyval
done

# 认证和挂载,所有环境变量均引用包含着文件系统认证信息的 Kubernetes Secret
# 参考文档:https://juicefs.com/docs/zh/cloud/getting_started#create-file-system
/usr/bin/juicefs auth --token=${TOKEN} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${VOL_NAME}

# 由于在容器中常驻,必须用 --foreground 模式运行,其它挂载选项(特别是 --cache-group)按照实际情况调整
# 参考文档:https://juicefs.com/docs/zh/cloud/reference/commands_reference#mount
/usr/bin/juicefs mount $VOL_NAME /mnt/jfs --foreground --cache-dir=/data/jfsCache --cache-size=512000 --cache-group=jfscache
env:
# 存放文件系统认证信息的 Secret,必须和该 StatefulSet 在同一个命名空间下
# 参考文档:https://juicefs.com/docs/zh/csi/guide/pv#cloud-service
- name: VOL_NAME
valueFrom:
secretKeyRef:
key: name
name: juicefs-secret
- name: ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: juicefs-secret
- name: SECRET_KEY
valueFrom:
secretKeyRef:
key: secret-key
name: juicefs-secret
- name: TOKEN
valueFrom:
secretKeyRef:
key: token
name: juicefs-secret
# 仅在私有部署需要
- name: ENVS
valueFrom:
secretKeyRef:
key: envs
name: juicefs-secret
# 使用 Mount Pod 的容器镜像
# 参考文档:https://juicefs.com/docs/zh/csi/guide/custom-image
image: juicedata/mount:ee-5.0.2-69f82b3
lifecycle:
# 容器退出时卸载文件系统
preStop:
exec:
command:
- sh
- -c
- umount /mnt/jfs
# 按照实际情况调整资源请求和约束
# 参考文档:https://juicefs.com/docs/zh/csi/guide/resource-optimization#mount-pod-resources
resources:
requests:
memory: 500Mi
# 挂载文件系统必须启用的权限
securityContext:
privileged: true
volumeMounts:
- mountPath: /data/jfsCache
name: cache-dir
- mountPath: /root/.juicefs
name: jfs-root-dir
volumes:
# 调整缓存目录的路径,如有多个缓存目录需要定义多个 volume
# 参考文档:https://juicefs.com/docs/zh/cloud/guide/cache#client-read-cache
- name: cache-dir
hostPath:
path: /data/jfsCache
type: DirectoryOrCreate
- name: jfs-root-dir
emptyDir: {}

StatefulSet 方式

apiVersion: apps/v1
kind: StatefulSet
metadata:
# 名称、命名空间可自定义
name: juicefs-cache-group
namespace: default
spec:
# 缓存组客户端数量
replicas: 1
podManagementPolicy: Parallel
selector:
matchLabels:
app: juicefs-cache-group
juicefs-role: cache
serviceName: juicefs-cache-group
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
template:
metadata:
labels:
app: juicefs-cache-group
juicefs-role: cache
spec:
# 一个 Kubernetes 节点上只运行一个缓存组客户端
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: juicefs-role
operator: In
values:
- cache
topologyKey: kubernetes.io/hostname
# 使用 hostNetwork,让 Pod 以固定 IP 运行,避免容器重建更换 IP,导致缓存数据失效
hostNetwork: true
containers:
- name: juicefs-cache
command:
- sh
- -c
- |
# 下面的 shell 代码仅在私有部署需要,作用是将 envs 这一 JSON 进行展开,将键值设置为环境变量
for keyval in $(echo $ENVS | sed -e 's/": "/=/g' -e 's/{"//g' -e 's/", "/ /g' -e 's/"}//g' ); do
echo "export $keyval"
eval export $keyval
done

# 认证和挂载,所有环境变量均引用包含着文件系统认证信息的 Kubernetes Secret
# 参考文档:https://juicefs.com/docs/zh/cloud/getting_started#create-file-system
/usr/bin/juicefs auth --token=${TOKEN} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${VOL_NAME}

# 由于在容器中常驻,必须用 --foreground 模式运行,其它挂载选项(特别是 --cache-group)按照实际情况调整
# 参考文档:https://juicefs.com/docs/zh/cloud/reference/commands_reference#mount
/usr/bin/juicefs mount $VOL_NAME /mnt/jfs --foreground --cache-dir=/data/jfsCache --cache-size=512000 --cache-group=jfscache
env:
# 存放文件系统认证信息的 Secret,必须和该 StatefulSet 在同一个命名空间下
# 参考文档:https://juicefs.com/docs/zh/csi/guide/pv#cloud-service
- name: VOL_NAME
valueFrom:
secretKeyRef:
key: name
name: juicefs-secret
- name: ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: juicefs-secret
- name: SECRET_KEY
valueFrom:
secretKeyRef:
key: secret-key
name: juicefs-secret
- name: TOKEN
valueFrom:
secretKeyRef:
key: token
name: juicefs-secret
# 仅在私有部署需要
- name: ENVS
valueFrom:
secretKeyRef:
key: envs
name: juicefs-secret
# 使用 Mount Pod 的容器镜像
# 参考文档:https://juicefs.com/docs/zh/csi/guide/custom-image
image: juicedata/mount:ee-5.0.2-69f82b3
lifecycle:
# 容器退出时卸载文件系统
preStop:
exec:
command:
- sh
- -c
- umount /mnt/jfs
# 按照实际情况调整资源请求和约束
# 参考文档:https://juicefs.com/docs/zh/csi/guide/resource-optimization#mount-pod-resources
resources:
requests:
memory: 500Mi
# 挂载文件系统必须启用的权限
securityContext:
privileged: true
volumeMounts:
- mountPath: /data/jfsCache
name: cache-dir
- mountPath: /root/.juicefs
name: jfs-root-dir
volumes:
# 调整缓存目录的路径,如有多个缓存目录需要定义多个 volume
# 参考文档:https://juicefs.com/docs/zh/cloud/guide/cache#client-read-cache
- name: cache-dir
hostPath:
path: /data/jfsCache
type: DirectoryOrCreate
- name: jfs-root-dir
emptyDir: {}

使用缓存组

上方示范便是在集群中启动了 JuiceFS 缓存集群,其缓存组名为 jfscache,那么为了让应用程序的 JuiceFS 客户端使用该缓存集群,需要让他们一并加入这个缓存组,并额外添加 --no-sharing 这个挂载参数,这样一来,应用程序的 JuiceFS 客户端虽然加入了缓存组,但却不参与缓存数据的构建,避免了客户端频繁创建、销毁所导致的缓存数据不稳定。

以动态配置为例,按照下方示范修改挂载参数即可,关于在 mountOptions 调整挂载配置,详见「挂载参数」

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: juicefs-sc
provisioner: csi.juicefs.com
parameters:
csi.storage.k8s.io/provisioner-secret-name: juicefs-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/node-publish-secret-name: juicefs-secret
csi.storage.k8s.io/node-publish-secret-namespace: default
mountOptions:
...
- cache-group=jfscache
- no-sharing

运行 JuiceFS S3 网关

建议用 Deployment 运行 S3 网关,Deployment 的写法参考下方示范。你需要自行撰写 Service 和 Ingress 来对外暴露服务。

apiVersion: apps/v1
kind: Deployment
metadata:
# 名称、命名空间可自定义
name: juicefs-gateway
namespace: default
spec:
# 网关客户端数量
replicas: 1
selector:
matchLabels:
app: juicefs-gateway
juicefs-role: gateway
template:
metadata:
labels:
app: juicefs-gateway
juicefs-role: gateway
spec:
containers:
- name: juicefs-gateway
command:
- sh
- -c
- |
# 下面的 shell 代码仅在私有部署需要,作用是将 envs 这一 JSON 进行展开,将键值设置为环境变量
for keyval in $(echo $ENVS | sed -e 's/": "/=/g' -e 's/{"//g' -e 's/", "/ /g' -e 's/"}//g' ); do
echo "export $keyval"
eval export $keyval
done

# 认证和挂载,所有环境变量均引用包含着文件系统认证信息的 Kubernetes Secret
# 参考文档:https://juicefs.com/docs/zh/cloud/getting_started#create-file-system
/usr/bin/juicefs auth --token=${TOKEN} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${VOL_NAME}

# 为了方便管理,将 MinIO 的认证信息直接设置为对象存储 AKSK
export MINIO_ROOT_USER=${ACCESS_KEY}
export MINIO_ROOT_PASSWORD=${SECRET_KEY}

# 参考文档:https://juicefs.com/docs/zh/cloud/reference/commands_reference#gateway
/usr/bin/juicefs gateway $VOL_NAME 0.0.0.0:9000 --cache-dir=/data/jfsCache
env:
# 存放文件系统认证信息的 Secret,必须和该 Deployment 在同一个命名空间下
# 参考文档:https://juicefs.com/docs/zh/csi/guide/pv#cloud-service
- name: VOL_NAME
valueFrom:
secretKeyRef:
key: name
name: juicefs-secret
- name: ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: juicefs-secret
- name: SECRET_KEY
valueFrom:
secretKeyRef:
key: secret-key
name: juicefs-secret
- name: TOKEN
valueFrom:
secretKeyRef:
key: token
name: juicefs-secret
# 仅在私有部署需要,云服务环境需要删掉下方环境变量
- name: ENVS
valueFrom:
secretKeyRef:
key: envs
name: juicefs-secret
# 使用 Mount Pod 的容器镜像
# 参考文档:https://juicefs.com/docs/zh/csi/guide/custom-image
ports:
- containerPort: 9000
image: juicedata/mount:ee-5.0.14-a38b96d
# 按照实际情况调整资源请求和约束
# 参考文档:https://juicefs.com/docs/zh/csi/guide/resource-optimization#mount-pod-resources
resources:
requests:
memory: 500Mi
volumeMounts:
- mountPath: /data/jfsCache
name: cache-dir
- mountPath: /root/.juicefs
name: jfs-root-dir
volumes:
# 调整缓存目录的路径,如有多个缓存目录需要定义多个 volume
# 参考文档:https://juicefs.com/docs/zh/cloud/guide/cache#client-read-cache
- name: cache-dir
hostPath:
path: /data/jfsCache
type: DirectoryOrCreate
- name: jfs-root-dir
emptyDir: {}

运行 JuiceFS WebDAV

对于企业版,建议用 Deployment 运行 WebDAV,的写法参考下方示范。你需要自行撰写 Service 和 Ingress 来对外暴露服务。

apiVersion: apps/v1
kind: Deployment
metadata:
# 名称、命名空间可自定义
name: juicefs-webdav
namespace: default
spec:
# 缓存组客户端数量
replicas: 1
selector:
matchLabels:
app: juicefs-webdav
juicefs-role: webdav
template:
metadata:
labels:
app: juicefs-webdav
juicefs-role: webdav
spec:
containers:
- name: juicefs-webdav
command:
- sh
- -c
- |
# 下面的 shell 代码仅在私有部署需要,作用是将 envs 这一 JSON 进行展开,将键值设置为环境变量
for keyval in $(echo $ENVS | sed -e 's/": "/=/g' -e 's/{"//g' -e 's/", "/ /g' -e 's/"}//g' ); do
echo "export $keyval"
eval export $keyval
done

# 认证和挂载,所有环境变量均引用包含着文件系统认证信息的 Kubernetes Secret
# 参考文档:https://juicefs.com/docs/zh/cloud/getting_started#create-file-system
/usr/bin/juicefs auth --token=${TOKEN} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${VOL_NAME}

# 设置用户名和密码
export WEBDAV_USER=root
export WEBDAV_PASSWORD=1234

# 参考文档:https://juicefs.com/docs/zh/cloud/reference/commands_reference#webdav
/usr/bin/juicefs webdav $VOL_NAME 0.0.0.0:9007 --cache-dir=/data/jfsCache
env:
# 存放文件系统认证信息的 Secret,必须和该 Deployment 在同一个命名空间下
# 参考文档:https://juicefs.com/docs/zh/csi/guide/pv#cloud-service
- name: VOL_NAME
valueFrom:
secretKeyRef:
key: name
name: juicefs-secret
- name: ACCESS_KEY
valueFrom:
secretKeyRef:
key: access-key
name: juicefs-secret
- name: SECRET_KEY
valueFrom:
secretKeyRef:
key: secret-key
name: juicefs-secret
- name: TOKEN
valueFrom:
secretKeyRef:
key: token
name: juicefs-secret
# 仅在私有部署需要
- name: ENVS
valueFrom:
secretKeyRef:
key: envs
name: juicefs-secret
# 使用 Mount Pod 的容器镜像
# 参考文档:https://juicefs.com/docs/zh/csi/guide/custom-image
ports:
- containerPort: 9007
image: juicedata/mount:ee-5.0.14-a38b96d
# 按照实际情况调整资源请求和约束
# 参考文档:https://juicefs.com/docs/zh/csi/guide/resource-optimization#mount-pod-resources
resources:
requests:
memory: 500Mi
volumeMounts:
- mountPath: /data/jfsCache
name: cache-dir
- mountPath: /root/.juicefs
name: jfs-root-dir
volumes:
# 调整缓存目录的路径,如有多个缓存目录需要定义多个 volume
# 参考文档:https://juicefs.com/docs/zh/cloud/guide/cache#client-read-cache
- name: cache-dir
hostPath:
path: /data/jfsCache
type: DirectoryOrCreate
- name: jfs-root-dir
emptyDir: {}