JuiceFS存儲

因語雀與csdn markdown 格式有區別,請查看原文:
https://www.yuque.com/dycloud/pss8ys

一、JuiceFS 介紹

1.1 JuiceFS 是什么

JuiceFS 是一款面向云環境設計的高性能 POSIX 文件系統,核心能力是將對象存儲轉化為全功能文件系統。它采用獨特的數據-元數據分離架構,解決了海量文件存儲的擴展性難題,特別適合 AI 訓練、大數據分析、容器存儲等場景。

🔑 核心價值:讓對象存儲獲得近似本地文件系統的性能與功能,同時保持云存儲的無限擴展性和成本優勢。

JuiceFS 采用 「數據」與「元數據」分離存儲 的架構,從而實現文件系統的分布式設計。文件數據本身會被切分保存在對象存儲(例如 Amazon S3),而元數據則可以保存在 Redis、MySQL、TiKV、SQLite 等多種數據庫中,你可以根據場景與性能要求進行選擇。

JuiceFS 提供了豐富的 API,適用于各種形式數據的管理、分析、歸檔、備份,可以在不修改代碼的前提下無縫對接大數據、機器學習、人工智能等應用平臺,為其提供海量、彈性、低價的高性能存儲。運維人員不用再為可用性、災難恢復、監控、擴容等工作煩惱,專注于業務開發,提升研發效率。同時運維細節的簡化,對 DevOps 極其友好。

1.2 核心特性

  • POSIX 兼容:像本地文件系統一樣使用,無縫對接已有應用,無業務侵入性;
  • HDFS 兼容:完整兼容 HDFS API,提供更強的元數據性能;
  • S3 兼容:提供 S3 網關 實現 S3 協議兼容的訪問接口;
  • 云原生:通過 Kubernetes CSI 驅動 輕松地在 Kubernetes 中使用 JuiceFS;
  • 分布式設計:同一文件系統可在上千臺服務器同時掛載,高性能并發讀寫,共享數據;
  • 強一致性:確認的文件修改會在所有服務器上立即可見,保證強一致性;
  • 強悍性能:毫秒級延遲,近乎無限的吞吐量(取決于對象存儲規模),查看性能測試結果;
  • 數據安全:支持傳輸中加密(encryption in transit)和靜態加密(encryption at rest),查看詳情;
  • 文件鎖:支持 BSD 鎖(flock)和 POSIX 鎖(fcntl);
  • 數據壓縮:支持 LZ4 和 Zstandard 壓縮算法,節省存儲空間。

1.3 應用場景

JuiceFS 為海量數據存儲設計,可以作為很多分布式文件系統和網絡文件系統的替代,特別是以下場景:

  • 大數據分析:HDFS 兼容;與主流計算引擎(Spark、Presto、Hive 等)無縫銜接;無限擴展的存儲空間;運維成本幾乎為 0;性能遠好于直接對接對象存儲。
  • 機器學習:POSIX 兼容,可以支持所有機器學習、深度學習框架;方便的文件共享還能提升團隊管理、使用數據效率。
  • Kubernetes:JuiceFS 支持 Kubernetes CSI;為容器提供解耦的文件存儲,令應用服務可以無狀態化;方便地在容器間共享數據。
  • 共享工作區:可以在任意主機掛載;沒有客戶端并發讀寫限制;POSIX 兼容已有的數據流和腳本操作。
  • 數據備份:在無限平滑擴展的存儲空間備份各種數據,結合共享掛載功能,可以將多主機數據匯總至一處,做統一備份。

1.4 架構設計

JuiceFS 整體上主要由三個部分組成。

  • ** 客戶端(Client)**:所有文件讀寫,乃至于碎片合并、回收站文件過期刪除等后臺任務,均在客戶端中發生。所以客戶端需要同時與對象存儲和元數據引擎打交道。客戶端支持眾多接入方式:
    • 通過 FUSE,JuiceFS 文件系統能夠以 POSIX 兼容的方式掛載到服務器,將海量云端存儲直接當做本地存儲來使用。
    • 通過 Hadoop Java SDK,JuiceFS 文件系統能夠直接替代 HDFS,為 Hadoop 提供低成本的海量存儲。
    • 通過 Kubernetes CSI 驅動,JuiceFS 文件系統能夠直接為 Kubernetes 提供海量存儲。
    • 通過 S3 網關,使用 S3 作為存儲層的應用可直接接入,同時可使用 AWS CLI、s3cmd、MinIO client 等工具訪問 JuiceFS 文件系統。
    • 通過 WebDAV 服務,以 HTTP 協議,以類似 RESTful API 的方式接入 JuiceFS 并直接操作其中的文件。
  • 數據存儲(Data Storage):文件將會切分上傳保存在對象存儲服務,既可以使用公有云的對象存儲,也可以接入私有部署的自建對象存儲。JuiceFS 支持幾乎所有的公有云對象存儲,同時也支持 OpenStack Swift、Ceph、MinIO 等私有化的對象存儲。
  • 元數據引擎(Metadata Engine):用于存儲文件元數據(metadata),包含以下內容:
    • 常規文件系統的元數據:文件名、文件大小、權限信息、創建修改時間、目錄結構、文件屬性、符號鏈接、文件鎖等
    • JuiceFS 獨有的元數據:文件的 chunk 及 slice 映射關系、客戶端 session 等

JuiceFS 采用多引擎設計,目前已支持 Redis、TiKV、MySQL/MariaDB、PostgreSQL、SQLite 等作為元數據服務引擎,也將陸續實現更多元數據存儲引擎。

1.5 讀寫流程

1.5.1 寫流程

與傳統文件系統只能使用本地磁盤存儲數據和對應的元數據的模式不同,JuiceFS 會將數據格式化以后存儲在對象存儲,同時會將文件的元數據存儲在專門的元數據服務中,這樣的架構讓 JuiceFS 成為一個強一致性的高性能分布式文件系統。

任何存入 JuiceFS 的文件都會被拆分成一個或多個 「Chunk」(最大 64 MiB)。而每個 Chunk 又由一個或多個 「Slice」 組成。Chunk 的存在是為了對文件做切分,優化大文件性能,而 Slice 則是為了進一步優化各類文件寫操作,二者同為文件系統內部的邏輯概念。Slice 的長度不固定,取決于文件寫入的方式。每個 Slice 又會被進一步拆分成 「Block」(默認大小上限為 4 MiB),成為最終上傳至對象存儲的最小存儲單元

所以我們在對象存儲平臺的文件瀏覽器中找不到存入 JuiceFS 的源文件,存儲桶中只有一個 chunks 目錄和一堆數字編號的目錄和文件,這正是經過 JuiceFS 拆分存儲的數據塊。與此同時,文件與 Chunks、Slices、Blocks 的對應關系等元數據信息存儲在元數據引擎中。正是這樣的分離設計,讓 JuiceFS 文件系統得以高性能運作。

JuiceFS 的存儲設計,還有著以下技術特點:

  • 對于任意大小的文件,JuiceFS 都不進行合并存儲,這也是為了性能考慮,避免讀放大。
  • 提供強一致性保證,但也可以根據場景需要與緩存功能一起調優,比如通過設置出更激進的元數據緩存,犧牲一部分一致性,換取更好的性能。。
  • 支持并默認開啟「回收站」功能,刪除文件后保留一段時間才徹底清理,最大程度避免誤刪文件導致事故。

1.5.2 讀流程

應用程序 調用 JuiceFS 文件系統接口發起讀請求

  • 1. 應用請求發起

應用程序 調用 JuiceFS 文件系統接口發起讀請求:

read(file, offset, len)

表示要從文件的某個位置(offset)讀取一定長度(len)的數據。

  • 2. JuiceFS Client 查詢元數據

JuiceFS Client 收到讀請求,先向元數據服務查詢這個文件內容的分塊(chunk)分布位置。

比如:查 inode=123 的分塊位置

  • 3. 元數據服務返回塊列表

元數據服務根據 inode,把塊(chunk)的位置和對應對象存儲的對象名返回,比如

[chunk1@obj1, chunk2@obj2]

意思是:這次讀請求命中了 obj1、obj2 兩個對象中的數據塊。

  • 4. 檢查本地緩存

JuiceFS Client 根據塊信息,先向本地緩存查詢所需 chunk 是否存在:

如果命中緩存:直接從本地讀取該 chunk 的數據

如果未命中緩存:則需要訪問底層對象存儲去拉取數據

  • 5. 命中緩存的處理流程

本地緩存命中

- <font style="color:rgb(51, 54, 57);">本地緩存系統直接返回所需數據塊</font>
- <font style="color:rgb(51, 54, 57);">JuiceFS Client 將數據返回給應用程序</font>
- <font style="color:rgb(51, 54, 57);">整個流程結束,效率很高</font>
  • 6. 未命中緩存的處理流程

本地緩存未命中

1. <font style="color:rgb(51, 54, 57);">本地緩存返回未命中標記,JuiceFS Client 轉而向</font>**<font style="color:rgb(51, 54, 57);">對象存儲</font>**<font style="color:rgb(51, 54, 57);">請求 chunk1</font>
2. <font style="color:rgb(51, 54, 57);">對象存儲把 chunk1 數據返回給 JuiceFS Client</font>
3. <font style="color:rgb(51, 54, 57);">JuiceFS Client 讀取數據后,</font>**<font style="color:rgb(51, 54, 57);">將數據塊緩存到本地(寫到本地緩存)</font>**<font style="color:rgb(51, 54, 57);">,以備下次快速訪問</font>
4. <font style="color:rgb(51, 54, 57);">JuiceFS Client 再把數據返回給應用程序</font>
總結:
  1. 應用發起讀請求到 JuiceFS Client
  2. Client 查元數據服務,獲得數據塊與對象存儲位置的對應關系
  3. Client 先查本地緩存,若緩存有直接取出
  4. 若本地未命中,則去對象存儲拉取
  5. 拉取到的數據寫入本地緩存
  6. 最終數據返回給應用程序

二、JuiceFS 安裝配置

2.1 安裝

JuiceFS 是采用 Go 語言開發的,所以具有良好的跨平臺能力,支持在幾乎所有主流架構的各類操作系統上運行,包括且不限于 Linux、macOS、Windows 等。

JuiceFS 客戶端只有一個二進制文件,可以下載預編譯的版本直接解壓使用,也可以用源代碼手動編譯,也可以直接使用一鍵安裝腳本 <font style="color:#DF2A3F;">curl -sSL https://d.juicefs.com/install | sh -</font> 自動下載安裝最新版 JuiceFS 客戶端。

如果在 Mac 下面使用,需要先安裝 FUSE for macOS,這是因為 macOS 默認不支持 FUSE 接口。

