Aller au contenu
medium

RustFS : stockage objet S3 haute performance en Rust

17 min de lecture

RustFS est un stockage objet S3 haute performance écrit en Rust et distribué sous licence Apache 2.0. Inspiré de l’architecture de MinIO, il promet des performances 2,3x supérieures pour les petits objets (4 Ko) grâce aux optimisations de Rust. Ce guide déploie un cluster distribué 4 nœuds avec erasure coding, teste l’API S3 complète et configure un service systemd — chaque commande a été vérifiée sur un lab KVM réel avec Ubuntu 24.04.

  • Architecture : comprendre le modèle peer-to-peer sans master et l’erasure coding
  • Mode single-node : démarrer RustFS sur un seul serveur pour le test
  • Cluster distribué : déployer un cluster 4 nœuds avec systemd
  • API S3 : créer des buckets, uploader/télécharger des fichiers avec AWS CLI
  • Dépannage : résoudre les problèmes courants (503, convergence, format)

RustFS est un système de stockage objet distribué open source développé en Rust (compilateur Rust 1.93+). Il fournit une API 100 % compatible S3 et une console d’administration web, le tout dans un unique binaire statique sans dépendance. Le projet a été créé en 2024 et reste en développement actif sur GitHub.

Analogie : imaginez un groupe de 4 coffres-forts identiques dans 4 bureaux de poste différents. Quand vous déposez un document dans n’importe quel bureau, il est automatiquement réparti entre les 4 coffres grâce à un code de correction d’erreurs — même si 2 coffres sont détruits, votre document reste récupérable. RustFS fonctionne ainsi : chaque nœud est égal (pas de chef), et l’erasure coding protège vos données.

CaractéristiqueDescription
Haute performanceÉcrit en Rust, optimisé pour les petits objets (2,3x plus rapide que MinIO sur 4 Ko)
Peer-to-peerPas de nœud maître — tous les nœuds sont égaux et interchangeables
Erasure codingReed-Solomon intégré : protège les données avec moins d’espace que la réplication
Binaire uniqueUn seul exécutable statique (~40 Mo), aucune dépendance système
S3 compatibleAPI S3 100 % compatible, fonctionne avec AWS CLI, MinIO Client (mc), tout SDK S3
Console webInterface d’administration intégrée (port 9001)
Apache 2.0Licence permissive, contrairement à l’AGPLv3 de MinIO
CritèreRustFSMinIOGarageSeaweedFS
LangageRustGoRustGo
ArchitecturePeer-to-peerPeer-to-peerHash ringMaster/Volume
Protection donnéesErasure codingErasure codingRéplicationRéplication + EC
LicenceApache 2.0AGPLv3AGPLv3Apache 2.0
MaturitéAlphaProductionProductionProduction
Min. nœuds (distribué)4433
Console webOuiOuiNonNon
Stockage fichierNonNonNonOui (Filer)

Architecture RustFS — cluster peer-to-peer avec erasure coding

Contrairement à SeaweedFS (master + volume servers) ou Ceph (monitors + OSDs), RustFS utilise une architecture entièrement décentralisée. Tous les nœuds sont identiques : chacun expose l’API S3 sur le port 9000 et la console web sur le port 9001. N’importe quel nœud peut recevoir les requêtes client.

Les nœuds communiquent entre eux via gRPC pour coordonner les opérations d’écriture et distribuer les fragments d’erasure coding.

L’erasure coding est la méthode utilisée par RustFS pour protéger les données. Au lieu de copier 3 fois chaque fichier (réplication 3x), l’erasure coding découpe les données en fragments de données et génère des fragments de parité supplémentaires.

Comment ça fonctionne :

ConceptExplication
DriveUn disque physique ou un répertoire de stockage sur un nœud
Set (erasure set)Un groupe de drives répartis sur plusieurs nœuds. Chaque objet vit dans un seul set
Fragments de donnéesLes morceaux du fichier original, répartis entre les drives du set
Fragments de paritéDes données de correction calculées par l’algorithme Reed-Solomon

Exemple avec 4 nœuds et 1 drive chacun (notre lab) :

  • 1 erasure set de 4 drives
  • 2 fragments de données + 2 fragments de parité (EC:2)
  • Tolérance : jusqu’à 2 drives en panne simultanée sans perte

Comparaison avec la réplication :

