juicefs+ceph rgw 存储安装
Juiicefs是一款国产开源的面向云原生的分布式文件系统。它可以支持多种存储介质,实现统一的存储接口,可作为国产化基础平台改造中(尤其是在大数据、云原生方向)重要的中间件使用。
当前应用场景:ceph集群存储 + k8s(containerd)使用juicefs-csi-driver作为容器存储自动挂载的驱动,实现容器自动分配存储空间,自动挂载。
参考官方文档:JuiceFS 简介 | JuiceFS Document Center和介绍 | JuiceFS Document Center
实施步骤:
1. 为ceph存储安装rgw, 如果你的ceph rgw的api可以正常使用可以省略此步。
安装方法可以参考DeepSeek给的结果,也可以参考我的上一篇,在此不做赘述。(注意收集并保存好:Access Key和Secret Key,后面要用,同时创建一个Bucket,作为下一步的存储空间)
2. 安装redis ,确保redis的地址可以正常访问。
3. 安装juicfs客户端,可以参考官方文档快速上手的安装手册,可以在本机上使用单机模式,创建一下论juicfs的文件系统,并挂载个本地目录,验证一下 ceph rgw 也就是S3存储协议的Bucket Endpoint 接口是否可用,如果你已经安装好了redis,也可以在本机使用分布式模式创建以下文件系统,将S3存储和Redis都验证一下有效性。这里可以通过观察ceph dashboard页面中Object Gateway > Buckets 观察创建的桶的大小是否增长,来验证创建文件系统的可用性。
这里需要注意的是命令中:
sudo juicefs format \
--storage s3 \
--bucket http://k8s.22.12.70.201:7480 \
--access-key **************\
--secret-key *********** \
redis://26.96.8.190:6379/1 \
k8sjfs# Bucket Endpoint k8s 为在ceph rgw中创建的bucket的名
# redis ip地址后有一个/1
其实这个第三步,如果你不考虑宿主机目录挂载,同时也不考虑创建S3网关,不需要考虑在宿主机上为监控提供metrics api ,可以省略此步。
4. 安装juicefs-csi-driver
这里官方文档使用helm安装,helm需要连接的数据源在github上,因为有墙,这步不大容易成功,至少我的网络环境使用helm不能正常安装。这里我使用了官方提供的kubectl直接安装的方式,不过,官网下载下来的k8s.yaml脚本中的镜像地址需要更改以下,不然镜像不能正常拉取。主要涉及的镜像修改后的地址如下:
//install juicefs-csi-driver
docker.m.daocloud.io/juicedata/csi-dashboard:v0.29.2
docker.m.daocloud.io/juicedata/juicefs-csi-driver:v0.29.2
k8s.m.daocloud.io/sig-storage/csi-provisioner:v2.2.2
k8s.m.daocloud.io/sig-storage/csi-resizer:v1.9.0
k8s.m.daocloud.io/sig-storage/livenessprobe:v2.11.0
k8s.m.daocloud.io/sig-storage/csi-node-driver-registrar:v2.9.0
docker.m.daocloud.io/juicedata/mount:ce-v1.3.0
修改k8s.yaml 脚本,除了镜像地址,还可以修改以下namespace,脚本默认是在kube-system空间下,我把它改为juicefs空间,你也可以选择不改。
kubectl create ns juicefs //如果不改k8s,可以省略
kubectl apply -f k8s.yaml // 执行脚本
使用:kubectl -n juicefs get pods -l app.kubernetes.io/name=juicefs-csi-driver 命令查看,具体可以参考官网步骤实施。
5. 创建 secret
按照官网:使用指南 > 创建和使用PV 实施。
这一步如果前面尝试过第三步,secret的yaml文件内容很好填写,注意第三步提示的细节就好了。
kubectl apply -f secret.yaml //部署
6. 创建sc
// jfs-sc.yamlapiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: jfs-sc
provisioner: csi.juicefs.com
reclaimPolicy: Delete # 这里我使用了回收模式,也可以选择Retain
parameters:csi.storage.k8s.io/provisioner-secret-name: jfs-secret
#这里要和你创建的secret名一致csi.storage.k8s.io/provisioner-secret-namespace: juicefs
#和前面部署的juicefs-csi-driver命名空间一致csi.storage.k8s.io/node-publish-secret-name: jfs-secretcsi.storage.k8s.io/node-publish-secret-namespace: juicefsjuicefs/mount-image: core.harbor.shell.com:443/juicefs-csi-driver/mount:ce-v1.3.0
# 这里是自定义容器镜像,我把刚才下载下来的docker.m.daocloud.io/juicedata/mount:ce-v1.3.0 镜像放到私有仓库里了,当前写的是私有仓库地址,这里如果不写在创建pvc的时候mountPod不能创建成功,因为它拉不下来mount镜像。pathPattern: "${.pvc.namespace}-${.pvc.name}"
#这里我是参考官网写的,目的是想更改PV的创建名称,但没有生效,具体原因不明,要有知道的小伙伴,希望能给指点。
allowVolumeExpansion: true
#这里是允许pv扩展,通过修改PersistentVolumeClaim
mountOptions:- cache-dir=/data/juicefs-cache- cache-size=1024
# 这里的参数是在宿主机上创建juicefs cache 增加存储性能,参数中设置的缓存大小是1G, 执行这一步的前提是要在k8s所有节点上创建/data/juicefs-cache ,并设置目录访问权限。
7. 测试
在执行这一步之前,需要查看以下前几步是否都执行成功了没有,如果内容如下所示,就可以执行测试了。
kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
jfs-sc csi.juicefs.com Delete Immediate true 9hkubectl get secret -n juicefs
NAME TYPE DATA AGE
jfs-secret Opaque 6 2d21hkubectl get pod -n juicefs
NAME READY STATUS RESTARTS AGE
juicefs-csi-controller-0 4/4 Running 0 2d22h
juicefs-csi-controller-1 4/4 Running 0 2d22h
juicefs-csi-dashboard-6554bf547d-6m8k4 1/1 Running 0 2d22h
juicefs-csi-node-2nbb6 3/3 Running 0 2d22h
juicefs-csi-node-7xlg5 3/3 Running 0 2d22h
juicefs-csi-node-mtzk5 3/3 Running 0 2d22h
juicefs-csi-node-vkfnh 3/3 Running 0 2d22h
创建测试文件 :
// test.yamlapiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-httpd-pvcnamespace: default
spec:accessModes:- ReadWriteManyresources:requests:storage: 1GistorageClassName: jfs-sc
---
apiVersion: apps/v1
kind: Deployment
metadata:name: my-httpdnamespace: default
spec:replicas: 1selector:matchLabels:app: my-httpdtemplate:metadata:labels:app: my-httpdspec:containers:- name: httpdimage: docker.m.daocloud.io/library/tomcat:9.0-jdk11ports:- containerPort: 8080protocol: TCPargs:- -c- cp -r /usr/local/tomcat/webapps.dist/ROOT /usr/local/tomcat/webappscommand:- /bin/shsecurityContext:runAsUser: 1000 # 修改挂载目录的拥有者用户,1000为自定义的第一个用户runAsGroup: 1000 # 修改自定义用户组volumeMounts:- name: datamountPath: /usr/local/tomcat/webappsmountPropagation: HostToContainer #这个参数是参考官网添加的,目的是容器损坏恢复自动挂载目录,但在我的执行过程中有这个参数,pod会不能正常启动(具体原因不明);如果你也遇到和我一样的情况,删除这个参数应该就可以了。volumes:- name: datapersistentVolumeClaim:claimName: my-httpd-pvc
# 下面的内容目的是通过sidecar模式,修改挂载目录访问权限,不然挂载后的目录容器将不能访问initContainers:- name: fix-permissionsimage: core.harbor.shell.com:443/library/nettools:v1command: ["sh","-c","chown -R 1000:1000 /mnt/data && chmod 755 /mnt/data"]volumeMounts:- name: datamountPath: /mnt/data
---
apiVersion: v1
kind: Service
metadata:name: my-httpdnamespace: default
spec:selector:app: my-httpdports:- protocol: TCPport: 8080targetPort: 8080type: ClusterIP
部署完后验证:
kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-bd90d1c7-9157-4098-b6ca-e7d7884e24ad 1Gi RWX Delete Bound default/my-httpd-pvc jfs-sc 8hkubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
my-httpd-pvc Bound pvc-bd90d1c7-9157-4098-b6ca-e7d7884e24ad 1Gi RWX jfs-sc 8hkubectl get pod -n juicefs
NAME READY STATUS RESTARTS AGE
juicefs-csi-controller-0 4/4 Running 0 2d22h
juicefs-csi-controller-1 4/4 Running 0 2d22h
juicefs-csi-dashboard-6554bf547d-6m8k4 1/1 Running 0 2d22h
juicefs-csi-node-2nbb6 3/3 Running 0 2d22h
juicefs-csi-node-7xlg5 3/3 Running 0 2d22h
juicefs-csi-node-mtzk5 3/3 Running 0 2d22h
juicefs-csi-node-vkfnh 3/3 Running 0 2d22h
juicefs-k8s70137-pvc-bd90d1c7-9157-4098-b6ca-e7d7884e24ad-isnkji 1/1 Running 0 8hkubectl get pod
NAME READY STATUS RESTARTS AGE
my-httpd-59779b8f75-2z6vd 1/1 Running 0 8h
先检查pv是否正常创建,并绑定,然后再看pvc, 因为juicefs-csi 采用了分离架构,每一个pvc创建都会在创建juicefs-csi 的容器空间下,创建一个mount pod 用来挂载实际应用中的pod,如果前面的secret内容有误,或者redis或s3有问题,mount pod就会出现故障,你可以通过查看mount pod的日志来分析具体故障原因。如果你做到了上述的最后一步,恭喜你juicefs+ceph+k8s 的通道成功打通了!
7. S3网关(非必要)
下面的步骤主要是创建监控,可以参考官方文档 中使用指南 > 运行其他 JuiceFS应用 > 运行 JuiceFS S3网关,将网关部署到k8s上(helm部署也是有问题),也可以选择使用宿主机本地部署,我将本地挂载和创建网关写了个脚本,可以开机后运行,也可以用的时候再去挂载,只要宿主机不重启,脚本执行一次就行。
// jfs-gw-start.sh#!/bin/bashexport MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=********
juicefs gateway --cache-size 2048 --multi-buckets redis://26.96.8.190:6379/1 10.12.70.130:9000 -d --log=/home/shell811127/juicefs/log/juicefs-s3-gateway.log
mc config host add juicefs http://22.12.70.130:9000 admin Txgm2m85331919@
mkdir -p /home/shell811127/data/mnt-ceph
sudo juicefs mount -d redis://26.96.8.190:6379/1 /home/shell811127/data/mnt-ceph --metrics :9567
这样的好处是可以在宿主机上直接用mc软件(minio的客户端)来管理k8s自动分配的存储目录。
mc命令使用参考:官方文档
剩下的使用Prometheus 和 Grafana安装监控dashboard,可以参考官网文档