[root@k8s-master01 ~]# juicefs version
juicefs version 1.3.0+2025-07-03.30190ca

2.2 單機模式

JuiceFS 文件系統由「對象存儲」和「數據庫」共同驅動,除了對象存儲,還支持使用本地磁盤、WebDAV 和 HDFS 等作為底層存儲。這里我們首先使用本地磁盤和 SQLite 數據庫快速創建一個單機文件系統用以了解和體驗 JuiceFS。

當然首先需要安裝 JuiceFS 的客戶端,然后接下來我們就可以使用 juicefs format 命令來創建一個 JuiceFS 文件系統了,該命令的格式為:

juicefs format [command options] META-URL NAME

從命令可以看出格式化文件系統需要提供 3 種信息:

  • <font style="color:#DF2A3F;">[command options]</font>:設定文件系統的存儲介質,留空則默認使用本地磁盤作為存儲介質,路徑為 $HOME/.juicefs/local/var/jfsC:/jfs/local
  • <font style="color:#DF2A3F;">META-URL</font>:用來設置元數據存儲,即數據庫相關的信息,通常是數據庫的 URL 或文件路徑
  • <font style="color:#DF2A3F;">NAME</font>:是文件系統的名稱

比如我們這里創建一個名為 dujiefs 的文件系統,則可以使用如下所示的命令:

[root@k8s-master01 ~]# juicefs format sqlite3://dujiefs.db dujiefs
2025/07/16 21:13:56.388967 juicefs[84626] <INFO>: Meta address: sqlite3://dujiefs.db [NewClient@interface.go:578]
2025/07/16 21:13:56.394557 juicefs[84626] <INFO>: Data use file:///var/jfs/dujiefs/ [format@format.go:527]
2025/07/16 21:13:56.405053 juicefs[84626] <INFO>: Volume is formatted as {"Name": "dujiefs","UUID": "c4e99180-6ccc-4353-ba4e-230adc805992","Storage": "file","Bucket": "/var/jfs/","BlockSize": 4096,"Compression": "none","EncryptAlgo": "aes256gcm-rsa","TrashDays": 1,"MetaVersion": 1,"MinClientVersion": "1.1.0-A","DirStats": true,"EnableACL": false
} [format@format.go:564]

從返回的信息中可以看到,該文件系統使用 SQLite 作為元數據存儲引擎,數據庫文件位于當前目錄,文件名為 dujiefs.db,保存了 dujiefs 文件系統的所有信息,它構建了完善的表結構,將用作所有數據的元信息的存儲。

由于沒有指定任何存儲相關的選項,客戶端默認使用本地磁盤作為存儲介質,根據返回的信息, dujiefs 的存儲路徑為 file:///var/jfs/dujiefs/

[root@k8s-master01 ~]# ll /var/jfs/dujiefs/juicefs_uuid 
-rw-r--r-- 1 root root 36 716 21:13 /var/jfs/dujiefs/juicefs_uuid

這樣我們就成功創建了一個文件系統了,接下來我們就可以使用 juicefs mount 命令來掛載文件系統了,該命令的一般格式為:

juicefs mount [command options] META-URL MOUNTPOINT

與創建文件系統的命令類似,掛載文件系統需要提供以下信息:

  • [command options]:用來指定文件系統相關的選項,例如:-d 可以實現后臺掛載;
  • META-URL:用來設置元數據存儲,即數據庫相關的信息,通常是數據庫的 URL 或文件路徑;
  • MOUNTPOINT:指定文件系統的掛載點。

由于 SQLite 是單文件數據庫,掛載時要注意數據庫文件的的路徑,JuiceFS 同時支持相對路徑和絕對路徑。比如我們這里可以使用以下命令將 dujiefs 文件系統掛載到 ./jfs 文件夾:

[root@k8s-master01 ~]# juicefs mount sqlite3://dujiefs.db ./jfs
2025/07/16 21:16:36.011783 juicefs[86277] <INFO>: Meta address: sqlite3://dujiefs.db [NewClient@interface.go:578]
2025/07/16 21:16:36.019412 juicefs[86277] <INFO>: Data use file:///var/jfs/dujiefs/ [mount@mount.go:588]
2025/07/16 21:16:36.113630 juicefs[86286] <INFO>: Meta address: sqlite3://dujiefs.db [NewClient@interface.go:578]
2025/07/16 21:16:36.118450 juicefs[86286] <INFO>: Data use file:///var/jfs/dujiefs/ [mount@mount.go:588]
2025/07/16 21:16:36.118570 juicefs[86286] <INFO>: JuiceFS version 1.3.0+2025-07-03.30190ca [mount@mount.go:631]
2025/07/16 21:16:36.119972 juicefs[86286] <INFO>: Disk cache (/var/jfsCache/c4e99180-6ccc-4353-ba4e-230adc805992/): used ratio - [space 44.3%, inode 1.2%] [newCacheStore@disk_cache.go:147]
2025/07/16 21:16:36.120107 juicefs[86286] <INFO>: Adjusted cache capacity based on freeratio: from 107374182400 to 67612702976 bytes [setlimitByFreeRatio@disk_cache.go:171]
2025/07/16 21:16:36.120226 juicefs[86286] <INFO>: Adjusted max items based on freeratio: from 0 to 33030143 items [setlimitByFreeRatio@disk_cache.go:176]
2025/07/16 21:16:36.126068 juicefs[86286] <INFO>: Create session 1 OK with version: 1.3.0+2025-07-03.30190ca [NewSession@base.go:535]
2025/07/16 21:16:36.127250 juicefs[86286] <INFO>: Prometheus metrics listening on 127.0.0.1:9567 [exposeMetrics@mount.go:134]
2025/07/16 21:16:36.129981 juicefs[86286] <INFO>: Add fuse.juicefs into PRUNEFS of /etc/updatedb.conf [disableUpdatedb@mount_unix.go:448]
2025/07/16 21:16:36.130117 juicefs[86286] <INFO>: Mounting volume dujiefs at ./jfs ... [mountMain@mount_unix.go:1027]
2025/07/16 21:16:36.523383 juicefs[86277] <INFO>: OK, dujiefs is ready at /root/jfs [checkMountpoint@mount_unix.go:235]
2025-07-16 21:16:41.128019 I | Unimplemented opcode POLL
2025/07/16 21:16:41.129289 juicefs[86277] <INFO>: watching /root/jfs, pid 86286 [watchdog@mount_unix.go:162]

默認情況下,客戶端會在前臺掛載文件系統,程序會一直運行在當前終端進程中,使用 Ctrl + C 組合鍵或關閉終端窗口,文件系統會被卸載。

為了讓文件系統可以在后臺保持掛載,可以在掛載時指定 -d--background 選項,即讓客戶端在守護進程中掛載文件系統:

[root@k8s-master01 ~]# juicefs mount -d sqlite3://dujiefs.db ./jfs
2025/07/16 21:17:10.783120 juicefs[86631] <INFO>: Meta address: sqlite3://dujiefs.db [NewClient@interface.go:578]
2025/07/16 21:17:10.789139 juicefs[86631] <INFO>: Data use file:///var/jfs/dujiefs/ [mount@mount.go:588]
2025/07/16 21:17:11.296754 juicefs[86631] <INFO>: OK, dujiefs is ready at /root/jfs [checkMountpoint@mount_unix.go:235]

接下來,任何存入掛載點 ~/jfs 的文件,都會按照 JuiceFS 的文件存儲格式被拆分成特定的「數據塊」并存入 file:///var/jfs/dujiefs/ 目錄中,相對應的「元數據」會全部存儲在 ydzsfs.db 數據庫中。

最后執行以下命令可以將掛載點 ~/jfs 卸載:

[root@k8s-master01 ~]# juicefs umount ~/jfs

2.3 使用對象存儲

幾乎所有主流的云計算平臺都有提供對象存儲服務,如亞馬遜 S3、阿里云 OSS 等,JuiceFS 支持幾乎所有的對象存儲服務。一般來說,創建對象存儲通常只需要 2 個環節:

  • 創建 Bucket 存儲桶,拿到 Endpoint 地址;
  • 創建 Access Key ID 和 Access Key Secret,即對象存儲 API 的訪問密鑰。

以阿里云 oss 為例,創建好的資源大概像下面這樣:

**Bucket Endpoint:**k8s-test-files.oss-cn-beijing.aliyuncs.com

AccessKeyID:xxxxx

AccessKey Secret:xxxxxx

我們這里以阿里云 OSS 服務為例來進行演示,首先創建一個 Bucket 存儲桶,命名為 k8s-test-files,然后創建 獲取賬號的密鑰對

[root@k8s-master01 ~]# juicefs format --storage oss \
>     --bucket https://k8s-test-files.oss-cn-beijing.aliyuncs.com \
>     --access-key xxxxxx \
>     --secret-key xxxxxx \
>     sqlite3://k8s-test-files.db  k8s-test-files2025/07/16 21:26:25.458490 juicefs[92527] <INFO>: Meta address: sqlite3://k8s-test-files.db [NewClient@interface.go:578]
2025/07/16 21:26:25.465257 juicefs[92527] <WARNING>: The latency to database is too high: 6.505436ms [newSQLMeta@sql.go:506]
2025/07/16 21:26:25.468105 juicefs[92527] <INFO>: Data use oss://k8s-test-files/k8s-test-files/ [format@format.go:527]
2025/07/16 21:26:25.778414 juicefs[92527] <INFO>: Volume is formatted as {"Name": "k8s-test-files","UUID": "a4531ea8-31c9-42a5-8953-bdb20af94bf3","Storage": "oss","Bucket": "https://k8s-test-files.oss-cn-beijing.aliyuncs.com","AccessKey": "xxxxxxxx","SecretKey": "removed","BlockSize": 4096,"Compression": "none","EncryptAlgo": "aes256gcm-rsa","KeyEncrypted": true,"TrashDays": 1,"MetaVersion": 1,"MinClientVersion": "1.1.0-A","DirStats": true,"EnableACL": false
} [format@format.go:564]

在上述命令中,我們指定了對象存儲的相關配置信息:

  • <font style="color:#DF2A3F;">--storage</font>:設置存儲類型,比如 cos、oss、s3 等;
  • <font style="color:#DF2A3F;">--bucket</font>:設置對象存儲的 Endpoint 地址;
  • <font style="color:#DF2A3F;">--access-key</font>:設置對象存儲 API 訪問密鑰 Access Key ID;
  • <font style="color:#DF2A3F;">--secret-key</font>:設置對象存儲 API 訪問密鑰 Access Key Secret。

創建完成即可進行掛載:

[root@k8s-master01 ~]# juicefs mount sqlite3://k8s-test-files.db ~/jfs -d
2025/07/16 21:29:09.579626 juicefs[94136] <INFO>: Meta address: sqlite3://k8s-test-files.db [NewClient@interface.go:578]
2025/07/16 21:29:09.585531 juicefs[94136] <INFO>: Data use oss://k8s-test-files/k8s-test-files/ [mount@mount.go:588]
2025/07/16 21:29:10.091791 juicefs[94136] <INFO>: OK, k8s-test-files is ready at /root/jfs [checkMountpoint@mount_unix.go:235]

掛載命令與使用本地存儲時完全一樣,這是因為創建文件系統時,對象存儲相關的信息已經寫入了 myjfs.db 數據庫,因此客戶端不需要額外提供對象存儲認證信息,也沒有本地配置文件。

相比使用本地磁盤,SQLite 和對象存儲的組合實用價值更高。從應用的角度看,這種形式等同于將容量幾乎無限的對象存儲接入到了本地計算機,讓你可以像使用本地磁盤那樣使用云存儲。

進一步的,該文件系統的所有數據都存儲在云端的對象存儲,因此可以把 k8s-test-files.db 數據庫復制到其他安裝了 JuiceFS 客戶端的計算機上進行掛載和讀寫。也就是說,任何一臺計算機只要能夠讀取到存儲了元數據的數據庫,那么它就能夠掛載讀寫該文件系統。

比如現在我們在 ~/jfs 目錄下面任意創建一些文件:

[root@k8s-master01 ~]# echo testsss > ~/jfs/dujie.txt
[root@k8s-master01 ~]# 
[root@k8s-master01 ~]# cat ~/jfs/dujie.txt
testsss

正常創建完成后該文件會按照 JuiceFS 的文件存儲格式被拆分成特定的「數據塊」并上傳到對象存儲中去,相對應的「元數據」會全部存儲在 k8s-test-files.db 數據庫中。

很顯然,SQLite 這種單文件數據庫很難實現被多臺計算機同時訪問。如果把 SQLite 改為 Redis、PostgreSQL、MySQL 等能夠通過網絡被多臺計算機同時讀寫訪問的數據庫,那么就可以實現 JuiceFS 文件系統的分布式掛載讀寫。

2.4 分布式模式

前面通過采用「對象存儲」和「SQLite」數據庫的組合,實現了一個可以在任意主機上掛載的文件系統。得益于對象存儲可以被網絡上任何有權限的計算機訪問的特點,我們只需要把 SQLite 數據庫文件復制到任何想要訪問該存儲的計算機,就可以實現在不同計算機上訪問同一個 JuiceFS 文件系統。

很顯然,想要依靠在計算機之間復制 SQLite 數據庫的方式進行文件系統共享,雖然可行,但文件的實時性是得不到保證的。受限于 SQLite 這種單文件數據庫無法被多個計算機同時讀寫訪問的情況,為了能夠讓一個文件系統可以在分布式環境中被多個計算機同時掛載讀寫,我們需要采用支持通過網絡訪問的數據庫,比如 Redis、PostgreSQL、MySQL 等。

接下來我們將 SQLite 數據庫替換成基于網絡的數據庫,從而實現 JuiceFS 文件系統的分布式掛載讀寫。JuiceFS 目前支持的基于網絡的數據庫有:

  • 鍵值數據庫:Redis、TiKV
  • 關系型數據庫:PostgreSQL、MySQL、MariaDB

不同的數據庫性能和穩定性表現也各不相同,比如 Redis 是內存型鍵值數據庫,性能極為出色,但可靠性相對較弱。PostgreSQL 是關系型數據庫,相比之下性能沒有內存型強悍,但它的可靠性要更強。我們這里以 Redis 為例來演示分布式模式的使用,我們就直接在 K8s 集群中部署一個簡單的 Redis 服務來進行說明:

apiVersion: apps/v1
kind: Deployment
metadata:name: redis
spec:selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:containers:image: redis/redis-stack-server:6.2.6-v6imagePullPolicy: IfNotPresentname: redisports:- containerPort: 6379protocol: TCP
---
apiVersion: v1
kind: Service
metadata:name: redis
spec:ports:- name: redis-portport: 6379targetPort: 6379selector:app: redistype: NodePort

[root@k8s-master01 ~]# kubectl get pods,svc
NAME                         READY   STATUS    RESTARTS       AGE
pod/redis-6ddf6cf85d-jxpd7   1/1     Running   0              60sNAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/redis        NodePort    10.96.171.175   <none>        6379:32470/TCP   109s

然后接下來我們就可以利用前面的對象存儲和這里的 Redis 來創建一個分布式的 JuiceFS 文件系統了,使用如下所示命令:

[root@k8s-master01 ~]#  juicefs format --storage oss \
>     --bucket https://k8s-test-files.oss-cn-beijing.aliyuncs.com \
>     --access-key xxxxx \
>     --secret-key xxxxxx \
>     redis://192.168.1.20:32470/1 dujiefs2025/07/16 21:41:41.756585 juicefs[102250] <INFO>: Meta address: redis://192.168.1.20:32470/1 [NewClient@interface.go:578]
2025/07/16 21:41:41.763414 juicefs[102250] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [checkRedisInfo@info.go:84]
2025/07/16 21:41:41.764574 juicefs[102250] <INFO>: Ping redis latency: 1.056191ms [checkServerConfig@redis.go:3692]
2025/07/16 21:41:41.766299 juicefs[102250] <INFO>: Data use oss://k8s-test-files/dujiefs/ [format@format.go:527]
2025/07/16 21:41:42.047836 juicefs[102250] <INFO>: Volume is formatted as {"Name": "dujiefs","UUID": "c334b68c-b303-4fdd-9478-4ed101e51d5f","Storage": "oss","Bucket": "https://k8s-test-files.oss-cn-beijing.aliyuncs.com","AccessKey": "xxxxxx","SecretKey": "removed","BlockSize": 4096,"Compression": "none","EncryptAlgo": "aes256gcm-rsa","KeyEncrypted": true,"TrashDays": 1,"MetaVersion": 1,"MinClientVersion": "1.1.0-A","DirStats": true,"EnableACL": false
} [format@format.go:564]

文件系統創建完畢以后,包含對象存儲密鑰等信息會完整的記錄到數據庫中,JuiceFS 客戶端只要擁有數據庫地址、用戶名和密碼信息,就可以掛載讀寫該文件系統,所以 JuiceFS 客戶端不需要本地配置文件。

由于這個文件系統的「數據」和「元數據」都存儲在基于網絡的服務中,因此在任何安裝了 JuiceFS 客戶端的計算機上都可以同時掛載該文件系統進行共享讀寫,例如:

[root@k8s-master01 ~]# juicefs mount redis://192.168.1.20:32470/1 ~/test -d
2025/07/16 21:42:26.584250 juicefs[102790] <INFO>: Meta address: redis://192.168.1.20:32470/1 [NewClient@interface.go:578]
2025/07/16 21:42:26.589964 juicefs[102790] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [checkRedisInfo@info.go:84]
2025/07/16 21:42:26.590998 juicefs[102790] <INFO>: Ping redis latency: 883.641μs [checkServerConfig@redis.go:3692]
2025/07/16 21:42:26.595887 juicefs[102790] <INFO>: Data use oss://k8s-test-files/dujiefs/ [mount@mount.go:588]
2025/07/16 21:42:27.101479 juicefs[102790] <INFO>: OK, dujiefs is ready at /root/test [checkMountpoint@mount_unix.go:235]

2.5 調大緩存提升性能

由于「對象存儲」是基于網絡的存儲服務,不可避免會產生訪問延時。為了解決這個問題,JuiceFS 提供并默認啟用了緩存機制,即劃撥一部分本地存儲作為數據與對象存儲之間的一個緩沖層,讀取文件時會異步地將數據緩存到本地存儲。

緩存機制讓 JuiceFS 可以高效處理海量數據的讀寫任務,默認情況下,JuiceFS 會在 $HOME/.juicefs/cache 或 /var/jfsCache 目錄設置 100GiB 的緩存。在速度更快的 SSD 上設置更大的緩存空間可以有效提升 JuiceFS 的讀寫性能。你可以使用 –cache-dir 調整緩存目錄的位置,使用 –cache-size 調整緩存空間的大小,例如:

[root@k8s-master01 ~]# juicefs mount --background \
>     --cache-dir /mycache \
>     --cache-size 512000 \
>     redis://192.168.1.20:32470/1 \
>     ~/jfs2025/07/16 21:50:15.839157 juicefs[107654] <INFO>: Meta address: redis://192.168.1.20:32470/1 [NewClient@interface.go:578]
2025/07/16 21:50:15.847879 juicefs[107654] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [checkRedisInfo@info.go:84]
2025/07/16 21:50:15.848719 juicefs[107654] <INFO>: Ping redis latency: 692.301μs [checkServerConfig@redis.go:3692]
2025/07/16 21:50:15.851939 juicefs[107654] <INFO>: Data use oss://k8s-test-files/dujiefs/ [mount@mount.go:588]
2025/07/16 21:50:16.361984 juicefs[107654] <INFO>: OK, dujiefs is ready at /root/jfs [checkMountpoint@mount_unix.go:235]

注意:JuiceFS 進程需要具有讀寫 <font style="color:rgb(38, 38, 38);">--cache-dir</font> 目錄的權限。

上述命令將緩存目錄設置在了 <font style="color:rgb(38, 38, 38);">/mycache</font> 目錄,并指定緩存空間為 <font style="color:rgb(38, 38, 38);">500GiB</font>

當掛載好文件系統以后可以通過 <font style="color:#DF2A3F;">juicefs bench</font> 命令對文件系統進行基礎的性能測試和功能驗證,確保 JuiceFS 文件系統能夠正常訪問且性能符合預期。

運行 juicefs bench 命令以后會根據指定的并發度(默認為 1)往 JuiceFS 文件系統中寫入及讀取 N 個大文件(默認為 1)及 N 個小文件(默認為 100),并統計讀寫的吞吐和單次操作的延遲,以及訪問元數據引擎的延遲。測試后可以去對象存儲中查看多了很多數據了。

2.6 生產環境部署

為了保證 JuiceFS 文件系統能符合生產環境的要求,這里給出了如下一些生產環境部署的建議。

2.6.1 監控指標收集與可視化

務必收集 JuiceFS 客戶端的監控指標并通過 Grafana 可視化。

2.6.2 元數據自動備份

元數據自動備份是自 JuiceFS v1.0.0 版本開始加入的特性