MéthodeStockage pour 1 Go utileTolérance de panne
Réplication 3x3 Go (300 %)2 copies perdues
Erasure coding EC:2 (4 drives)2 Go (200 %)2 drives perdus
EC:4 (configuration 12+4)1,33 Go (133 %)4 drives perdus

RustFS supporte 3 modes de déploiement :

ModeDescriptionMinimum
SNSD (Single-Node Single-Drive)Un nœud, un disque. Pour le test uniquement1 nœud, 1 disque
SNMD (Single-Node Multi-Drive)Un nœud, plusieurs disques. Erasure coding local1 nœud, 4 disques
MNMD (Multi-Node Multi-Drive)Plusieurs nœuds, chacun avec 1+ disques. Production4 nœuds minimum
PortUsage
9000API S3 (requêtes client, communication inter-nœuds)
9001Console web d’administration

Avant de déployer un cluster complet, commençons par un nœud unique pour valider l’installation et tester l’API S3.

  • 1 machine Linux (VM, serveur, WSL)
  • Ubuntu 24.04 (ou toute distribution Linux x86_64)
  • 2 Go de RAM minimum
  • AWS CLI installé (apt install awscli)
  1. Télécharger le binaire :

    Fenêtre de terminal
    wget https://dl.rustfs.com/artifacts/rustfs/release/rustfs-linux-x86_64-musl-latest.zip
    unzip rustfs-linux-x86_64-musl-latest.zip
    sudo mv rustfs /usr/local/bin/
    sudo chmod +x /usr/local/bin/rustfs

    Vérification :

    Fenêtre de terminal
    rustfs --version

    Résultat attendu :

    rustfs 1.0.0-alpha.83
  2. Créer le répertoire de données :

    Fenêtre de terminal
    sudo mkdir -p /data/rustfs0
  3. Démarrer en mode single-node :

    Fenêtre de terminal
    rustfs --address :9000 \
    --console-enable \
    --access-key rustfsadmin \
    --secret-key rustfsadmin \
    /data/rustfs0

    Le serveur affiche :

    RustFS Http API: http://<IP>:9000 http://127.0.0.1:9000
    Console WebUI available at: http://<IP>:9001/rustfs/console/index.html

Ouvrez un second terminal et configurez les variables d’environnement pour AWS CLI :

Fenêtre de terminal
export AWS_ACCESS_KEY_ID=rustfsadmin
export AWS_SECRET_ACCESS_KEY=rustfsadmin
export AWS_DEFAULT_REGION=us-east-1

Créer un bucket :

Fenêtre de terminal
aws --endpoint-url http://localhost:9000 s3 mb s3://test-bucket
make_bucket: test-bucket

Uploader un fichier :

Fenêtre de terminal
echo "Hello RustFS!" > /tmp/test.txt
aws --endpoint-url http://localhost:9000 s3 cp /tmp/test.txt s3://test-bucket/docs/
upload: /tmp/test.txt to s3://test-bucket/docs/test.txt

Lister les objets :

Fenêtre de terminal
aws --endpoint-url http://localhost:9000 s3 ls s3://test-bucket --recursive
2026-03-01 10:27:16 14 docs/test.txt

Télécharger un fichier :

Fenêtre de terminal
aws --endpoint-url http://localhost:9000 s3 cp s3://test-bucket/docs/test.txt /tmp/download.txt
cat /tmp/download.txt
Hello RustFS!

Générer une URL pré-signée (accès temporaire sans authentification) :

Fenêtre de terminal
aws --endpoint-url http://localhost:9000 s3 presign s3://test-bucket/docs/test.txt --expires-in 3600
http://localhost:9000/test-bucket/docs/test.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&...

Upload multipart (fichiers volumineux) :

Fenêtre de terminal
dd if=/dev/urandom of=/tmp/bigfile.bin bs=1M count=10 2>/dev/null
aws --endpoint-url http://localhost:9000 s3 cp /tmp/bigfile.bin s3://test-bucket/data/
upload: /tmp/bigfile.bin to s3://test-bucket/data/bigfile.bin

