
在 K3s 上部署与使用 JuiceFS从搭建双节点集群到 CSI 持久化 NGINX 数据实战【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs本文是一份面向 Kubernetes 用户的实战指南基于轻量级 Kubernetes 发行版 K3s 搭建双节点集群安装 JuiceFS CSI Driver并通过 StorageClass 动态供给方式将 JuiceFS 文件系统挂载到 NGINX 容器中实现数据持久化。读完本文你将掌握 K3s 集群的快速部署流程、JuiceFS CSI 驱动的安装与配置方法以及如何在 Kubernetes 工作负载中验证分布式文件系统的实际挂载效果。为什么选择 K3s 运行 JuiceFSK3s 是经过功能优化的 Kubernetes 发行版与 Kubernetes 完全兼容即几乎所有在 Kubernetes 上能执行的操作都可以在 K3s 上执行。K3s 将整个容器编排系统打包进一个容量不足 100MB 的二进制程序中大幅减少了部署 Kubernetes 生产集群的环境依赖降低了安装难度对系统硬件的性能要求也更低。对于希望以最小成本体验 JuiceFS 与 Kubernetes 集成方案的场景开发测试、边缘计算、小规模生产K3s 是理想的载体它保留了 Kubernetes 的 StorageClass、PersistentVolumeClaimPVC、CSI 等核心存储抽象JuiceFS 在这些抽象之上提供的动态供给、多读多写、跨节点共享能力可以完整复用。JuiceFS 在 Kubernetes 中的使用方式并不唯一除了本文使用的 CSI Driver仓库文档还介绍了更简单的 hostPath 挂载方式适合对隔离性和权限控制无复杂要求的场景读者可以按需对比选择。本文聚焦最通用、最推荐的 CSI 方案。部署 K3s 集群K3s 对硬件的最低要求很低内存512MB建议 1GBCPU1 核在实际部署生产集群时通常可以将 4 核 CPU 和 8G 内存作为一个节点的硬件配置起点。K3s server 节点本文示例中server 节点的服务器 IP 地址为192.168.1.35。使用 K3s 官方提供的安装脚本即可将常规 Linux 发行版自动部署为 server 节点curl -sfL https://get.k3s.io | sh -部署成功后K3s 服务会自动启动kubectl 等工具也会一并安装。执行命令查看节点状态sudo kubectl get nodesNAME STATUS ROLES AGE VERSION k3s-s1 Ready control-plane,master 28h v1.21.4k3s1随后获取node-token它是 worker 节点加入集群所需的凭证sudo -u root cat /var/lib/rancher/k3s/server/node-tokenK3s worker 节点worker 节点的服务器 IP 为192.168.1.36。执行以下命令将节点加入集群其中K3S_URL指向 server 节点的 IP 或域名默认端口6443K3S_TOKEN替换为从 server 节点获取的node-tokencurl -sfL https://get.k3s.io | K3S_URLhttp://192.168.1.35:6443 K3S_TOKENK1041f7c4fabcdefghijklmnopqrste2ec338b7300674f::server:3d0ab12800000000000000006328bbd80 sh -部署成功后回到 server 节点确认两个节点都已就绪sudo kubectl get nodesNAME STATUS ROLES AGE VERSION k3s-s1 Ready control-plane,master 28h v1.21.4k3s1 k3s-n1 Ready none 28h v1.21.4k3s1安装 JuiceFS CSI Driver与在 Kubernetes 上安装 JuiceFS CSI Driver 的方法一致既可以通过 Helm 安装也可以通过 kubectl 直接安装。这里使用 kubectl 方式kubectl apply -f https://raw.githubusercontent.com/juicedata/juicefs-csi-driver/master/deploy/k8s.yamlJuiceFS CSI Driver 负责在集群节点上完成两件核心工作作为 provisioner 响应 PVC 的创建请求以及作为 node 插件在目标节点上以 FUSE 方式挂载 JuiceFS 文件系统。它的存在使得应用 Pod 无需感知底层文件系统的挂载细节。创建存储类复制并修改以下内容创建配置文件例如juicefs-sc.yamlapiVersion: v1 kind: Secret metadata: name: juicefs-sc-secret namespace: kube-system type: Opaque stringData: name: test metaurl: redis://juicefs.afyq4z.0001.use1.cache.amazonaws.com/3 storage: s3 bucket: https://juicefs-test.s3.us-east-1.amazonaws.com access-key: your-access-key-id secret-key: your-access-key-secret --- apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: juicefs-sc provisioner: csi.juicefs.com reclaimPolicy: Retain volumeBindingMode: Immediate parameters: csi.storage.k8s.io/node-publish-secret-name: juicefs-sc-secret csi.storage.k8s.io/node-publish-secret-namespace: kube-system csi.storage.k8s.io/provisioner-secret-name: juicefs-sc-secret csi.storage.k8s.io/provisioner-secret-namespace: kube-system配置文件中stringData部分用于设置 JuiceFS 文件系统相关信息CSI 驱动会根据这些信息自动创建文件系统。其中name文件系统名称也是数据存储中所有对象的名称前缀对应juicefs format META-URL NAME中的 NAME见 cmd/format.go 的命令定义metaurl元数据引擎地址即 JuiceFS 的 META-URL例如 Redis 连接串storage对象存储类型例如s3、gs、oss、cos等完整支持列表参见 how_to_set_up_object_storage.mdbucket存储数据的对象存储桶路径access-key/secret-key对象存储的访问凭证。当需要在存储类中使用已经预先创建好的文件系统时只需填写name和metaurl两项即可其他项可以删除或将值留空。执行命令部署存储类kubectl apply -f juicefs-sc.yaml查看存储类状态sudo kubectl get scNAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 28h juicefs-sc csi.juicefs.com Retain Immediate false 28h注意一个存储类与一个 JuiceFS 文件系统相关联你可以根据需要创建任意数量的存储类。但需要注意修改配置文件中的存储类名称避免同名冲突。源码视角Secret 与 format 命令的对应关系从源码实现看stringData中的字段与juicefs format命令的参数一一对应。在 cmd/format.go 中数据存储相关参数定义如下--storage对象存储类型默认值为file本地目录实际使用时需显式指定为s3等云端对象存储--bucket存储数据的桶路径默认值为$HOME/.juicefs/local非 root或/var/jfsroot--access-key/--secret-key对象存储认证信息也可通过环境变量ACCESS_KEY、SECRET_KEY注入。也就是说CSI 驱动本质上是在集群内部替你执行了一次文件系统初始化根据 Secret 中的连接信息创建元数据引擎与对象存储的绑定关系并把文件系统的配置如BlockSize、Compression、Shards等持久化到元数据引擎中。更详细的参数说明可参考 command_reference.mdx 中format命令一节。使用 JuiceFS 持久化 NGINX 数据接下来部署一个 NGINX Pod使用刚才创建的juicefs-sc存储类声明持久化存储验证 JuiceFS 的数据持久化能力。Deployment创建配置文件例如depolyment.yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: web-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 10Pi storageClassName: juicefs-sc --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-run labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: linuxserver/nginx ports: - containerPort: 80 volumeMounts: - mountPath: /config name: web-data volumes: - name: web-data persistentVolumeClaim: claimName: web-pvc这份配置有两个值得注意的要点accessModes: ReadWriteMany这是 JuiceFS 这类分布式文件系统的核心价值。底层文件系统支持多节点同时读写因此多个 Pod此处replicas: 2可以挂载同一个 PVC数据实时共享。传统块存储如云盘通常只能支持 ReadWriteOnce无法实现跨节点共享。storage: 10PiPVC 请求的容量只是声明值JuiceFS 的容量取决于对象存储规模因此这里可以按需声明一个很大的值。在后续的验证输出中可以看到挂载点容量即为1.0P与 PVC 声明一致。执行部署sudo kubectl apply -f depolyment.yamlService创建配置文件例如service.yaml将 NGINX 的 80 端口暴露为集群内服务apiVersion: v1 kind: Service metadata: name: nginx-run-service spec: selector: app: nginx ports: - name: http port: 80执行部署sudo kubectl apply -f service.yamlIngressK3s 默认预置了 traefik-ingress通过以下配置为 NGINX 创建 ingress将外部 HTTP 请求路由到集群内的 Service。创建配置文件例如ingress.yamlapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-run-ingress annotations: traefik.ingress.kubernetes.io/router.entrypoints: web spec: rules: - http: paths: - pathType: Prefix path: /web backend: service: name: nginx-run-service port: number: 80执行部署sudo kubectl apply -f ingress.yaml访问与验证部署完成以后使用相同局域网的主机访问任何一个集群节点即可看到 NGINX 的欢迎页面通过 Ingress 的/web路径路由到后端服务。接下来验证容器是否成功挂载了 JuiceFS。先查看 Pod 状态sudo kubectl get podsNAME READY STATUS RESTARTS AGE nginx-run-7d6fb7d6df-qhr2m 1/1 Running 0 28h nginx-run-7d6fb7d6df-5hpv7 1/1 Running 0 24h两个副本均处于 Running 状态。然后进入任意一个 Pod 查看文件系统挂载情况sudo kubectl exec nginx-run-7d6fb7d6df-qhr2m -- df -ThFilesystem Type Size Used Avail Use% Mounted on overlay overlay 20G 3.2G 17G 17% / tmpfs tmpfs 64M 0 64M 0% /dev tmpfs tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup JuiceFS:jfs fuse.juicefs 1.0P 174M 1.0P 1% /config /dev/sda1 ext4 20G 3.2G 17G 17% /etc/hosts shm tmpfs 64M 0 64M 0% /dev/shm tmpfs tmpfs 2.0G 12K 2.0G 1% /run/secrets/kubernetes.io/serviceaccount tmpfs tmpfs 2.0G 0 2.0G 0% /proc/acpi tmpfs tmpfs 2.0G 0 2.0G 0% /proc/scsi tmpfs tmpfs 2.0G 0 2.0G 0% /sys/firmware从输出可以看到名为jfs的 JuiceFS 文件系统类型为fuse.juicefs已经挂载到容器的/config目录容量 1.0P已使用 174M。这就表明集群中的 Pod 已经成功配置并使用 JuiceFS 持久化数据了。验证结论数据写在对象存储上而非容器本地fuse.juicefs文件系统类型说明该挂载点由 JuiceFS 客户端通过 FUSE 提供应用对/config的读写请求会经由用户态文件系统转发到对象存储数据面与元数据引擎元数据面这正是 JuiceFS 的架构本质。也因此Pod 被删除或调度到集群中任意其他节点重建后PVC 会自动在新节点重新挂载同一个文件系统数据不丢失两个 NGINX 副本共享同一份/config数据任何一端写入的内容另一端立即可见ReadWriteMany语义应用侧无需关心底层对象存储的实现细节挂载体验与本地磁盘一致。延伸Kubernetes 中使用 JuiceFS 的其他方式本文演示的 CSI Driver 是 Kubernetes 生产环境的标准用法除此之外仓库文档还提供了另外两种方案可按需选用hostPath 方式在所有节点上预先安装并挂载 JuiceFS再通过 hostPath 卷 将宿主机挂载点的子目录直接暴露给容器。优点是简单直接、易排查缺点是需要逐节点预挂载、缺乏隔离性、挂载进程资源不受 Kubernetes 管控且挂载进程意外退出时 Pod 无法自动恢复。容器内直接挂载在应用镜像中集成 JuiceFS 客户端参考 how_to_use_on_kubernetes.md 中的 Dockerfile 示例以特权模式运行容器并在启动时执行juicefs mount。需要注意特权模式会赋予容器访问宿主机所有设备的权限使用前务必进行充分的安全评估。对于大多数生产场景本文的 CSI Driver 方案是平衡功能、安全与可维护性的首选。小结至此你已经完成了一条完整的 JuiceFS-on-K3s 链路双节点 K3s 集群 → JuiceFS CSI Driver → Secret StorageClass → PVC Deployment Service Ingress → 容器内验证fuse.juicefs挂载。这套组合为 Kubernetes 工作负载提供了具有跨节点共享、弹性容量、按需供给能力的分布式存储层无论是本地开发环境还是生产集群均可参照本文逐步落地。【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考