元數據對 JuiceFS 文件系統非常關鍵,一旦丟失或損壞將可能影響大批文件甚至整個文件系統。因此必須對元數據進行定期備份。

元數據自動備份特性默認開啟,備份間隔為 1 小時,備份的元數據會經過壓縮后存儲至對應的對象存儲中(與文件系統的數據隔離)。備份由 JuiceFS 客戶端執行,備份期間會導致其 CPU 和內存使用量上升,默認情況下可認為會在所有客戶端中隨機選擇一個執行備份操作。

特別注意默認情況下當文件系統的文件數達到一百萬時,元數據自動備份功能將會關閉,需要配置一個更大的備份間隔(--backup-meta 選項)才會再次開啟。備份間隔每個客戶端獨立配置,設置 --backup-meta 0 則表示關閉元數據自動備份特性。

注意:備份元數據所需的時間取決于具體的元數據引擎,不同元數據引擎會有不同的性能表現。

2.6.3 回收站

回收站是自 JuiceFS v1.0.0 版本開始加入的特性

回收站默認開啟,文件被刪除后的保留時間默認配置為 1 天,可以有效防止數據被誤刪除時造成的數據丟失風險。

不過回收站開啟以后也可能帶來一些副作用,如果應用需要經常刪除文件或者頻繁覆蓋寫文件,會導致對象存儲使用量遠大于文件系統用量。這本質上是因為 JuiceFS 客戶端會將對象存儲上被刪除的文件或者覆蓋寫時產生的需要垃圾回收的數據塊持續保留一段時間。因此,在部署 JuiceFS 至生產環境時就應該考慮好合適的回收站配置,回收站保留時間可以通過以下方式配置(如果將 --trash-days 設置為 0 則表示關閉回收站特性):

  • 新建文件系統:通過 juicefs format--trash-days <value> 選項設置
  • 已有文件系統:通過 juicefs config--trash-days <value> 選項修改

2.6.4 客戶端后臺任務

同一個 JuiceFS 文件系統的所有客戶端在運行過程中共享一個后臺任務集,每個任務定時執行,且具體執行的客戶端隨機選擇。具體的后臺任務包括:

  • 清理待刪除的文件和對象
  • 清理回收站中的過期文件和碎片
  • 清理長時間未響應的客戶端會話
  • 自動備份元數據

由于這些任務執行時會占用一定資源,因此可以為業務較繁重的客戶端配置 --no-bgjob 選項來禁止其參與后臺任務。

注意:請保證至少有一個 JuiceFS 客戶端可以執行后臺任務

2.6.5 客戶端日志滾動

當后臺運行 JuiceFS 掛載點時,客戶端默認會將日志輸出到本地文件中。取決于掛載文件系統時的運行用戶,本地日志文件的路徑稍有區別。root 用戶對應的日志文件路徑是 /var/log/juicefs.log,非 root 用戶的日志文件路徑是 $HOME/.juicefs/juicefs.log

本地日志文件默認不會滾動,生產環境中為了確保日志文件不占用過多磁盤空間需要手動配置。以下是一個日志滾動的示例配置:

# /etc/logrotate.d/juicefs
/var/log/juicefs.log {dailyrotate 7compressdelaycompressmissingoknotifemptycopytruncate
}

通過 logrotate -d /etc/logrotate.d/juicefs 命令可以驗證配置文件的正確性。

三、K8S 中部署

3.1 以 hostPath 方式掛載 JuiceFS

如果你僅僅需要在 Kubernetes 容器中簡單使用 JuiceFS,沒有其他任何復雜要求(比如隔離性、權限控制),那么完全可以以 hostPath 卷的方式使用 JuiceFS,搭建起來也十分簡單。

首先安裝前文的方式在 Kubernetes 節點上統一安裝、掛載 JuiceFS。

然后在 Pod 的資源清單文件定義中使用 hostPath 卷,直接將宿主機上的 JuiceFS 子目錄掛載到容器中即可:

apiVersion: v1
kind: Pod
metadata:name: juicefs-app
spec:containers:- ...volumeMounts:- name: jfs-datamountPath: /opt/app-datavolumes:- name: jfs-datahostPath:path: /jfs/myapp/  # 假設掛載點為 /jfstype: Directory

相比以 CSI 驅動的方式來使用 JuiceFS,hostPath 更為簡單直接,出問題也更易排查,但也要注意:

  • 為管理方便,一般所有容器都在使用同一個宿主機掛載點,缺乏隔離可能導致數據安全問題,未來也無法在不同應用中單獨調整 JuiceFS 掛載參數。請謹慎評估。
  • 所有節點都需要提前掛載 JuiceFS,因此集群加入新節點,需要在初始化流程里進行安裝和掛載,否則新節點沒有 JuiceFS 掛載點,容器將無法創建。
  • 宿主機上的 JuiceFS 掛載進程所占用的系統資源(如 CPU、內存等)不受 Kubernetes 控制,有可能占用較多宿主機資源。可以考慮用 system-reserved 來適當調整 Kubernetes 的系統資源預留值,為 JuiceFS 掛載進程預留更多資源。
  • 如果宿主機上的 JuiceFS 掛載進程意外退出,將會導致應用 Pod 無法正常訪問掛載點,此時需要重新掛載 JuiceFS 文件系統并重建應用 Pod。作為對比,JuiceFS CSI 驅動提供 **「掛載點自動恢復」**功能來解決這個問題。

如果你使用 Docker 作為 Kubernetes 容器運行環境,最好令 JuiceFS 先于 Docker 啟動,否則在節點重啟的時候,偶爾可能出現容器啟動時,JuiceFS 尚未掛載好的情況,此時便會因該依賴問題啟動失敗。以 systemd 為例,可以用下方 unit file 來配置啟動順序:

# /etc/systemd/system/docker.service.d/override.conf
[Unit]
# 請使用下方命令確定 JuiceFS 掛載服務的名稱(例如 jfs.mount):
# systemctl list-units | grep "\.mount"
After=network-online.target firewalld.service containerd.service jfs.mount

3.2 以 CSI 驅動方式掛載 JuiceFS

JuiceFS CSI 驅動遵循 CSI 規范,實現了容器編排系統與 JuiceFS 文件系統之間的接口。在 Kubernetes 下,JuiceFS 可以用 PersistentVolume 的形式提供給 Pod 使用。

3.2.1 CSI 驅動運行模式

整體上 JuiceFS CSI 驅動包含以下組件:<font style="color:#DF2A3F;">JuiceFS CSI Controller(StatefulSet)</font> 以及 <font style="color:#DF2A3F;">JuiceFS CSI Node Service(DaemonSet)</font>

3.2.2 容器掛載模式

CSI 默認采用容器掛載(Mount Pod)模式,也就是讓 JuiceFS 客戶端運行在獨立的 Pod 中,其架構如下:

采用獨立 Mount Pod 來運行 JuiceFS 客戶端,并由 CSI Node Service 來管理 Mount Pod 的生命周期。這樣的架構提供如下好處:

  • 多個 Pod 共用 PV 時,不會新建 Mount Pod,而是對已有的 Mount Pod 做引用計數,計數歸零時刪除 Mount Pod。
  • CSI 驅動組件與客戶端解耦,方便 CSI 驅動自身的升級。

在同一個節點上,一個 PVC 會對應一個 Mount Pod,而使用了相同 PV 的容器,則可以共享一個 Mount Pod。PVC、PV、Mount Pod 之間的關系如下圖所示:

CSI 驅動默認以容器掛載模式運行,但特定場景下該模式不一定適用,因此 CSI 驅動還提供 Sidecar 模式以及進程掛載模式。

3.2.3 Sidecar 模式

Mount Pod 需要由 CSI Node 創建,考慮到 CSI Node 是一個 DaemonSet 組件,如果你的 Kubernetes 集群不支持部署 DaemonSet(比如一些云服務商提供的 Serverless Kubernetes 服務),那么 CSI Node 將無法部署,也就無法正常使用 CSI 驅動。對于這種情況,可以選擇使用 CSI 驅動的 Sidecar 模式,讓 JuiceFS 客戶端運行在 Sidecar 容器中。

以 Sidecar 模式安裝 CSI 驅動,所部署的組件只有 CSI Controller,不再需要 CSI Node。對于需要使用 CSI 驅動的 Kubernetes 命名空間,CSI Controller 會監聽容器變動,檢查是否使用了 JuiceFS PVC,并根據情況為其注入 Sidecar 容器。

創建和使用的流程大致如下:

  • CSI Controller 啟動時,向 API Server 注冊 Webhook;
  • 應用 Pod 指定使用 JuiceFS PVC;
  • API Server 在創建應用 Pod 前調用 CSI Controller 的 Webhook 接口;
  • CSI Controller 向應用 Pod 中注入 Sidecar 容器,容器中運行著 JuiceFS 客戶端;
  • API Server 創建應用 Pod,Sidecar 容器啟動后運行 JuiceFS 客戶端執行掛載,應用容器啟動后可直接訪問文件系統。

使用 Sidecar 模式需要注意:

  • 運行環境需要支持 FUSE,也就是支持以特權容器(Privileged)運行;
  • 不同于 Mount Pod 的容器掛載方式,Sidecar 容器注入進了應用 Pod,因此將無法進行任何復用,大規模場景下,請尤其注意資源規劃和分配;
  • Sidecar 容器和應用容器的掛載點共享是通過 <font style="color:#DF2A3F;">hostPath</font> 實現的,是一個有狀態服務,如果 Sidecar 容器發生意外重啟,應用容器中的掛載點不會自行恢復,需要整個 Pod 重新創建(相較下,Mount Pod 模式則支持掛載點自動恢復);
  • 不要直接從 Mount Pod 模式升級成 Sidecar 模式。已有的 Mount Pod 在 Sidecar 模式下將無法回收。并且一般而言,考慮到 Sidecar 不支持復用,不推薦從 Mount Pod 模式遷移為 Sidecar 模式;
  • 對于啟用了 Sidecar 注入的命名空間,CSI Controller 會監聽該命名空間下創建的所有容器,檢查 PVC 的使用并查詢獲取相關信息。如果希望最大程度地減小開銷,可以在該命名空間下,對不使用 JuiceFS PV 的應用 Pod 打上 <font style="color:#DF2A3F;">disable.sidecar.juicefs.com/inject: true</font> 標簽,讓 CSI Controller 忽略這些不相關的容器。

3.2.4 進程掛載模式

相較于采用獨立 Mount Pod 的容器掛載方式或 Sidecar 模式,CSI 驅動還提供無需獨立 Pod 的進程掛載模式,在這種模式下,CSI Node Service 容器中將會負責運行一個或多個 JuiceFS 客戶端,該節點上所有需要掛載的 JuiceFS PV,均在 CSI Node Service 容器中以進程模式執行掛載。