Le mode distribué est le déploiement réel de RustFS. Il nécessite au minimum 4 serveurs pour former un erasure set fonctionnel.

  • 4 machines avec Ubuntu 24.04
  • 2 Go de RAM et 1 vCPU par nœud
  • Connectivité réseau entre tous les nœuds (port 9000)
  • Le binaire RustFS installé sur chaque nœud
  1. Configurer la résolution DNS sur chaque nœud :

    Ajoutez dans /etc/hosts de chaque nœud les 4 adresses :

    Fenêtre de terminal
    sudo tee -a /etc/hosts << 'EOF'
    192.168.122.31 node1
    192.168.122.20 node2
    192.168.122.64 node3
    192.168.122.212 node4
    EOF

    Remplacez les adresses IP par celles de vos machines.

    Vérification : depuis chaque nœud, les 3 autres doivent répondre au ping :

    Fenêtre de terminal
    ping -c1 node1 && ping -c1 node2 && ping -c1 node3 && ping -c1 node4
  2. Créer le répertoire de données sur chaque nœud :

    Fenêtre de terminal
    sudo mkdir -p /data/rustfs0
    sudo mkdir -p /var/logs/rustfs
  3. Configurer les variables d’environnement :

    Créez le fichier /etc/default/rustfs sur chaque nœud (contenu identique) :

    Fenêtre de terminal
    sudo tee /etc/default/rustfs << 'EOF'
    RUSTFS_ACCESS_KEY=rustfsadmin
    RUSTFS_SECRET_KEY=rustfsadmin
    RUSTFS_VOLUMES="http://node{1...4}:9000/data/rustfs0"
    RUSTFS_ADDRESS=":9000"
    RUSTFS_CONSOLE_ENABLE=true
    RUST_LOG=error
    RUSTFS_OBS_LOG_DIRECTORY="/var/logs/rustfs/"
    EOF

    La syntaxe {1...4} (trois points) est spécifique à RustFS — elle génère automatiquement les URLs pour node1 à node4. Ne confondez pas avec la syntaxe shell {1..4} (deux points).

  4. Créer le service systemd :

    Le fichier /etc/systemd/system/rustfs.service est identique sur chaque nœud :

    Fenêtre de terminal
    sudo tee /etc/systemd/system/rustfs.service << 'EOF'
    [Unit]
    Description=RustFS Object Storage Server
    Documentation=https://rustfs.com/docs/
    After=network-online.target
    Wants=network-online.target
    [Service]
    Type=notify
    NotifyAccess=main
    User=root
    Group=root
    WorkingDirectory=/usr/local
    EnvironmentFile=-/etc/default/rustfs
    ExecStart=/usr/local/bin/rustfs $RUSTFS_VOLUMES
    LimitNOFILE=1048576
    TasksMax=infinity
    Restart=always
    RestartSec=10s
    [Install]
    WantedBy=multi-user.target
    EOF

    Le Type=notify indique que RustFS notifie systemd une fois prêt à recevoir des requêtes. Le service redémarre automatiquement en cas de crash (Restart=always).

Démarrez sur les 4 nœuds simultanément :

Fenêtre de terminal
sudo systemctl enable --now rustfs

Vérification (sur chaque nœud) :

Fenêtre de terminal
sudo systemctl is-active rustfs

Résultat attendu : active.

Consultez les logs pour confirmer le démarrage :

Fenêtre de terminal
sudo journalctl -u rustfs --no-pager -n 10

Vous devriez voir :

RustFS Http API: http://<IP>:9000 http://127.0.0.1:9000
Console WebUI available at: http://<IP>:9001/rustfs/console/index.html
RustFS server version: refs/tags/1.0.0-alpha.83 started successfully

Le message started successfully confirme que le nœud a rejoint le cluster. La convergence prend environ 10 à 15 secondes : le temps que chaque nœud contacte les 3 autres et synchronise les métadonnées de format (format.json).

Configurez AWS CLI pour pointer vers n’importe quel nœud du cluster :

Fenêtre de terminal
export AWS_ACCESS_KEY_ID=rustfsadmin
export AWS_SECRET_ACCESS_KEY=rustfsadmin
export AWS_DEFAULT_REGION=us-east-1

Créer un bucket via node1 :

Fenêtre de terminal
aws --endpoint-url http://node1:9000 s3 mb s3://cluster-bucket
make_bucket: cluster-bucket

Uploader via node1, lire depuis node2 :

Fenêtre de terminal
echo "Test distribué RustFS" > /tmp/cluster-test.txt
aws --endpoint-url http://node1:9000 s3 cp /tmp/cluster-test.txt s3://cluster-bucket/docs/test.txt
aws --endpoint-url http://node2:9000 s3 ls s3://cluster-bucket --recursive
2026-03-01 10:37:39 23 docs/test.txt

