最近更新时间:2025-03-10 11:01:43
如果对灵活性、可观测性有要求,推荐以 CSI 存储卷的方式使用KPFS。您可以以静态配置和动态配置两种方式来使用CSI Driver,KPFS以持久卷(PersistentVolume)的形式提供给Pod使用。
创建Helm应用
前往容器服务,在Helm应用页面,选择集群,单击新建按钮。
配置应用信息
选择Chart来源,Ksyun Helm Chart,选择kpfs-v-driver,点击部署。
如下图所示,待所有容器都处于Running时,驱动部署完成。
kubectl -n kube-system get pods -l app.kubernetes.io/name=kpfs-v-driver
通过Helm脚本方式安装CSI Driver。
使用Apt,在KCE集群内安装Helm
您需要找一台集群内的节点,该节点要求配置kubectl(使用kubectl get node可输出KCE集群的所有节点)。
# 下载Helm的GPG公钥,并保存在系统的密钥环中,以便后续验证Helm软件包的签名
curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
# 安装apt-transport-https软件包
sudo apt-get install apt-transport-https --yes
# 将Helm的软件仓库添加到系统的Apt源列表
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
# 更新软件包索引,并安装Helm软件包
sudo apt-get update
sudo apt-get install helm
CSI驱动的Helm chart包文件,请根据KCE集群所在地域下载对应地域的Helm chart包文件。
检查kubelet根目录
在Kubernetes集群中任意一个非Master节点上执行以下命令:
ps -ef | grep kubelet | grep root-dir
如果结果不为空,则代表该集群的 kubelet 的根目录(--root-dir
)做了定制,需要在 values 中将 kubeletDir
根据实际情况进行设置:
kubeletDir: <kubelet-dir>
登录KCE的一个worker节点,将步骤2下载的文件拷贝至worker节点的/root目录下并解压缩,安装CSI Driver。
cd juicefs-csi-driver
# 不论是初次安装还是后续的配置变更,都可以运行这一行命令达到效果
helm upgrade --install juicefs-csi-driver . -n kube-system -f ./value.yaml
检查部署状态,使用下方命令确认CSI驱动组件正常运行。
kubectl -n kube-system get pods -l app.kubernetes.io/name=juicefs-csi-driver
NAME READY STATUS RESTARTS AGE
juicefs-csi-controller-0 3/3 Running 0 6m44s
juicefs-csi-controller-1 3/3 Running 0 6m33s
juicefs-csi-dashboard-5d8d4df769-t5jt9 1/1 Running 0 6m44s
juicefs-csi-node-jfkhv 3/3 Running 0 6m44s
CSI Node Service 是一个 DaemonSet,默认在所有节点部署,因此在上方命令的输出中,CSI Node Pod 数量应该与 worker 节点数相同。如果你注意到数量不一致,请检查是否有节点被打上了污点。视情况删除污点,或给 CSI Node Service 打上对应的容忍,来修复此问题。
在CSI驱动中,挂载KPFS文件系统所需的认证信息,均存在 Kubernetes Secret 中,因此您必须先创建文件系统认证信息。通过 kubectl apply -f secret.yaml
指令创建认证信息:
apiVersion: v1
metadata:
name: juicefs-secret
namespace: default
labels:
# 增加该标签以启用认证信息校验
juicefs.com/validate-secret: "true"
kind: Secret
type: Opaque
stringData:
name: ${KPFS_NAME}
token: ${KPFS_TOKEN}
access-key: ${ACCESS_KEY}
secret-key: ${SECRET_KEY}
envs: '{"BASE_URL": "$KPFS_URL/static", "CFG_URL": "$KPFS_URL/volume/%s/mount"}'
字段说明:
name
:KPFS文件系统名称。
token
:访问KPFS文件系统所需的Token(参见KPFS控制台-文件系统详情页挂载方法中的Token值)。
access-key / secret-key
:账户的AK/SK信息(参见快速上手)。
envs
:填写BASE_URL 及 CFG_URL,将KPFS_URL替换为KPFS控制台-文件系统详情页挂载命令中的http://IP:端口地址)。
Secret命名是自定义的,您可以创建出多个Secret,存储不同的文件系统认证信息,这样便可以在同一个 Kubernetes 集群中使用多个不同的KPFS文件系统。示例如下:
---
apiVersion: v1
metadata:
name: vol-secret-1
namespace: default
kind: Secret
...
---
apiVersion: v1
metadata:
name: vol-secret-2
namespace: kube-system
kind: Secret
...
静态配置是最简单直接地在 Kubernetes 中使用 KPFS PV 的方式,直接将整个文件系统的根目录(或子目录)作为 PV 挂载到Pod里,适用于不同容器共享数据的场景。
通过kubectl apply -f pv.yaml
指令创建PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: juicefs-pv
labels:
juicefs-name: ten-pb-fs
spec:
capacity:
storage: 10Pi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
csi:
# 在先前的安装步骤中,已经创建了名为 csi.juicefs.com 的 CSIDriver
driver: csi.juicefs.com
# volumeHandle 需要保证集群内唯一,因此一般直接用 PV 名即可
volumeHandle: juicefs-pv
fsType: juicefs
# 在先前的步骤中已经创建好文件系统认证信息(Secret),在这里引用
# 如果要在静态配置下使用不同的认证信息,甚至使用不同的文件系统,则需要创建不同的Secret
nodePublishSecretRef:
name: juicefs-secret
namespace: default
字段说明:
storage:
不支持给静态 PV 设置存储容量,填写任意有效值即可。
accessModes
:PV访问模式,支持ReadWriteMany
(允许多个node读写访问)和 ReadOnlyMany
(允许多个node只读访问)两种访问方式。您可根据使用CSI驱动的方式不同, 在PV定义中,填写需要的accessModes
。
persistentVolumeReclaimPolicy
:静态PV仅支持Retain
,PV删除时对应KPFS文件系统不会被删除。
nodePublisSecretRef
:先前的步骤中创建好的文件系统认证信息(Secret)。
通过kubectl apply -f pvc.yaml
指令创建PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: juicefs-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany
volumeMode: Filesystem
storageClassName: ""
resources:
requests:
storage: 10Pi
selector:
matchLabels:
juicefs-name: ten-pb-fs
字段说明:
accessModes
:PV访问模式,支持ReadWriteMany
(允许多个node读写访问)和 ReadOnlyMany
(允许多个node只读访问)两种访问方式。必须与PV的accessModes
一致才能绑定。
storageClassName
:静态配置下必须指定 storageClassName 为空字符串,代表该 PV 不采用任何 StorageClass,而是直接使用 selector 所指定的 PV。
storage
:不支持给静态 PV 设置存储容量,填写任意小于 PV 的storage
有效值即可。
selector
:指定使用的PV。
通过kubectl apply -f app.yaml
指令创建Pod:
apiVersion: v1
kind: Pod
metadata:
name: juicefs-app
namespace: default
spec:
containers:
- args:
- -c
- while true; do echo $(date -u) >> /data/out.txt; sleep 5; done
command:
- /bin/sh
image: centos
name: app
volumeMounts:
# pod内挂载路径
- mountPath: /data
name: data
# 必须配置好传播,以防 mount pod 异常以后,挂载点无法自动恢复
mountPropagation: HostToContainer
resources:
requests:
cpu: 10m
volumes:
- name: data
persistentVolumeClaim:
# 替换成要使用的PVC名称
claimName: juicefs-pvc
Pod创建完成后,可以进入容器确认数据正常写入:
kubectl exec -ti juicefs-app -- tail -f /data/out.txt
在CSI驱动体系中,您可以通过mountOptions
字段填写需要调整的挂载配置,mountOptions
支持KPFS本身的挂载参数和FUSE相关选项(相关参数信息参见客户端命令)。
静态配置下,您可以通过在PV中定义mountOptions
调整挂载参数,示例如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: juicefs-pv
labels:
juicefs-name: ten-pb-fs
spec:
mountOptions:
- cache-size=204800
...
注意 如果是修改已有PV的挂载配置,修改后需要重建应用Pod,才能使变动生效。
在静态配置下,如果没有显式指定挂载子目录,文件系统的根目录将会被挂载进容器,因此如果对应用有数据隔离的要求,希望让多个应用共享同一个子目录,可使用subdir
参数挂载子目录。如果子目录尚不存在,会在挂载前自动创建。示例如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: juicefs-pv
labels:
juicefs-name: ten-pb-fs
spec:
mountOptions:
- subdir=/my/sub/dir
...
静态配置下,如果想要在不同命名空间中共享同一个文件系统,只需要让不同 PV 使用相同的文件系统认证信息(Secret)即可。示例如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
labels:
pv-name: mypv1
spec:
csi:
nodePublishSecretRef:
name: juicefs-secret
namespace: default
...
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv2
labels:
pv-name: mypv2
spec:
csi:
nodePublishSecretRef:
name: juicefs-secret
namespace: default
...
动态配置方式,创建PV的基础配置参数在StorageClass中定义。您只需创建PVC,指定StorageClass,并且在Pod中引用该PVC,就会自动为您创建一个PV,每一个PV会最终对应KPFS文件系统中的一个子目录。适用于大量应用且不同应用、不同团队间需要实现数据隔离的场景。
StorageClass(存储类)里指定了创建PV所需的各类配置,您可以将其理解为动态配置下的Profile:不同的StorageClass就是不同的Profile,可以在其中指定不同的认证信息、挂载配置,让动态配置下可以同时使用不同的文件系统,或者指定不同的挂载。
通过kubectl apply -f sc.yaml
指令创建StorageClass:
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
reclaimPolicy: Retain
字段说明:
reclaimPolicy:
动态PV支持Delete|Retain
两种回收策略。Delete
策略会导致在删除PV时,PVC子目录随着一起释放。如果数据安全性要求高,推荐使用Retain,以免误删数据。
parameters
:先前的步骤中创建好的文件系统认证信息(Secret)。
通过kubectl apply -f pvc.yaml
指令创建PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: juicefs-pvc
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: juicefs-sc
字段说明:
accessModes:
PV访问模式,支持ReadWriteMany
(允许多个node读写访问)和 ReadOnlyMany
(允许多个node只读访问)两种访问方式。
storage:
支持为动态PV设置存储容量,为该PV所对应的子目录添加容量限制。
storageClassName:
指定使用的StorageClass。
通过kubectl apply -f app.yaml
指令创建Pod:
apiVersion: v1
kind: Pod
metadata:
name: juicefs-app
namespace: default
spec:
containers:
- args:
- -c
- while true; do echo $(date -u) >> /data/out.txt; sleep 5; done
command:
- /bin/sh
image: centos
name: app
volumeMounts:
# pod内挂载路径
- mountPath: /data
name: juicefs-pv
# 必须配置好传播,以防 mount pod 异常以后,挂载点无法自动恢复
mountPropagation: HostToContainer
volumes:
- name: juicefs-pv
persistentVolumeClaim:
# 替换成要使用的PVC名称
claimName: juicefs-pvc
Pod创建完成后,可以进入容器确认数据正常写入:
kubectl exec -ti juicefs-app -- tail -f /data/out.txt
在CSI驱动体系中,您可以通过mountOptions
字段填写需要调整的挂载配置,mountOptions
支持KPFS本身的挂载参数和FUSE相关选项(相关参数信息参见客户端命令)。
动态配置下,您可以在 StorageClass 定义中通过mountOptions
调整挂载参数。如果需要为不同应用使用不同挂载参数,则需要创建多个 StorageClass,单独添加所需参数。在StorageClass中修改挂载参数,不影响已经创建的PV。示例如下:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sc-juicefs-training
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-size=204800
注意 StorageClass 仅仅是动态配置下用于创建PV的模板,在StorageClass中修改挂载配置,不影响已经创建的 PV。如果你需要调整挂载配置,需要删除PVC重建。
动态配置下,PV会在KPFS文件系统根目录下创建形如pvc-4f2e2384-61f2-4045-b4df-fbdabe496c1b
的随机命名子目录,随机命名不方便辨认,您可以在StorageClass中通过pathPattern
来定义更加易读的PV目录名称,示例如下:
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
pathPattern: "${.pvc.namespace}-${.pvc.name}"
pathPattern支持注入node和PVC的元数据,比如:
${.node.name}-${.node.podCIDR}
,注入 Node 的 metadata.name
和 spec.podCIDR
,例如 minikube-10.244.0.0/24
${.node.labels.foo}
,注入 Node 的 metadata.labels["foo"]
${.node.annotations.bar}
,注入 Node 的 metadata.annotations["bar"]
${.pvc.namespace}-${.pvc.name}
,注入 PVC 的 metadata.namespace
和 metadata.name
,例如 default-dynamic-pvc
${.pvc.labels.foo}
,注入 PVC 的 metadata.labels["foo"]
${.pvc.annotations.bar}
,注入 PVC 的 metadata.annotations["bar"]
动态配置下,支持PV的扩容。您可以在StorageClass中指定allowVolumeExpansion: true
,同时指定扩容时所需使用的文件系统认证信息(Secret),示例如下:
apiVersion: storage.k8s.io/v1
kind: StorageClass
...
parameters:
csi.storage.k8s.io/node-publish-secret-name: juicefs-secret
csi.storage.k8s.io/node-publish-secret-namespace: default
csi.storage.k8s.io/provisioner-secret-name: juicefs-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: juicefs-secret # 与 provisioner-secret-name 相同即可
csi.storage.k8s.io/controller-expand-secret-namespace: default # 与 provisioner-secret-namespace 相同即可
allowVolumeExpansion: true # 表示支持扩容
然后编辑PVC的spec
字段,指定更大的存储请求,可以触发PV的扩容。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 20Gi # 在此处指定更大的容量
上述方法对存量 PV 不生效,如果需要扩容存量PV,需要手动修改 PV,为其增加 Secret 配置。
apiVersion: v1
kind: PersistentVolume
metadata:
name: pvc-xxxx
spec:
csi:
controllerExpandSecretRef:
name: juicefs-secret
namespace: default
纯净模式