由于所有 JuiceFS 客戶端均在 CSI Node Service 容器中運行,CSI Node Service 將需要更大的資源聲明,推薦將其資源請求調大到至少 1 CPU 和 1GiB 內存,資源約束調大到至少 2 CPU 和 5GiB 內存,或者根據實際場景資源占用進行調整。

在 Kubernetes 中,容器掛載模式無疑是更加推薦的 CSI 驅動用法,但脫離 Kubernetes 的某些場景,則可能需要選用進程掛載模式。在 v0.10 之前,JuiceFS CSI 驅動僅支持進程掛載模式。而 v0.10 及之后版本則默認為容器掛載模式。

3.3 CSI 驅動安裝

3.3.1 安裝

https://juicefs.com/docs/zh/csi/guide/custom-image

[root@k8s-master01 ~]# helm repo add juicefs https://juicedata.github.io/charts/
"juicefs" has been added to your repositories
[root@k8s-master01 ~]# helm repo update
[root@k8s-master01 ~]# helm fetch --untar juicefs/juicefs-csi-driver
[root@k8s-master01 ~]# cd juicefs-csi-driver
# 查看redis
[root@k8s-master01 ~]# kubectl get svc 
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          4d1h
redis        NodePort    10.96.171.175   <none>        6379:32470/TCP   48m[root@k8s-master01 juicefs-csi-driver]# vim values.yaml 
image:repository: harbor.home.com/library/juicefs-csi-drivertag: "v0.29.0"pullPolicy: ""dashboardImage:repository: harbor.home.com/library/csi-dashboardtag: "v0.29.0"pullPolicy: ""sidecars:livenessProbeImage:repository: harbor.home.com/library/livenessprobetag: "v2.12.0"pullPolicy: ""nodeDriverRegistrarImage:repository: harbor.home.com/library/csi-node-driver-registrartag: "v2.9.0"pullPolicy: ""csiProvisionerImage:repository: harbor.home.com/library/csi-provisionertag: "v2.2.2"pullPolicy: ""csiResizerImage:repository: harbor.home.com/library/csi-resizertag: "v1.9.0"pullPolicy: ""...- pvcSelector:matchLabels:custom-image: "true"# eeMountImage: "juicedata/mount:ee-5.0.17-0c63dc5"ceMountImage: "harbor.home.com/library/mount:ce-v1.3.0"
...
storageClasses:
- name: "juicefs-sc"# Set to true to actually create this StorageClassenabled: false# Set existingSecret to indicate whether to use an existing secret. If it is empty, a corresponding secret will be created according to the plain text configuration.existingSecret: ""# Either Retain or Delete, ref: https://juicefs.com/docs/csi/guide/resource-optimization#reclaim-policyreclaimPolicy: Retain# Set to true to allow PVC expansionallowVolumeExpansion: true# Additional annotations for this StorageClass, e.g. make it default# annotations:#   storageclass.kubernetes.io/is-default-class: "true"backend:# The JuiceFS file system namename: "juicefs"# Connection URL for metadata engine (e.g. Redis), for community edition use only, ref: https://juicefs.com/docs/community/databases_for_metadatametaurl: "redis://192.168.1.20:32470/1"# Object storage type, such as s3, gs, oss, for community edition use only, ref: https://juicefs.com/docs/community/how_to_setup_object_storagestorage: "oss"# Bucket URL, for community edition use only, ref: https://juicefs.com/docs/community/how_to_setup_object_storagebucket: "https://k8s-test-files.oss-cn-beijing.aliyuncs.com"# Token for JuiceFS Enterprise Edition token, ref: https://juicefs.com/docs/cloud/acltoken: ""# Access key for object storageaccessKey: "xxxxx"# Secret key for object storagesecretKey: "xxxxx"pathPattern: "${.PVC.namespace}-${.PVC.name}"mountPod:# Mount pod resource requests & limitsresources:limits:cpu: 5000mmemory: 5Girequests:cpu: 1000mmemory: 1Gi# Override mount pod image, ref: https://juicefs.com/docs/csi/guide/custom-imageimage: "harbor.home.com/library/mount:ce-v1.3.0"# Set annotations for the mount podannotations: {}

安裝

[root@k8s-master01 juicefs-csi-driver]# helm upgrade --install juicefs-csi-driver juicefs/juicefs-csi-driver -n kube-system -f ./values.yaml

3.3.2 創建 secret

apiVersion: v1
kind: Secret
metadata:name: juicefs-secretnamespace: kube-system
type: Opaque
stringData:name: juicefs-vol             access-key: xxxx     secret-key: xxxxx# follows are for JuiceFS enterprise# follows are for JuiceFS communitymetaurl:  redis://192.168.1.20:32470storage: ossbucket:  https://k8s-test-files.oss-cn-beijing.aliyuncs.com

3.3.3 創建 storageclass

StorageClass(存儲類)里指定了創建 PV 所需的各類配置,你可以將其理解為動態配置下的「Profile」:不同的 StorageClass 就是不同的 Profile,可以在其中指定不同的文件系統認證信息、掛載配置,讓動態配置下可以同時使用不同的文件系統,或者指定不同的掛載。因此如果你打算以「動態配置」或「通用臨時卷」的方式使用 JuiceFS CSI 驅動,那么你需要提前創建 StorageClass。

注意,StorageClass 僅僅是動態配置下用于創建 PV 的「模板」,也正因此,使用的時候必須注意:

  • 在 StorageClass 中修改掛載配置,不影響已經創建的 PV。 對于已有的 PV,需要直接在 PV 級別調整掛載配置,或者干脆刪除 PVC 重建;
  • 自 v0.24.3 開始,可以在 ConfigMap 中使用 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">matchStorageClassName</font> 來方便地選擇已有 PVC,更推薦用這種方式來修改 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-secretcsi.storage.k8s.io/provisioner-secret-namespace: kube-systemcsi.storage.k8s.io/node-publish-secret-name: juicefs-secretcsi.storage.k8s.io/node-publish-secret-namespace: kube-systemjuicefs/mount-image: harbor.home.com/library/mount:ce-v1.3.0

3.4 測試

部署完成后我們可以安裝上面的提示來創建一個 PVC 和 Pod 進行測試下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: juicefs-pvcnamespace: test
spec:accessModes:- ReadWriteManyresources:requests:storage: 200GstorageClassName: juicefs-sc
--- 
apiVersion: v1
kind: Pod
metadata:name: juicefs-app
spec:containers:- args:- -c- while true; do echo $(date -u) >> /data/out.txt; sleep 5; donecommand:- /bin/shimage: busyboxname: appvolumeMounts:- mountPath: /dataname: juicefs-pvvolumes:- name: juicefs-pvpersistentVolumeClaim:claimName: juicefs-pvc
[root@k8s-master01 jfs]# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
juicefs-pvc   Bound    pvc-cf9cac89-96a8-4bb6-a97b-327c67a2c183   200G       RWX            juicefs-sc     <unset>                 2m11s

默認情況下 JuiceFS CSI 采用容器掛載(Mount Pod)模式,會讓 JuiceFS 客戶端運行在獨立的 Pod 中,所以當我們創建上面的 Pod 后,會先創建一個獨立的 Mount Pod:

[root@k8s-master01 jfs]# kubectl get pods -n kube-system -l app.kubernetes.io/name=juicefs-mount
NAME                                                                 READY   STATUS    RESTARTS      AGE
juicefs-k8s-node03-pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn   1/1     Running   0             69s[root@k8s-master01 juicefs-csi-driver]# kubectl logs -f -n kube-system juicefs-k8s-node03-pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn 
2025/07/17 03:43:51.354741 juicefs[7] <INFO>: Meta address: redis://192.168.1.20:32470 [NewClient@interface.go:578]
2025/07/17 03:43:51.361287 juicefs[7] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [checkRedisInfo@info.go:84]
2025/07/17 03:43:51.362623 juicefs[7] <INFO>: Ping redis latency: 1.228855ms [checkServerConfig@redis.go:3692]
2025/07/17 03:43:51.364295 juicefs[7] <INFO>: Data use oss://k8s-test-files/juicefs-vol/ [format@format.go:527]
2025/07/17 03:43:51.648929 juicefs[7] <INFO>: Volume is formatted as {"Name": "juicefs-vol","UUID": "82ef5f79-f254-4bdf-9aae-7954d0354fc8","Storage": "oss","Bucket": "https://k8s-test-files.oss-cn-beijing.aliyuncs.com","AccessKey": "xxxxx","SecretKey": "removed","BlockSize": 4096,"Compression": "none","EncryptAlgo": "aes256gcm-rsa","KeyEncrypted": true,"TrashDays": 1,"MetaVersion": 1,"MinClientVersion": "1.1.0-A","DirStats": true,"EnableACL": false
} [format@format.go:564]
2025/07/17 03:43:52.504044 juicefs[1] <INFO>: Meta address: redis://192.168.1.20:32470 [NewClient@interface.go:578]
2025/07/17 03:43:52.516657 juicefs[1] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [checkRedisInfo@info.go:84]
2025/07/17 03:43:52.517924 juicefs[1] <INFO>: Ping redis latency: 1.155465ms [checkServerConfig@redis.go:3692]
2025/07/17 03:43:52.529824 juicefs[1] <INFO>: Data use oss://k8s-test-files/juicefs-vol/ [mount@mount.go:588]
2025/07/17 03:43:53.760643 juicefs[24] <INFO>: Meta address: redis://192.168.1.20:32470 [NewClient@interface.go:578]
2025/07/17 03:43:53.852370 juicefs[24] <WARNING>: AOF is not enabled, you may lose data if Redis is not shutdown properly. [checkRedisInfo@info.go:84]
2025/07/17 03:43:53.886953 juicefs[24] <INFO>: Ping redis latency: 34.404648ms [checkServerConfig@redis.go:3692]
2025/07/17 03:43:54.032569 juicefs[24] <INFO>: Data use oss://k8s-test-files/juicefs-vol/ [mount@mount.go:588]
2025/07/17 03:43:54.032693 juicefs[24] <INFO>: JuiceFS version 1.3.0+2025-07-03.30190ca1 [mount@mount.go:631]
2025/07/17 03:43:54.081067 juicefs[24] <INFO>: Disk cache (/var/jfsCache/82ef5f79-f254-4bdf-9aae-7954d0354fc8/): used ratio - [space 45.5%, inode 1.1%] [newCacheStore@disk_cache.go:147]
2025/07/17 03:43:54.081198 juicefs[24] <INFO>: Adjusted cache capacity based on freeratio: from 107374182400 to 67612702976 bytes [setlimitByFreeRatio@disk_cache.go:171]
2025/07/17 03:43:54.081223 juicefs[24] <INFO>: Adjusted max items based on freeratio: from 0 to 33030143 items [setlimitByFreeRatio@disk_cache.go:176]
2025/07/17 03:43:54.092159 juicefs[24] <INFO>: Create session 2 OK with version: 1.3.0+2025-07-03.30190ca1 [NewSession@base.go:535]
2025/07/17 03:43:54.097453 juicefs[24] <INFO>: Prometheus metrics listening on [::]:9567 [exposeMetrics@mount.go:134]
2025/07/17 03:43:54.106918 juicefs[24] <INFO>: Add fuse.juicefs into PRUNEFS of /etc/updatedb.conf [disableUpdatedb@mount_unix.go:448]
2025/07/17 03:43:54.107215 juicefs[24] <INFO>: Mounting volume juicefs-vol at /jfs/pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn ... [mountMain@mount_unix.go:1027]
2025/07/17 03:43:54.548096 juicefs[1] <INFO>: OK, juicefs-vol is ready at /jfs/pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn [checkMountpoint@mount_unix.go:235]
2025-07-17 03:43:57.640297 I | Unimplemented opcode POLL
2025/07/17 03:43:57.642404 juicefs[1] <INFO>: watching /jfs/pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn, pid 24 [watchdog@mount_unix.go:162]