Le fichier uploadé sur node1 est immédiatement accessible depuis node2 : les métadonnées et fragments d’erasure coding sont distribués entre les 4 nœuds.

Télécharger depuis node3 :

Fenêtre de terminal
aws --endpoint-url http://node3:9000 s3 cp s3://cluster-bucket/docs/test.txt /tmp/dl.txt
cat /tmp/dl.txt
Test distribué RustFS

Upload multipart via node1, vérification depuis node4 :

Fenêtre de terminal
dd if=/dev/urandom of=/tmp/bigfile.bin bs=1M count=10 2>/dev/null
aws --endpoint-url http://node1:9000 s3 cp /tmp/bigfile.bin s3://cluster-bucket/data/bigfile.bin
aws --endpoint-url http://node4:9000 s3 ls s3://cluster-bucket --recursive
2026-03-01 10:37:50 10485760 data/bigfile.bin
2026-03-01 10:37:39 23 docs/test.txt

Chaque objet est réparti en fragments d’erasure coding sur les 4 drives du cluster. N’importe quel nœud peut servir n’importe quel objet.

RustFS fournit une interface d’administration web accessible sur le port 9001 :

http://node1:9001/rustfs/console/index.html

Connectez-vous avec les identifiants configurés dans /etc/default/rustfs (rustfsadmin / rustfsadmin). La console permet de parcourir les buckets, gérer les utilisateurs et surveiller l’état du cluster.

  • Load balancer : en production, placez un reverse proxy (HAProxy, Nginx) devant les nœuds pour distribuer les requêtes en round-robin sur le port 9000
  • DNS : utilisez un enregistrement DNS qui résout vers tous les nœuds plutôt que /etc/hosts
  • Pare-feu : ouvrez les ports 9000 (S3 inter-nœuds + clients) et 9001 (console, accès restreint)
  • 4 nœuds minimum pour le mode distribué (MNMD)
  • Disques XFS en JBOD pour la meilleure performance avec l’erasure coding
  • Plusieurs disques par nœud en production : la syntaxe http://node{1...4}:9000/data/rustfs{0...3} crée 4 drives par nœud, soit 16 drives au total pour un meilleur erasure set
  • Changez les identifiants par défaut : rustfsadmin/rustfsadmin est uniquement pour le test
  • TLS : configurez un certificat pour chiffrer les communications S3 et inter-nœuds
  • Réseau dédié : isolez le trafic inter-nœuds sur un VLAN ou réseau privé
SymptômeCause probableSolution
503 Service Unavailable sur S3Le cluster n’a pas convergé (format.json non synchronisé)Arrêtez tous les nœuds, nettoyez /data/rustfs0, redémarrez simultanément
can not get formats dans les logsUn ou plusieurs nœuds ne sont pas joignablesVérifiez la résolution DNS (/etc/hosts) et la connectivité réseau (port 9000)
retrying get formats after NLes nœuds se retentent en backoff exponentiel (2, 4, 8, 16s…)Vérifiez que tous les nœuds exécutent rustfs. Si données corrompues : nettoyez et redémarrez
Console web renvoie 403Accès via curl sans token CSRFNormal — utilisez un navigateur web pour accéder à la console
WARNING: Host local has more than 0 drives of setPlus d’un drive du même erasure set sur le même nœudAcceptable en lab. En production, répartissez les drives sur des nœuds différents
Service systemd échoue au démarrageDonnées résiduelles d’un déploiement précédent incompatiblesudo rm -rf /data/rustfs0 && sudo mkdir -p /data/rustfs0, puis redémarrez
  • RustFS est un stockage objet S3 haute performance écrit en Rust, sous licence Apache 2.0
  • L’architecture peer-to-peer sans master simplifie le déploiement : tous les nœuds sont identiques et interchangeables
  • L’erasure coding (Reed-Solomon) protège les données plus efficacement que la réplication — avec 4 drives, 2 peuvent tomber sans perte
  • Le mode distribué (MNMD) nécessite au minimum 4 nœuds ; tous doivent démarrer simultanément pour la convergence initiale
  • La syntaxe d’expansion {1...4} (trois points) est spécifique à RustFS pour décrire les endpoints du cluster
  • Le projet est en alpha : très prometteur pour les performances mais pas prêt pour la production critique
  • En production, utilisez XFS en JBOD, un load balancer devant les nœuds et des identifiants forts

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn