Stockage

JuiceFS

Système de fichiers POSIX cloud-native sur object storage (S3/GCS/OSS) + moteur de métadonnées Redis/PostgreSQL. CSI driver K8s. Idéal workloads AI/ML.

JuiceFS est un système de fichiers distribué POSIX cloud-native qui sépare le stockage des données (object storage : S3, GCS, Azure Blob, OSS, MinIO…) du stockage des métadonnées (moteur de métadonnées : Redis, TiKV, PostgreSQL, MySQL). Les données sont découpées en blocs stockés dans l'object storage, les métadonnées (arbre de fichiers, inodes, permissions) sont dans le moteur de métadonnées. Ce découplage permet de combiner la scalabilité illimitée de l'object storage avec les performances d'un moteur de métadonnées rapide.

JuiceFS existe en deux versions : Community Edition (Apache 2.0, GitHub) et Cloud Edition (SaaS, métadonnées managées). La fiche couvre l'édition Community.


Informations essentielles

Origine : Juicedata Inc. (Chine)  ·  Licence : Apache 2.0 (Community Edition)  ·  Architectures : x86_64, ARM64

Liens : Site officiel  ·  Documentation  ·  GitHub  ·  Releases

Support : Support communautaire via GitHub Issues et Discord.

Stack par défaut

ComposantValeur
Stockage des donnéesObject storage (S3, MinIO, OSS, GCS, Azure Blob, Ceph…)
Stockage des métadonnéesRedis (dev/prod léger), TiKV / PostgreSQL / MySQL (prod)
Protocoles clientsFUSE, NFS, S3 gateway, Hadoop (HDFS compatible), CSI K8s
Cache localConfigurable (disque ou RAM) pour les lectures chaudes
Access modes K8sReadWriteMany, ReadWriteOnce

Concepts clés

ConceptDescription
Metadata EngineBase de données pour les métadonnées (Redis, PG, TiKV…)
Object storageStockage des blocs de données (chunk size : 64 MB par défaut)
CacheCache local sur disque pour réduire les lectures vers l'object storage
Mount pointPoint de montage FUSE sur le client
CSI Driverjuicefs-csi-driver pour l'intégration Kubernetes

Moteurs de métadonnées supportés

MoteurUsage recommandé
RedisDev, test, production légère (données en RAM, persistance AOF)
TiKVProduction distribuée (scalable horizontalement)
PostgreSQLProduction, familier pour les équipes SQL
MySQL / MariaDBProduction, déjà utilisé en entreprise
SQLiteDéveloppement local uniquement

Prérequis

RessourceValeur
OSLinux (FUSE requis), macOS (via macFUSE)
Packagesfuse3 ou fuse (Linux)
Moteur métadonnéesRedis, PostgreSQL ou autre moteur supporté
Object storageBucket S3 (ou compatible) accessible depuis les clients

Installer les dépendances

# Ubuntu / Debian
sudo apt-get install -y fuse3

# Rocky Linux / AlmaLinux
sudo dnf install -y fuse3

Installation de la CLI JuiceFS

# Linux amd64
curl -sSL https://d.juicefs.com/install | sh -

# Ou via binary direct
JUICEFS_VERSION=1.2.0
curl -Lo juicefs.tar.gz \
  https://github.com/juicedata/juicefs/releases/download/v${JUICEFS_VERSION}/juicefs-${JUICEFS_VERSION}-linux-amd64.tar.gz
tar -xzf juicefs.tar.gz
sudo install juicefs /usr/local/bin/

juicefs version

Créer et monter un volume JuiceFS

1. Formater le volume (créer le filesystem)

# Exemple avec Redis + MinIO
juicefs format \
  --storage minio \
  --bucket http://minio.minio.svc.cluster.local:9000/juicefs-bucket \
  --access-key <MINIO_ACCESS_KEY> \
  --secret-key <MINIO_SECRET_KEY> \
  redis://:password@redis.redis.svc.cluster.local:6379/1 \
  myvolume

# Exemple avec S3 + PostgreSQL
juicefs format \
  --storage s3 \
  --bucket https://s3.eu-west-1.amazonaws.com/mon-bucket \
  --access-key <AWS_ACCESS_KEY> \
  --secret-key <AWS_SECRET_KEY> \
  "postgres://user:password@pg-host:5432/juicemeta?sslmode=disable" \
  myvolume

2. Monter le volume (FUSE)

sudo mkdir -p /mnt/jfs
juicefs mount \
  redis://:password@redis.redis.svc.cluster.local:6379/1 \
  /mnt/jfs \
  --background

# Vérifier
df -h /mnt/jfs
ls /mnt/jfs

3. Démontage

juicefs umount /mnt/jfs

Intégration Kubernetes (CSI Driver)

Installer juicefs-csi-driver

helm repo add juicefs https://juicedata.github.io/charts/
helm repo update

helm install juicefs-csi-driver juicefs/juicefs-csi-driver \
  --namespace kube-system

Secret avec les credentials

apiVersion: v1
kind: Secret
metadata:
  name: juicefs-secret
  namespace: kube-system
type: Opaque
stringData:
  name: myvolume
  metaurl: "redis://:password@redis.redis.svc.cluster.local:6379/1"
  storage: minio
  bucket: http://minio.minio.svc.cluster.local:9000/juicefs-bucket
  access-key: <MINIO_ACCESS_KEY>
  secret-key: <MINIO_SECRET_KEY>

StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: juicefs
provisioner: csi.juicefs.com
parameters:
  csi.storage.k8s.io/provisioner-secret-name: juicefs-secret
  csi.storage.k8s.io/provisioner-secret-namespace: kube-system
  csi.storage.k8s.io/node-publish-secret-name: juicefs-secret
  csi.storage.k8s.io/node-publish-secret-namespace: kube-system
reclaimPolicy: Retain
mountOptions:
  - cache-size=2048          # Cache local en MB
  - cache-dir=/var/jfsCache

PVC JuiceFS (ReadWriteMany)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: shared-dataset
  namespace: ml-training
spec:
  accessModes:
    - ReadWriteMany          # Plusieurs pods en lecture/écriture simultanée
  storageClassName: juicefs
  resources:
    requests:
      storage: 100Gi         # Indicatif - pas de quota réel avec JuiceFS

Vérification de l'installation CSI

# 1. Pods CSI driver
kubectl get pods -n kube-system | grep juicefs
# juicefs-csi-controller (3/3) et juicefs-csi-node-* (3/3) doivent être Running

# 2. Vérifier la StorageClass
kubectl get sc juicefs

# 3. Vérifier les logs du controller
kubectl logs -n kube-system \
  $(kubectl get pod -n kube-system -l app=juicefs-csi-controller \
    -o jsonpath='{.items[0].metadata.name}') \
  -c juicefs-plugin --tail=20

Premier test de bout en bout

# test-juicefs.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-juicefs-pvc
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: juicefs
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-juicefs-writer
  namespace: default
spec:
  containers:
  - name: writer
    image: busybox
    command: ["/bin/sh", "-c"]
    args:
    - |
      echo "JuiceFS OK $(date)" > /data/test.txt
      cat /data/test.txt
      df -h /data
      sleep 3600
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: test-juicefs-pvc
---
# Second pod sur le même volume (test ReadWriteMany)
apiVersion: v1
kind: Pod
metadata:
  name: test-juicefs-reader
  namespace: default
spec:
  containers:
  - name: reader
    image: busybox
    command: ["/bin/sh", "-c", "sleep 5 && cat /data/test.txt && sleep 3600"]
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: test-juicefs-pvc
kubectl apply -f test-juicefs.yaml

kubectl get pvc test-juicefs-pvc -w
# Doit passer Pending → Bound

kubectl logs test-juicefs-writer
# "JuiceFS OK <date>" + df affichant le volume

kubectl logs test-juicefs-reader
# Doit afficher le même fichier écrit par le writer (test RWX)

# Pièges courants
# - PVC en Pending : le metadata engine (Redis/PostgreSQL) est inaccessible depuis les pods
# - "format error" : le bucket S3 n'est pas accessible ou les credentials sont incorrects
# - Monter un volume sans CSI (FUSE) pour déboguer la connectivité :
#   juicefs status <metaurl>

# Nettoyage
kubectl delete -f test-juicefs.yaml

Performances et cache

JuiceFS lit les données depuis l'object storage - le cache local est crucial pour les performances :

# Monter avec cache agressif
juicefs mount \
  redis://:password@host:6379/1 \
  /mnt/jfs \
  --cache-size 51200 \           # 50 GB de cache disque
  --cache-dir /var/jfsCache \
  --prefetch 3 \                 # Précharger 3 blocs en avance
  --background

# Voir les statistiques de cache
juicefs stats /mnt/jfs

Mise à jour

# Mettre à jour la CLI
curl -sSL https://d.juicefs.com/install | sh -

# Mettre à jour le CSI Driver
helm upgrade juicefs-csi-driver juicefs/juicefs-csi-driver \
  --namespace kube-system \
  --reuse-values

# Mettre à jour le format du filesystem (si nécessaire après mise à jour majeure)
juicefs config <metaurl> --capacity 0   # Vérifier la compatibilité

Troubleshooting

# Vérifier l'état du volume
juicefs status <metaurl>

# Statistiques en temps réel
juicefs stats /mnt/jfs

# Vérifier l'intégrité des données
juicefs fsck <metaurl>

# Logs du CSI Driver
kubectl logs -n kube-system -l app=juicefs-csi-controller --tail=100
kubectl logs -n kube-system -l app=juicefs-csi-node --tail=100

Volume non monté dans le pod

# Vérifier les logs du node plugin
kubectl logs -n kube-system <juicefs-csi-node-pod> -c juicefs-plugin --tail=50

# Vérifier la connectivité au metadata engine depuis le nœud
# (Redis ou PostgreSQL doit être accessible)

Performances dégradées

# Diagnostiquer les I/O lentes
juicefs stats /mnt/jfs --interval 1

# Augmenter le cache disque (StorageClass ou option de montage)
# Vérifier la latence vers l'object storage

Commandes utiles

juicefs version                            # Version du client
juicefs status <metaurl>                   # État du volume
juicefs info <metaurl> <chemin>            # Info sur un fichier
juicefs stats /mnt/jfs                     # Métriques en temps réel
juicefs bench /mnt/jfs                     # Benchmark
juicefs gc <metaurl>                       # Garbage collect (supprimer les chunks orphelins)
juicefs fsck <metaurl>                     # Vérification d'intégrité
juicefs clone <src> <dst>                  # Clone rapide (côté serveur, sans copie de données)

Ressources

Newsletter · 2 000+ abonnés

Reste au courant de ce qui bouge en prod

RudeOps veille devops hebdo, droit au but.

Gratuit · Sans spam · Désinscription en un clic