可以看到 Mount Pod 已經成功掛載了 JuiceFS 文件系統,接下來我們再看下我們創建的 Pod:

[root@k8s-master01 juicefs-csi-driver]# kubectl get pods -n test 
NAME          READY   STATUS    RESTARTS   AGE
juicefs-app   1/1     Running   0          2m28s
[root@k8s-master01 juicefs-csi-driver]# 
[root@k8s-master01 juicefs-csi-driver]# kubectl get pvc -n test 
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
juicefs-pvc   Bound    pvc-61b5439f-ab85-4ec8-824e-918f1c445143   200G       RWX            juicefs-sc     <unset>                 2m28s
[root@k8s-master01 juicefs-csi-driver]# kubectl exec -it -n test juicefs-app  sh 
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # 
/ # ls /data
out.txt
/ # 
/ # cat /data/out.txt
Thu Jul 17 03:43:56 UTC 2025
Thu Jul 17 03:44:01 UTC 2025
Thu Jul 17 03:44:06 UTC 2025
Thu Jul 17 03:44:11 UTC 2025
Thu Jul 17 03:44:16 UTC 2025
Thu Jul 17 03:44:21 UTC 2025
Thu Jul 17 03:44:26 UTC 2025

這個時候 Pod 中的 /data 目錄已經成功掛載了 JuiceFS 文件系統,我們可以前往 Mount Pod 中查看下:

[root@k8s-master01 jfs]# kubectl exec -it -n kube-system juicefs-k8s-node03-pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn  sh 
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
# 
# ls /jfs
pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn
# ls /jfs/pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn
out.txt
# head -n 5 /jfs/pvc-61b5439f-ab85-4ec8-824e-918f1c445143-ogcbtn/out.txt
Thu Jul 17 03:43:56 UTC 2025
Thu Jul 17 03:44:01 UTC 2025
Thu Jul 17 03:44:06 UTC 2025
Thu Jul 17 03:44:11 UTC 2025
Thu Jul 17 03:44:16 UTC 2025

3.5 靜態 PV

上面安裝 JuiceFS CSI Driver 后手動創建了一個 StorageClass,所以我們可以直接使用這個 StorageClass 來創建 PVC,但是如果我們想要使用靜態 PV 的話,我們就需要手動創建 PV 和 PVC,下面我們就來看下如何創建靜態 PV。首先手動創建一個 PV,創建所需的資源定義示范如下:

apiVersion: v1
kind: PersistentVolume
metadata:name: juicefs-static-pvlabels:juicefs-name: ten-gb-fs
spec:capacity:storage: 10GivolumeMode: FilesystemaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Retaincsi:# 在先前的安裝步驟中,已經創建了名為 csi.juicefs.com 的 CSIDriver# 可以使用 kubectl get csidriver csi.juicefs.com 查看driver: csi.juicefs.com# volumeHandle 需要保證集群內唯一,因此一般直接用 PV 名即可volumeHandle: juicefs-pvfsType: juicefs# 在先前的步驟中已經創建好文件系統認證信息(Secret),在這里引用# 如果要在靜態配置下使用不同的認證信息,甚至使用不同的 JuiceFS 文件系統,則需要創建不同的 SecretnodePublishSecretRef:name: juicefs-secret namespace: kube-system
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: juicefs-static-pvcnamespace: default
spec:accessModes:- ReadWriteManyvolumeMode: Filesystem# 靜態配置下必須指定 storageClassName 為空字符串# 代表該 PV 不采用任何 StorageClass,而是直接使用 selector 所指定的 PVstorageClassName: ""# 由于目前 JuiceFS CSI 驅動不支持設置存儲容量,此處 requests.storage 填寫任意小于等于 PV capacity 的有效值即可resources:requests:storage: 10Giselector:matchLabels:juicefs-name: ten-gb-fs

然后再創建一個應用 Pod,并在其中引用上面的 PVC:

apiVersion: v1
kind: Pod
metadata:name: juicefs-appnamespace: default
spec:containers:- args:- -c- while true; do echo $(date -u) >> /data/out.txt; sleep 5; donecommand:- /bin/shimage: busyboxname: appvolumeMounts:- mountPath: /dataname: dataresources:requests:cpu: 10mvolumes:- name: datapersistentVolumeClaim:claimName: juicefs-static-pvc

? kubectl get pv juicefs-static-pv
NAME                CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                        STORAGECLASS   REASON   AGE
juicefs-static-pv   10Gi       RWX            Retain           Bound    default/juicefs-static-pvc                           9s
? kubectl get pvc juicefs-static-pvc
NAME                 STATUS   VOLUME              CAPACITY   ACCESS MODES   STORAGECLASS   AGE
juicefs-static-pvc   Bound    juicefs-static-pv   10Gi       RWX                           15s
? kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
juicefs-app   1/1     Running   0          58s

此外如果想要在不同命名空間中共享同一個文件系統,只需要讓不同 PV 使用相同的文件系統認證信息(Secret)即可:

apiVersion: v1
kind: PersistentVolume
metadata:name: mypv1namespace: ns1labels:pv-name: mypv1
spec:csi:nodePublishSecretRef:name: juicefs-sc-secretnamespace: kube-system...
---
apiVersion: v1
kind: PersistentVolume
metadata:name: mypv2namespace: ns2labels:pv-name: mypv2
spec:csi:nodePublishSecretRef:name: juicefs-sc-secretnamespace: kube-system...

這樣也就不會重復創建 Mount Pod 了。默認情況下,僅在多個應用 Pod 使用相同 PV 時,Mount Pod 才會被復用。如果你希望進一步降低開銷,可以更加激進地復用 Mount Pod,讓使用相同 StorageClass 創建出來的所有 PV,都復用同一個 Mount Pod(當然復用只能發生在同一個節點)。不同的應用 Pod,將會綁定掛載點下不同的路徑,實現一個掛載點為多個應用容器提供服務。

為相同 StorageClass PV 復用 Mount Pod,需要為 CSI Node Service 添加 <font style="color:rgb(38, 38, 38);">STORAGE_CLASS_SHARE_MOUNT</font> 這個環境變量:

? kubectl -n kube-system set env -c juicefs-plugin daemonset/juicefs-csi-node STORAGE_CLASS_SHARE_MOUNT=true

但是高度復用意味著更低的隔離程度,如果 Mount Pod 發生意外,掛載點異常,影響面也會更大,因此如果你決定啟用該復用策略,請務必同時啟用「掛載點自動恢復」(JuiceFS CSI 驅動自 v0.10.7 開始支持掛載點自動恢復:當 Mount Pod 遭遇故障,重啟或重新創建 Mount Pod 以后,應用容器也能繼續工作。),以及合理增加 「Mount Pod 的資源請求」。

四、高級功能與配置

4.1 ConfigMap 配置

從 v0.24 開始,CSI 驅動支持在名為 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">juicefs-csi-driver-config</font> 的 ConfigMap 中書寫配置,支持多種多樣的配置項,既可以用來配置 Mount Pod 或 sidecar,也包含 CSI 驅動自身的配置,并且支持動態更新:修改 Mount Pod 配置時不需要重建 PV,修改 CSI 自身配置時,也不需要重啟 CSI Node 或者 Controller。

由于 ConfigMap 功能強大、更加靈活,它將會或已經取代從前在 CSI 驅動中各種修改配置的方式,例如下方標有「不推薦」的小節,均為舊版中靈活性欠佳的實踐,請及時棄用。簡而言之,如果一項配置已經在 ConfigMap 中得到支持,則在 ConfigMap 中具有最高優先級,因此請優先在 ConfigMap 中對其進行配置,棄用舊版本中的實踐。

修改 ConfigMap 以后,相關改動并不會立刻生效,這是由于掛載進容器的 ConfigMap 并非實時更新,而是定期同步(詳見 Kubernetes 官方文檔)。

如果希望立即生效,可以給 CSI 組件臨時添加 Annotation 來觸發更新:

kubectl -n kube-system annotate pods -l app.kubernetes.io/name=juicefs-csi-driver useless-annotation=true

ConfigMap 生效后,后續創建的 Mount Pod 都會應用新的配置,但已有的 Mount Pod 并不會自動更新! 根據所修改的項目不同,可能需要重建應用 Pod 或者 Mount Pod,方可令修改生效。請繼續閱讀下方相關章節了解各自項目具體的生效條件。
ConfigMap 中支持的所有配置項,都可以在這里找到示范

