在 Kubernetes 中使用 JuiceFS
JuiceFS 可以作为存储卷(Volume
)挂载到 Kubernetes Pod
中作为持久化存储。
相比于相比普通云盘(如 AWS EBS,阿里云弹性云盘等),JuiceFS 支持更多适合云环境使用的特性:
- 支持
ReadWriteMany
访问模式,可以同时挂载到多个 Pod 作为共享存储并发读写 - 支持
ReadOnlyMany
访问模式,可以同时以只读模式挂载到多个 Pod - 文件系统挂载不受可用区限制,在单可用区失效情况下,支持工作负载的跨可用区迁移,实现高可用
- 弹性容量高达 10Pi,无需进行扩容操作
- 支持快速拷贝,生成数据副本用于离线调测(内测中)
在 Kubernetes 中使用 JuiceFS 可以通过以下三种方式:
- CSI (推荐用于 Kubernetes v1.13 及以上版本)
- flexVolume (适用于 Kubernetes v1.2 及以上版本)
- hostPath (可用于所有 Kubernetes 版本)
针对不同的使用场景,可以选择合适的集成方式。
通过 CSI 存储卷
JuiceFS CSI 驱动 实现了 容器存储接口(CSI) 规范,用于在容器编排器中管理 JuiceFS 文件系统生命周期。
更多 JuiceFS CSI 驱动的文档请参考:JuiceFS CSI 驱动文档 。
在 Kubernetes v1.13 中, CSI 的支持已被提升为 GA 。CSI 支持在 Kubernetes v1.9 里作为 alpha 特性引入,在 Kubernetes v1.10 中提升为 beta。 如果要在更早的版本里使用 JuiceFS,可以考虑通过 flexVolume
或 hostPath
挂载。
通过 flexVolume 存储卷
脚本 juicefs
同时也是 Flex 卷的驱动,支持 init
, mount
and unmount
操作。
你需要把 juicefs
放到所有主机的 /usr/libexec/kubernetes/kubelet-plugins/volume/exec/juicedata~juicefs/juicefs
位置, 并且将它改成可执行的(需要 Python2.6+ 或者 Python3)。
$ wget https://juicefs.com/static/juicefs
$ chmod +x juicefs
$ cp juicefs /usr/libexec/kubernetes/kubelet-plugins/volume/exec/juicedata~juicefs/juicefs
在配置文件中使用明文密钥
你可以像下面这样定义一个 Flex 卷并使用 juicedata/juicefs
作为驱动:
volumes:
- name: test
flexVolume:
driver: "juicedata/juicefs"
options:
name: "my-jfs"
token: "TOKEN"
accesskey: "ACCESSKEY"
secretkey: "SECRETKEY"
你还可以把其他挂载参数加入到 options
里,比如 cacheSize
和 cacheDir
完整的参数列表请参考 juicefs mount -h
。
每个 Pod 会使用一个独立的挂载点,跟 Pod 有相同的生命周期。
Kubernetes 密钥管理
或许你不想把密钥的明文放到 Pod 配置文件中,使用 Kubernetes 的密钥管理可以做到。
先创建一个:
apiVersion: v1
kind: Secret
metadata:
name: my-jfs
type: juicedata/juicefs
data:
token: BASE64(TOKEN)
accesskey: BASE64(ACCESSKEY)
secretkey: BASE64(SECRETKEY)
用下面的方法可以生成秘密的 base64 编码:
$ echo -n TOKEN | base64
然后你可以在 Pod 配置文件中使用它:
volumes:
- name: test
flexVolume:
driver: "juicedata/juicefs"
secretRef:
name: “my-jfs”
options:
name: "my-jfs"
使用 JuiceFS 的配置文件
不管是使用明文还是 Kubernetes 密钥,Flex 卷都会把它们通过命令行参数的方式传递给驱动,比如:
/usr/libexec/kubernetes/kubelet-plugins/volume/exec/juicedata~juicefs/juicefs mount /var/lib/kubelet/pods/aa8ef19f-ba1f-11e7-ab55-0800279245af/volumes/juicedata~juicefs/test '{"kubernetes.io/fsType":"","kubernetes.io/pod.name":"test","kubernetes.io/pod.namespace":"default","kubernetes.io/pod.uid":"aa8ef19f-ba1f-11e7-ab55-0800279245af","kubernetes.io/pvOrVolumeName":"test","kubernetes.io/readwrite":"rw","kubernetes.io/secret/accesskey":"","kubernetes.io/secret/secretkey":"","kubernetes.io/secret/token":"TOKEN","kubernetes.io/serviceAccount.name":"default","name":"NAME"}'
这样看起来也不是很安全,其他人通过 ps
等方法可以看到密钥明文或者编码后的, 通过 JuiceFS 的配置文件(/root/.juicefs/my-jfs.conf
)我们可以把这些从命令行中隐藏起来, 它是一个有如下内容的 JSON 文件:
{“token”: “TOKEN”, “accesskey”: “ACCESSKEY”, “secretkey”: ”SECRETKEY“}
一旦你把这个配置文件部署到所有主机的 /root/.juicefs/my-jfs.conf
, 就不需要在 Pod 配置文件中使用明文或者密码了,如下:
volumes:
- name: test
flexVolume:
driver: "juicedata/juicefs"
options:
name: "NAME"
通过 hostPath 存储卷
可以把 JuiceFS 在所有主机中挂载到同一个挂载点(比如 /jfs
), 然后使用 HostPath 驱动把它(或者某个子目录)绑定到容器中:
volumes:
- name: test-volume
hostPath:
path: /jfs
# this field is optional
type: Directory
所有在同一个主机中的容器会共享同一个客户端(以及文件系统缓存等)。
注意: HostPath 未来可能会在未来 Kubernetes 版本中被本地卷(Local volume)取代。
更多特性
更多支撑 Kuberentes 中应用的特性正在开发内测中,如有需求请通过浏览器右下角的客户支持与我们即时沟通:
- 支持 CSI 存储卷克隆
- 支持 CSI 存储卷快照与恢复