globalConfig:# 支持模板變量,比如 ${MOUNT_POINT}、${SUB_PATH}、${VOLUME_ID}mountPodPatch:# 未定義 pvcSelector,則為全局配置- lifecycle:preStop:exec:command:- sh- -c- +e- umount -l ${MOUNT_POINT}; rmdir ${MOUNT_POINT}; exit 0# 如果多個 pvcSelector 匹配的是相同的 PVC,則后定義的配置會覆蓋更早定義的配置- pvcSelector:matchLabels:mylabel1: "value1"# 啟用 host networkhostNetwork: true- pvcSelector:matchLabels:mylabel2: "value2"# 增加 labelslabels:custom-labels: "mylabels"- pvcSelector:matchLabels:...# 修改資源定義resources:requests:cpu: 100mmemory: 512Mi- pvcSelector:matchLabels:...readinessProbe:exec:command:- stat- ${MOUNT_POINT}/${SUB_PATH}failureThreshold: 3initialDelaySeconds: 10periodSeconds: 5successThreshold: 1- pvcSelector:matchLabels:...# 目前暫不推薦使用 liveness probe,請優先使用 readiness probe# JuiceFS 客戶端自身也會進行檢活和重啟,因此避免額外設置 liveness probe,從外部重啟livenessProbe:exec:command:- stat- ${MOUNT_POINT}/${SUB_PATH}failureThreshold: 3initialDelaySeconds: 10periodSeconds: 5successThreshold: 1- pvcSelector:matchLabels:...annotations:# 延遲刪除juicefs-delete-delay: 5m# 退出時清理 cachejuicefs-clean-cache: "true"# 為 Mount Pod 注入環境變量- pvcSelector:matchLabels:...env:- name: DEMO_GREETINGvalue: "Hello from the environment"- name: DEMO_FAREWELLvalue: "Such a sweet sorrow"# 掛載 volumes 到 Mount Pod- pvcSelector:matchLabels:...volumeDevices:- name: block-devicesdevicePath: /dev/sda1volumes:- name: block-devicespersistentVolumeClaim:claimName: block-pv# 選擇特定的 StorageClass- pvcSelector:matchStorageClassName: juicefs-scterminationGracePeriodSeconds: 60# 選擇特定的 PVC- pvcSelector:matchName: pvc-nameterminationGracePeriodSeconds: 60

4.2 定制 MountPod 容器或 Sidecar 容器

通過 ConfigMap 修改配置后,推薦使用「平滑升級 Mount Pod」特性來在不重建應用 Pod 的情況下使修改生效,但是需要注意,請升級到 v0.25.2 或更新版本,v0.25.0(該功能首次發布)尚不支持某些配置平滑升級,如果希望充分利用平滑升級的能力,務必升級到最新版再操作。

如果仍在使用舊版、無法享受到平滑升級,則需要根據情況來重建應用 Pod 或 Mount Pod,具體操作在下方,請務必提前配置好「掛載點自動恢復」,避免重建 Mount Pod 后,應用 Pod 中的掛載點永久丟失。

4.2.1 環境變量

4.2.1.1 使用 ConfigMap

該功能最低需要 CSI 驅動版本 v0.24.5,修改后需要重建業務 Pod 生效。

  mountPodPatch:- env:- name: DEMO_GREETINGvalue: "Hello from the environment"- name: DEMO_FAREWELLvalue: "Such a sweet sorrow"
4.2.1.2 使用 Secret
apiVersion: v1
kind: Secret
metadata:name: juicefs-secretnamespace: defaultlabels:# 增加該標簽以啟用認證信息校驗juicefs.com/validate-secret: "true"
type: Opaque
stringData:envs: '{"BASE_URL": "http://10.0.0.1:8080/static"}'

4.2.2 資源限制

該特性需要的 CSI 驅動最低版本為 0.24.0,示例如下:

  mountPodPatch:- resources:requests:cpu: 100mmemory: 512Mi

4.2.3 掛載參數

https://juicefs.com/docs/zh/community/command_reference/#mount

每一個 JuiceFS 掛載點都是 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">juicefs mount</font> 命令創建的,在 CSI 驅動體系中,需要通過 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">mountOptions</font> 字段填寫需要調整的掛載配置。

<font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">mountOptions</font> 同時支持 JuiceFS 本身的掛載參數和 FUSE 相關選項。但要注意,雖然 FUSE 參數在命令行使用時會用 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">-o</font> 傳入,但在 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">mountOptions</font> 中需要省略 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">-o</font>,直接在列表中追加參數即可。以下方掛載命令為例:

juicefs mount ... --cache-size=204800 -o writeback_cache,debug

翻譯成 CSI 中的 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">mountOptions</font>,格式如下:

mountOptions:# JuiceFS mount options- cache-size=204800# 額外的 FUSE 相關選項- writeback_cache- debug

4.2.4 使用 ConfigMap

該功能最小需要 CSI 驅動 v0.24.7。修改 ConfigMap 相關配置后,需重建業務 Pod 生效。

ConfigMap 中的配置具備最高優先級,他會遞歸合并覆蓋 PV 中的 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">mountOptions</font>,因此為了避免出現“修改了卻不生效”的誤用情況,建議將所有配置遷移到 ConfigMap,不再繼續使用 PV 級別的 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">mountOptions</font>

靈活使用 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">pvcSelector</font> 可實現批量修改 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">mountOptions</font> 的目的。

  mountPodPatch:- pvcSelector:matchLabels:# 所有含有此 label 的 PVC 都將應用此配置need-update-options: "true"mountOptions:- writeback- cache-size=204800

4.2.5 健康檢查&容器回調

該特性需要的 CSI 驅動最低版本為 0.24.0,使用場景:

  • 配合 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">readinessProbe</font> 配合監控體系,建立告警機制;
  • 定制 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">preStopHook</font>,避免 sidecar 場景中,掛載容器早于業務容器退出,造成業務波動。詳見 Sidecar 模式推薦設置。
  - pvcSelector:matchLabels:custom-probe: "true"readinessProbe:exec:command:- stat- ${MOUNT_POINT}/${SUB_PATH}failureThreshold: 3initialDelaySeconds: 10periodSeconds: 5successThreshold: 1

4.2.6 掛載額外的 Volume

使用場景:

  • 部分對象存儲服務(比如 Google 云存儲)在訪問時需要提供額外的認證文件,這就需要你用創建單獨的 Secret 保存這些文件,然后在認證信息中引用。這樣一來,CSI 驅動便會將這些文件掛載進 Mount Pod,然后在 Mount Pod 中添加對應的環境變量,令 JuiceFS 掛載時使用該文件進行對象存儲的認證。
  • JuiceFS 企業版支持掛載共享塊設備,既可以作為緩存存儲,也可以配置成數據塊的永久存儲。
4.2.6.1 使用 ConfigMap

該功能最低需要 CSI 驅動版本 v0.24.7,修改后需重建業務 Pod 生效。

  # mount some volumes to the Mount Pod- pvcSelector:matchLabels:need-block-device: "true"volumeDevices:- name: block-devicesdevicePath: /dev/sda1volumes:- name: block-devicespersistentVolumeClaim:claimName: block-pv- pvcSelector:matchLabels:need-mount-secret: "true"volumeMounts:- name: config-1mountPath: /root/.config/gcloudvolumes:- name: gc-secretsecret:secretName: gc-secretdefaultMode: 420
4.2.6.2 使用 secret

在 JuiceFS Secret 的 <font style="color:#DF2A3F;background-color:rgb(246, 247, 248);">configs</font> 字段中,只能掛載額外的 Secret,無法配置共享塊設備的掛載。

apiVersion: v1
kind: Secret
metadata:name: juicefs-secret
type: Opaque
stringData:...# 在 configs 中填寫 Secret 名稱和掛載目錄,將該 Secret 整體掛載進指定的目錄configs: "{gc-secret: /root/.config/gcloud}"

4.3 應用間共享存儲

如果你在 JuiceFS 文件系統已經存儲了大量數據,希望掛載進容器使用,或者希望讓多個應用共享同一個 JuiceFS 目錄,有以下做法:

4.3.1 掛載子目錄

掛載子目錄有兩種方式,一種是通過 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">--subdir</font> 掛載選項,另一種是通過 volumeMounts.subPath屬性,下面分別介紹。

  • 使用**** **<font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">--subdir</font>** ****掛載選項

修改「掛載參數」,用 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">subdir</font> 參數掛載子目錄。如果子目錄尚不存在,CSI Controller 會在掛載前自動創建。

apiVersion: v1
kind: PersistentVolume
metadata:name: juicefs-pvlabels:juicefs-name: ten-pb-fs
spec:mountOptions:- subdir=/my/sub/dir...
  • 使用 **<font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">volumeMounts.subPath</font>** 屬性
apiVersion: v1
kind: Pod
metadata:name: juicefs-appnamespace: default
spec:containers:- volumeMounts:- name: datamountPath: /data# 注意 subPath 只能用相對路徑,不能用絕對路徑。subPath: my/sub/dir...volumes:- name: datapersistentVolumeClaim:claimName: juicefs-pvc

如果在同一臺宿主機上可能會運行多個應用 Pod,并且這些應用 Pod 需要掛載同一個文件系統的不同子目錄,那么建議使用 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">volumeMounts.subPath</font> 屬性來掛載,因為這種方式只會創建 1 個 Mount Pod,可以大大節省宿主機的資源。

4.3.2 跨命名空間共享同一個文件系統

如果想要在不同命名空間中共享同一個文件系統,只需要讓不同 PV 使用相同的文件系統認證信息(Secret)即可:

apiVersion: v1
kind: PersistentVolume
metadata:name: mypv1labels:pv-name: mypv1
spec:csi:nodePublishSecretRef:name: juicefs-secretnamespace: default...
---
apiVersion: v1
kind: PersistentVolume
metadata:name: mypv2labels:pv-name: mypv2
spec:csi:nodePublishSecretRef:name: juicefs-secretnamespace: default...

4.4 常用 PV 設置

4.4.1 PV 容量分配

從 v0.19.3 開始,JuiceFS CSI 驅動支持在動態配置設置存儲容量(要注意,僅支持動態配置)。

在靜態配置中,PVC 中指定的容量會被忽略,填寫任意有效值即可,建議填寫一個較大的數值,避免未來版本如果帶來該功能支持時,因為容量超限導致問題。

...
storageClassName: ""
resources:requests:storage: 10Ti

而在動態配置中,可以在 PVC 中指定存儲容量,這個容量限制將會被翻譯成 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">juicefs quota</font> 命令,在 CSI Controller 中執行,為該 PV 所對應的子目錄添加容量限制。關于 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">juicefs quota</font> 命令,可以參考社區版文檔

...
storageClassName: juicefs-sc
resources:requests:storage: 100Gi

創建并掛載好 PV 后,可以進入容器用 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">df -h</font> 驗證容量生效:

$ df -h
Filesystem         Size  Used Avail Use% Mounted on
overlay             84G   66G   18G  80% /
tmpfs               64M     0   64M   0% /dev
JuiceFS:myjfs       100G     0  100G   0% /data-0

4.4.2 PV 擴容

在 JuiceFS CSI 驅動 0.21.0 及以上版本,支持動態擴展 PersistentVolume 的容量(僅支持動態配置)。需要在 StorageClass 中指定 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">allowVolumeExpansion: true</font>,同時指定擴容時所需使用的 Secret,主要提供文件系統的認證信息,例如:

apiVersion: storage.k8s.io/v1
kind: StorageClass
...
parameters:csi.storage.k8s.io/node-publish-secret-name: juicefs-secretcsi.storage.k8s.io/node-publish-secret-namespace: defaultcsi.storage.k8s.io/provisioner-secret-name: juicefs-secretcsi.storage.k8s.io/provisioner-secret-namespace: defaultcsi.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 的 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">spec</font> 字段,指定更大的存儲請求,可以觸發 PersistentVolume 的擴充:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: myclaim
spec:accessModes:- ReadWriteOnceresources:requests:storage: 20Gi  # 在此處指定更大的容量
上述方法對存量 PV 不生效,如果需要對擴容存量 PV,需要手動修改 PV,為其增加 Secret 配置:
apiVersion: v1
kind: PersistentVolume
metadata:name: pvc-xxxx
spec:csi:controllerExpandSecretRef:name: juicefs-secretnamespace: default

4.4.3 回收策略

靜態配置下僅支持 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">persistentVolumeReclaimPolicy: Retain</font>,無法隨著刪除回收。

動態配置支持 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">Delete|Retain</font> 兩種回收策略,按需使用。<font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">Delete</font> 會導致 JuiceFS 內的 PVC 子目錄隨著 PV 刪除一起釋放,如果擔心數據安全,可以配合 JuiceFS 的回收站功能一起使用:

  • 社區版回收站文檔
  • 企業版回收站文檔

4.4.4 給 Monut Pod 掛載宿主機目錄

如果希望在 Mount Pod 中掛載宿主機文件或目錄,可以聲明 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">juicefs/host-path</font>,可以在這個字段中填寫多個文件映射,逗號分隔。這個字段在靜態和動態配置方式中填寫位置不同,以 <font style="color:rgb(28, 30, 33);background-color:rgb(246, 247, 248);">/data/file.txt</font> 這個文件為例。

靜態配置:

apiVersion: v1
kind: PersistentVolume
metadata:name: juicefs-pvlabels:juicefs-name: ten-pb-fs
spec:...csi:driver: csi.juicefs.comvolumeHandle: juicefs-pvfsType: juicefsnodePublishSecretRef:name: juicefs-secretnamespace: defaultvolumeAttributes:juicefs/host-path: /data/file.txt

動態配置

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: juicefs-sc
provisioner: csi.juicefs.com
parameters:juicefs/host-path: /data/file.txt

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94556.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94556.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94556.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【HarmonyOS Next之旅】DevEco Studio使用指南(三十八) -> 構建HAR

目錄 1 -> 前言 2 -> 使用約束 3 -> 創建模塊 4 -> 構建HAR 4.1 -> 以debug模式構建HAR 4.2 -> 以release模式構建HAR 4.3 -> 構建字節碼格式的HAR 4.4 -> 對HAR進行簽名 1 -> 前言 構建模式&#xff1a;DevEco Studio默認提供debug和rele…

93、【OS】【Nuttx】【構建】cmake menuconfig 目標

【聲明】本博客所有內容均為個人業余時間創作&#xff0c;所述技術案例均來自公開開源項目&#xff08;如Github&#xff0c;Apache基金會&#xff09;&#xff0c;不涉及任何企業機密或未公開技術&#xff0c;如有侵權請聯系刪除 背景 接之前 blog 【OS】【Nuttx】【構建】cm…

React 表單處理:移動端輸入場景下的卡頓問題與防抖優化方案

文章目錄每日一句正能量前言一、問題場景與表現二、技術攻堅過程三、優化效果與經驗沉淀每日一句正能量 山再高&#xff0c;往上攀&#xff0c;總能登頂&#xff1b;路再長&#xff0c;走下去&#xff0c;終將到達。每日一勵&#xff0c;勇往直前。 前言 在移動端 React 項目開…

數據安全防護所需要的關鍵要素

數據安全防護是一個覆蓋數據全生命周期&#xff08;采集、存儲、傳輸、處理、銷毀&#xff09;、融合技術、管理、流程與人員的系統性工程。其核心目標是保障數據的??保密性&#xff08;Confidentiality&#xff09;、完整性&#xff08;Integrity&#xff09;、可用性&#…

【JavaEE】(8) 網絡原理 HTTP/HTTPS

一、什么是 HTTP 協議 上節說到&#xff0c;應用層的協議需要約定通信的內容和數據格式。我們可以自定義應用層協議&#xff0c;也可以基于現成的應用層協議進行開發。協議的種類很多&#xff0c;最常見的之一就是 HTTP&#xff0c;廣泛用于網站和手機 App。準確來說&#xff0…

C語言的數組與字符串練習題4

C語言的數組與字符串練習題4 16. 數組元素去重 題目描述: 編寫一個C程序,輸入一組整數存儲在數組中,去除數組中的重復元素,并輸出去重后的數組。 解題思路: 遍歷數組,對于每個元素,檢查它之前是否已經存在相同的元素。如果不存在,則將其保留;否則,跳過。可以使用一…

Transformers簡單介紹 - 來源于huggingface

Transformers介紹 - 來源于huggingface 文章目錄Transformers介紹 - 來源于huggingfaceTransformers能做什么pipeline()函數零樣本分類推理API完形填空命名實體識別問答摘要提取翻譯transformers是如何工作的transformers的具體組成注意力層機制transformers原始結構architectu…

template<typename R = void> 意義

在 C 中&#xff0c;template<typename R void> 表示定義一個模板參數 R&#xff0c;其默認類型為 void。這意味著&#xff1a;如果用戶沒有顯式指定 R&#xff0c;則 R 默認為 void。如果用戶顯式指定了 R&#xff08;如 template<typename R void> 后面跟著 &l…

國產3D大型裝配設計新突破①:圖紙打開設計雙加速 | 中望3D 2026

本文為CAD芯智庫整理&#xff0c;未經允許請勿復制、轉載&#xff01;在中望3D 2026的新版中&#xff0c;不僅在設計效率上進行了重大優化&#xff0c;更是在裝配方面實現了突破性的改進&#xff0c;讓每一個項目都能快速、精確地從概念變為現實。 中望3D2026亮點速遞裝配篇將…

游戲開發狀態機與行為樹的優缺點

在游戲開發中&#xff0c;狀態機&#xff08;Finite State Machine, FSM&#xff09; 和行為樹&#xff08;Behavior Tree, BT&#xff09; 是兩種常用的 AI 邏輯控制框架&#xff0c;分別適用于不同場景&#xff0c;其優缺點對比可從靈活性、維護成本、適用場景等多個維度分析…

Linux下ELF文件的介紹

目錄 1.溫故知新 2.ELF文件介紹 3.ELF文件組成 4.ELF文件形成到加載 5.連接過程 1.溫故知新 上一篇博客&#xff0c;我們介紹了我們的動靜態&#xff0c;知道了我們的庫其實也是文件&#xff0c;如果我們想寫一個庫也是可以的&#xff0c;我們的把我們的庫文件編譯成.o文件…

人工智能領域、圖歐科技、IMYAI智能助手2025年6月更新月報

2025年6月AI領域重要模型更新與平臺優化匯總 摘要&#xff1a; 本文匯總了2025年6月期間AI領域發布的多項重要模型更新及平臺功能優化信息&#xff0c;涵蓋Google Gemini、阿里通義萬相、字節豆包、百度文心一言、MiniMax海螺02、Google Veo3、快手可靈2.1、FLUX Kontext等模型…

從零開始學Express,理解服務器,路由于中間件

當我們初學前端時&#xff0c;常常只關注頁面效果和交互&#xff0c;但隨著項目復雜度提升&#xff0c;我們遲早會遇到“服務端”的問題&#xff1a;如何讓一個頁面的數據是從數據庫來的&#xff1f;怎么讓不同的用戶看到不同的內容&#xff1f;這時候&#xff0c;我們就需要一…

Codeforces Round 987 (Div. 2)

ABC 略D預處理出每個位置的前綴最大和后綴最小。從后向前枚舉&#xff0c;如果一個數無法后移&#xff0c;那么答案就是最大前綴&#xff0c;否則答案要不是前綴最大&#xff0c;要不就是這個數先移到前綴最大位置再移到能移到的最大的位置此處的答案。用線段樹維護#include<…

Javascript/ES6+/Typescript重點內容篇——手撕(待總結)

前端核心知識點梳理與面試題詳解 1. Promise 核心知識點 Promise 是異步編程的解決方案&#xff0c;用于處理異步操作三種狀態&#xff1a;pending&#xff08;進行中&#xff09;、fulfilled&#xff08;已成功&#xff09;、rejected&#xff08;已失敗&#xff09;狀態一旦改…

[自動化Adapt] 父子事件| 冗余過濾 | SQLite | SQLAlchemy | 會話工廠 | Alembic

第五章&#xff1a;事件處理與融合 歡迎回到OpenAdapt探索之旅~ 在第四章&#xff1a;系統配置中&#xff0c;我們掌握了如何定制化系統參數。更早的第一章&#xff1a;錄制引擎則展示了系統如何捕獲海量原始操作數據。 假設我們需要訓練機器人輸入"hello"一詞。原…

組合期權:跨式策略

文章目錄0.簡介1.買入跨式組合&#xff08;Long Straddle&#xff09;1.1 適用場景?1.2 合約選擇1.3 損益分析1.4 案例示范2.賣出跨式組合&#xff08;Short Straddle&#xff09;2.1 適用場景?2.2 合約選擇2.3 損益分析2.4 案例示范3.小結參考文獻0.簡介 跨式策略是一種交易…

Vue計算屬性詳解2

可寫計算屬性 計算屬性默認是只讀的,但在特殊場景下,我們可以創建"可寫"的計算屬性,通過同時提供getter和setter實現: <script setup>import { ref, computed } from vueconst firstName = ref(John)const lastName = ref(Doe)const fullName = computed(…

UniStorm 5.3.0 + Unity2022 + URP配置說明

一、前言 以前我用的是UniStorm3.0&#xff0c;主要用在內置管線里面&#xff0c;最近想在URP管線里面使用UniStorm天氣系統&#xff0c;于是弄了UniStorm5.3.0的包&#xff0c;在Unity2022.3的URP模式下配置&#xff0c;直接導入package&#xff0c;兩次宣告失敗。最后看了官方…

力扣經典算法篇-44-組合總和(回溯問題)

1、題干 給你一個無重復元素的整數數組candidates和一個目標整數 target &#xff0c;找出 candidates 中可以使數字和為目標數 target 的 所有 不同組合 &#xff0c;并以列表形式返回。你可以按 任意順序 返回這些組合。 candidates 中的 同一個 數字可以 無限制重復被選取 。…