Le stockage : bloc, fichier, objet
Pourquoi
Sur le serveur unique d'où part l'équipe de Signalements, la question du stockage ne se posait pas : il y avait un disque. PostgreSQL y écrivait ses fichiers, l'application y déposait ses journaux, et la prochaine fonctionnalité, les photos jointes aux signalements, y aurait atterri dans un répertoire /var/lib/signalements/photos. Une seule interface, le système de fichiers, pour tous les usages.
Dans le cloud, ce disque unique éclate en trois produits différents, et le choix entre eux n'est pas une affaire de prix au gigaoctet. C'est une affaire d'interface : le stockage bloc se présente comme un disque, le stockage fichier comme un répertoire partagé, le stockage objet comme une API HTTP. Chacun a ses garanties, ses limites et ses façons de perdre des données. Une équipe qui ne les distingue pas commet des erreurs classiques :
- elle écrit les photos sur le disque de l'instance, puis découvre que la seconde instance de la leçon 3 ne les voit pas, et que le remplacement d'une instance les fait disparaître ;
- elle croit qu'un volume « répliqué trois fois » est sauvegardé, et découvre qu'un
rm -rfest lui aussi répliqué trois fois, instantanément ; - elle rend un bucket public « juste pour tester », et le retrouve dans un rapport de fuite de données.
Cette leçon donne les critères pour choisir, puis met en œuvre les deux modèles dont Signalements a besoin : un volume bloc, pour comprendre le mécanisme, et un bucket privé pour les pièces jointes, qui restera dans l'architecture finale.
Les concepts
Trois interfaces, trois contrats
Le plus simple est de partir de ce que voit le programme qui lit et écrit les données.
| Bloc | Fichier | Objet | |
|---|---|---|---|
| Ce que voit le système | Un périphérique (/dev/sdb) découpé en blocs numérotés | Un arbre de répertoires et de fichiers, monté à distance | Une API HTTP : PUT, GET, DELETE sur des clés |
| Qui gère le système de fichiers | Vous (mkfs, mount) | Le service | Il n'y a pas de système de fichiers |
| Partage entre machines | Non, un volume est attaché à une seule instance à la fois | Oui, plusieurs instances montent le même partage | Oui, tout client HTTP autorisé |
| Modification partielle | Oui, n'importe quel bloc | Oui, n'importe quel octet d'un fichier | Non, on réécrit l'objet entier |
| Portée | Une zone | Une zone (chez Scaleway) | Une région |
| Usage typique | Disque système, base de données autogérée | Répertoire partagé par plusieurs serveurs d'application | Fichiers déposés par les utilisateurs, sauvegardes, artefacts, sites statiques |
Le stockage bloc (block storage) est le plus proche du disque physique. Le système d'exploitation de l'instance voit un périphérique vierge ; il y crée une table de partitions, un système de fichiers ext4 ou XFS, et c'est lui qui décide où va chaque octet. Le service ne connaît que des blocs : il ignore tout des fichiers qu'ils contiennent.
Le stockage fichier (file storage) déplace le système de fichiers chez le fournisseur. L'instance monte un partage réseau, et plusieurs instances peuvent le monter en même temps : c'est le rôle historique de NFS et de SMB.
Le stockage objet (object storage) abandonne la notion même de système de fichiers. On range des objets (des données et des métadonnées) dans des buckets, chaque objet étant désigné par une clé, comme photos/2026/10/4812.jpg. Les barres obliques ne sont qu'une convention : il n'y a pas de répertoires, seulement des clés qui partagent un préfixe. L'interface de référence est celle d'Amazon S3, que la plupart des fournisseurs, dont Scaleway, reproduisent en partie.
Chez Scaleway, et ailleurs
| Modèle | Scaleway | AWS | Azure | Google Cloud | OVHcloud |
|---|---|---|---|---|---|
| Disque local de l'hôte | Local Storage (local volume) | Instance store | Disque temporaire | Local SSD | Disque local des instances |
| Bloc réseau | Block Storage (SBS) | EBS | Managed Disks | Persistent Disk, Hyperdisk | Block Storage |
| Fichier | File Storage | EFS | Azure Files | Filestore | File Storage, NAS-HA |
| Objet | Object Storage | S3 | Blob Storage | Cloud Storage | Object Storage |
Quelques précisions propres à Scaleway, tirées de sa documentation :
- Local Storage : le disque système de certaines gammes d'instances vit sur l'hyperviseur lui-même, sur des SSD en RAID. Sa taille est fixée par le type d'instance (600 Go au maximum) ; il est rapide, mais lié à la machine physique. Si l'hyperviseur tombe, il faut une intervention physique pour récupérer les données. Les gammes récentes démarrent directement sur un volume bloc.
- Block Storage (SBS, Scaleway Block Storage) existe en deux classes de performance,
sbs_5k(5 000 IOPS) etsbs_15k(15 000 IOPS), sur des disques NVMe, de 5 Go à 15 To par volume. Les données sont répliquées trois fois. On paie la taille du volume à l'heure, pas les données réellement écrites. Une instance accepte au plus 16 volumes, volume de démarrage compris. - File Storage est disponible dans la région de Paris (Amsterdam est annoncée). Un système de fichiers fait de 25 Go à 50 To, ses données sont répliquées trois fois dans une seule zone, et il se monte depuis les instances et les clusters Kapsule. Détail qui surprend : il ne s'agit pas de NFS. La documentation de montage utilise
mount -t virtiofs, un protocole de partage entre l'hyperviseur et la machine virtuelle ; le transport réseau vers le stockage est géré par Scaleway, hors de votre vue. - Object Storage propose trois classes : Standard Multi-AZ (répartie sur trois zones de la région, équivalent de la classe
STANDARDd'AWS), Standard One Zone (trois baies d'une seule zone, équivalent deONEZONE_IA) et Glacier (archivage, à restaurer avant lecture). Le point d'accès de Paris esthttps://s3.fr-par.scw.cloud.
Note
Les gammes, les classes et leur disponibilité par région évoluent. Avant de dimensionner, vérifiez la page Product availability by region de Scaleway : la classe Multi-AZ, par exemple, n'existe pas dans toutes les régions.
Durabilité et disponibilité
Deux mots se confondent souvent, alors qu'ils mesurent deux risques différents.
- La durabilité est la probabilité de ne pas perdre une donnée sur une période donnée. AWS annonce pour S3 Standard une durabilité « conçue » de 99,999999999 % sur un an (onze neuf) : sur dix millions d'objets, on s'attend statistiquement à en perdre un tous les dix mille ans.
- La disponibilité est la proportion du temps pendant laquelle on peut lire et écrire la donnée. AWS annonce 99,99 % pour la même classe, soit moins d'une heure d'indisponibilité par an.
Une donnée peut être parfaitement durable et indisponible : pendant une panne de zone, les objets d'une classe One Zone ne sont probablement pas perdus, mais on ne peut plus les lire. L'inverse arrive aussi : un volume disponible à 100 % dont un script a effacé le contenu n'a plus aucune durabilité utile.
Et surtout, la réplication protège contre les pannes matérielles, pas contre les erreurs logiques. Trois copies d'un fichier supprimé, chiffré par un rançongiciel ou corrompu par un bogue applicatif sont trois copies du problème. C'est pourquoi une réplication n'est jamais une sauvegarde, et pourquoi le versionnement et les instantanés existent.
Instantanés et cohérence
Un instantané (snapshot) est une copie d'un volume à un instant donné. Chez la plupart des fournisseurs, il est incrémental : seuls les blocs modifiés depuis l'instantané précédent sont stockés. Chez Scaleway, un instantané est une ressource indépendante, facturée, qui survit à la suppression du volume ou de l'instance d'origine.
La question délicate est celle de la cohérence. Un instantané pris pendant que l'instance écrit capture le disque dans l'état où il serait après une coupure de courant : c'est la cohérence après plantage (crash-consistent). Un système de fichiers journalisé comme ext4 sait s'en remettre, et une base de données bien écrite aussi, en rejouant son journal. Mais rien ne garantit qu'une application qui écrivait deux fichiers liés les ait écrits tous les deux. La documentation d'AWS le dit franchement : l'instantané ne contient que ce qui était écrit sur le volume au moment de la demande, pas ce que l'application ou le système gardaient en cache, et il est recommandé de suspendre les écritures, voire de démonter le volume, pour obtenir un instantané complet.
La cohérence applicative demande donc un geste de plus : vider les caches et geler les écritures le temps de déclencher l'instantané (avec fsfreeze sous Linux), ou, pour une base de données, utiliser son propre mécanisme de sauvegarde. C'est l'une des raisons pour lesquelles la base de Signalements est confiée à un service managé (leçon 2) : ses sauvegardes sont cohérentes par construction.
La cohérence d'un stockage objet
Pendant quatorze ans, S3 a été à cohérence éventuelle pour certaines opérations : juste après avoir réécrit un objet, une lecture pouvait encore renvoyer l'ancienne version. Depuis le 1er décembre 2020, AWS garantit une cohérence forte en lecture après écriture, sans changement côté client. La documentation de Scaleway annonce la même garantie, read-after-write, pour les PUT et les DELETE dans toutes ses régions : un objet écrit est immédiatement visible dans les lectures et les listes. Vérifiez ce point chez tout autre fournisseur compatible S3 : les vieux tutoriels qui recommandent d'attendre « un peu » après une écriture datent de l'époque de la cohérence éventuelle.
En pratique
Les commandes ci-dessous supposent la CLI scw configurée sur le projet signalements (leçon 1), et l'instance sig-app-1 créée en leçon 4 dans la zone fr-par-1. Elles ne montrent pas de sortie : les identifiants et les tailles seront différents chez vous, et la leçon ne présente pas de sortie inventée. Quand un champ est utile pour la suite, il est extrait avec -o json et jq.
Créer un volume et l'attacher
Signalements n'a pas besoin de disque persistant sur ses instances, et c'est voulu : l'état vit dans la base managée et dans le bucket. Pour comprendre le mécanisme, nous attachons tout de même à sig-app-1 un volume sig-exports, où un traitement nocturne pourrait écrire des exports CSV. Il sera supprimé à la fin de la leçon.
$ VOLUME_ID=$(scw block volume create name=sig-exports perf-iops=5000 \
from-empty.size=20GB zone=fr-par-1 -w -o json | jq -r .id)
$ SERVEUR_ID=$(scw instance server list name=sig-app-1 zone=fr-par-1 -o json | jq -r '.[0].id')
$ scw instance server attach-volume server-id="$SERVEUR_ID" volume-id="$VOLUME_ID" \
volume-type=sbs_volume zone=fr-par-1
perf-iops=5000choisit la classesbs_5k;15000choisiraitsbs_15k, plus chère, utile pour une base de données autogérée.from-empty.size=20GBcrée un volume vide de 20 Go. Scaleway compte en gigaoctets décimaux (10⁹ octets), alors que les outils Linux affichent souvent des gibioctets :lsblkmontrera environ 18,6 G.-w(--wait) attend que le volume soit prêt avant de rendre la main.zone=fr-par-1: un volume bloc est une ressource zonale, il ne peut être attaché qu'à une instance de la même zone.sig-app-2, enfr-par-2, ne pourra jamais le monter.- La gestion des volumes passe par l'API Block Storage (
scw block), mais l'attachement reste une opération sur l'instance (scw instance server attach-volume), avec le typesbs_volume.
L'attachement est à chaud : pas besoin de redémarrer l'instance.
Le formater et le monter
Connectez-vous à sig-app-1 (par le bastion de la leçon 6 si vous l'avez déjà construit) et repérez le nouveau périphérique :
$ lsblk
Le disque système apparaît avec ses partitions montées (/, /boot/efi) ; le nouveau volume est un disque d'environ 18,6 G, sans partition ni point de montage, souvent sdb. Vérifiez la taille avant toute commande destructrice : formater le mauvais périphérique est irréversible.
$ sudo mkfs.ext4 -L sig-exports /dev/sdb
$ sudo mkdir -p /srv/exports
$ sudo mount /dev/sdb /srv/exports
$ lsblk -f /dev/sdb
mkfs.ext4 crée le système de fichiers (et efface tout ce que le volume contenait) ; -L lui donne une étiquette lisible. lsblk -f affiche son type et son UUID.
Le montage ne survivra pas à un redémarrage. Pour le rendre permanent, on l'inscrit dans /etc/fstab, par UUID et non par nom de périphérique :
$ UUID=$(sudo blkid -s UUID -o value /dev/sdb)
$ echo "UUID=$UUID /srv/exports ext4 defaults,nofail 0 2" | sudo tee -a /etc/fstab
$ sudo umount /srv/exports && sudo mount -a && findmnt /srv/exports
- Par UUID : les noms
sdb,sdcsont attribués dans l'ordre de détection et peuvent changer après l'ajout ou le retrait d'un volume. L'UUID est écrit dans le système de fichiers lui-même et le suit partout. nofail: si le volume est détaché ou indisponible au démarrage, le système démarre quand même, sans ce montage. Sans cette option, systemd considère le montage comme requis, et l'instance peut rester bloquée en mode de secours, injoignable par SSH. Sur une machine que l'on ne peut atteindre que par le réseau, c'est la différence entre un avertissement et une intervention par la console série.umountpuismount -arejoue le fichierfstab: une erreur de syntaxe se découvre maintenant, et pas au prochain redémarrage.
Agrandir un volume
Un volume se redimensionne à la hausse, jamais à la baisse :
$ scw block volume update "$VOLUME_ID" size=40GB zone=fr-par-1
Le périphérique grandit, mais pas le système de fichiers qu'il contient. Sur l'instance, sudo resize2fs /dev/sdb étend un ext4 à chaud (pour XFS, c'est xfs_growfs sur le point de montage). Si le système de fichiers est dans une partition, il faut d'abord agrandir la partition, par exemple avec growpart.
Prendre un instantané cohérent
Gelez les écritures, déclenchez l'instantané, dégelez :
$ sudo fsfreeze --freeze /srv/exports # sur l'instance
$ scw block snapshot create "$VOLUME_ID" name=sig-exports-$(date +%F) zone=fr-par-1
$ sudo fsfreeze --unfreeze /srv/exports # sur l'instance, aussitôt
fsfreeze --freeze vide les tampons du système de fichiers sur le disque et bloque toute nouvelle écriture : les processus qui écrivent attendent. Il faut donc dégeler dès que l'instantané est déclenché, sans attendre qu'il soit terminé : comme chez AWS, la capture porte sur l'état au moment de la demande, et la copie se poursuit en arrière-plan. Ne gelez jamais le système de fichiers racine depuis une session SSH : vous risquez de bloquer votre propre shell.
Restaurer, c'est créer un nouveau volume à partir de l'instantané :
$ scw block volume create name=sig-exports-restaure perf-iops=5000 \
from-snapshot.snapshot-id=<id-instantane> zone=fr-par-1 -w
Un instantané est zonal, comme son volume. Pour le transporter vers une autre zone ou région, Scaleway propose de l'exporter vers un bucket (scw block snapshot export-to-object-storage), puis de l'importer ailleurs.
Configurer un client S3
Pour le stockage objet, la CLI scw sait créer des buckets, mais l'outil de référence reste un client S3 générique : n'importe quel outil écrit pour S3 fonctionne avec Scaleway si on lui donne le bon point d'accès. Nous utilisons l'AWS CLI version 2, selon la configuration documentée par Scaleway. Il faut une clé d'API Scaleway (identifiant d'accès et clé secrète) ; la leçon 7 explique comment en créer une limitée au projet.
Dans ~/.aws/config :
[profile scw-par]
region = fr-par
output = json
services = scw-fr-par
[services scw-fr-par]
s3 =
endpoint_url = https://s3.fr-par.scw.cloud
s3api =
endpoint_url = https://s3.fr-par.scw.cloudDans ~/.aws/credentials, sous le même nom de profil sans le préfixe profile :
[scw-par]
aws_access_key_id = SCWXXXXXXXXXXXXXXXXX
aws_secret_access_key = <clé secrète>servicesetendpoint_url(fonction de l'AWS CLI v2 pour les points d'accès par service) redirigent les commandess3ets3apivers Scaleway au lieu d'AWS. Il faut déclarer les deux :s3pour les commandes de haut niveau (cp,ls,presign),s3apipour les appels bruts (put-bucket-policy).region = fr-pardoit correspondre au point d'accès : la région entre dans le calcul de la signature des requêtes (Signature V4).- Un profil nommé plutôt que
[default]évite d'envoyer par mégarde une commande destinée à AWS vers Scaleway, ou l'inverse.
Exportez AWS_PROFILE=scw-par pour la suite de la séance.
Note
Depuis fin 2024, l'AWS CLI calcule par défaut une somme de contrôle CRC pour chaque envoi (paramètre request_checksum_calculation, valeur par défaut when_supported). Certains services « compatibles S3 » ont d'abord rejeté ces envois. Scaleway documente la prise en charge de ces algorithmes (dont CRC32, CRC32C et CRC64NVME) ; si un autre fournisseur renvoie des erreurs d'en-têtes inattendus, la parade connue est request_checksum_calculation = when_required dans le profil.
La CLI scw peut aussi générer la configuration d'autres clients S3 : scw object config get type=rclone (ou s3cmd, mc).
Créer le bucket des pièces jointes
$ SUFFIXE=$(openssl rand -hex 3)
$ BUCKET=signalements-pj-$SUFFIXE
$ aws s3api create-bucket --bucket "$BUCKET"
$ aws s3 ls
Le nom d'un bucket devient un nom DNS public, signalements-pj-xxxxxx.s3.fr-par.scw.cloud : il doit être unique sur la plateforme, en minuscules, sans souligné ni point. D'où le suffixe aléatoire. Évitez les points en particulier : le certificat TLS générique *.s3.fr-par.scw.cloud ne couvre pas un nom à plusieurs niveaux, et l'accès HTTPS en style « sous-domaine » échouerait.
Déposez une photo de test et lisez ses métadonnées :
$ aws s3 cp banc-casse.jpg "s3://$BUCKET/photos/2026/10/4812.jpg" --content-type image/jpeg
$ aws s3api head-object --bucket "$BUCKET" --key photos/2026/10/4812.jpg
head-object renvoie la taille, le type de contenu, l'ETag (une empreinte du contenu) et la classe de stockage, sans télécharger l'objet.
Partager sans rendre public : l'URL présignée
L'application doit permettre à un agent municipal d'afficher la photo d'un signalement. Rendre l'objet public serait la solution paresseuse ; la bonne est l'URL présignée : une URL qui contient, dans ses paramètres, une signature calculée avec la clé secrète de l'application et une date d'expiration.
$ aws s3 presign "s3://$BUCKET/photos/2026/10/4812.jpg" --expires-in 900
L'URL renvoyée donne accès à cet objet, en lecture (GET), pendant quinze minutes, à quiconque la possède, sans autre authentification. L'aide de l'AWS CLI fixe la durée maximale à 604 800 secondes (sept jours), limite de la signature V4. L'application Signalements génère ce type d'URL à la volée, avec son SDK, à chaque affichage : le bucket reste privé, et une URL qui fuit dans un historique de navigateur expire d'elle-même.
L'URL présignée hérite des droits de la clé qui l'a signée, à l'instant où elle est utilisée : si la clé est révoquée, l'URL cesse de fonctionner. La documentation de Scaleway signale aussi qu'un décalage d'horloge de plus de quinze minutes entre le client et le service fait échouer la signature (RequestTimeTooSkewed) : un client sans synchronisation NTP produit des URL refusées.
Restreindre l'accès au bucket
Par défaut, un bucket Scaleway est privé et accessible à tous les utilisateurs et applications du projet qui ont des droits Object Storage dans l'IAM (leçon 7). Une politique de bucket restreint cet accès bucket par bucket. Le format ressemble à celui d'AWS, avec trois différences qui piègent les habitués :
- la version courante est
2023-04-17(la version2012-10-17est dépréciée chez Scaleway) ; - seules les autorisations comptent : tout ce qui n'est pas explicitement autorisé est refusé, et une instruction
Denyest inutile ; - les principaux sont des identifiants Scaleway (
user_id:...,application_id:...), et les ressources sont écrites sans préfixearn:.
Pour Signalements, l'application (son identité IAM, créée en leçon 7) lit et écrit les photos, et votre utilisateur garde la main :
{
"Version": "2023-04-17",
"Id": "signalements-pj",
"Statement": [
{
"Sid": "API Signalements : lecture et écriture des photos",
"Effect": "Allow",
"Principal": {"SCW": "application_id:<ID_APPLICATION_API>"},
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": ["signalements-pj-xxxxxx/photos/*"]
},
{
"Sid": "Administration par l'équipe",
"Effect": "Allow",
"Principal": {"SCW": "user_id:<VOTRE_ID_UTILISATEUR>"},
"Action": "*",
"Resource": ["signalements-pj-xxxxxx", "signalements-pj-xxxxxx/*"]
}
]
}$ aws s3api put-bucket-policy --bucket "$BUCKET" --policy file://politique-pj.json
Warning
Dès qu'une politique est posée, tout principal qui n'y figure pas perd l'accès au bucket, y compris vous si vous n'êtes pas propriétaire de l'organisation. Une politique remplace la précédente, et un bucket n'en a qu'une. Si vous vous êtes enfermé dehors, le propriétaire de l'organisation garde toujours le droit de supprimer la politique (aws s3api delete-bucket-policy).
Versionnement, verrouillage et cycle de vie
Le versionnement conserve chaque version d'un objet : une réécriture crée une nouvelle version, une suppression pose un marqueur de suppression au lieu d'effacer.
$ aws s3api put-bucket-versioning --bucket "$BUCKET" \
--versioning-configuration Status=Enabled
$ aws s3api list-object-versions --bucket "$BUCKET" --prefix photos/
Les anciennes versions sont stockées, donc facturées. Sans règle d'expiration, un bucket versionné grossit indéfiniment. C'est le rôle des règles de cycle de vie, appliquées par Scaleway une fois par jour : expirer, transférer vers une classe moins chère, nettoyer les envois en plusieurs parties abandonnés. Dans cycle-de-vie.json :
{
"Rules": [
{
"ID": "archiver-photos-anciennes",
"Status": "Enabled",
"Filter": {"Prefix": "photos/"},
"Transitions": [{"Days": 365, "StorageClass": "GLACIER"}]
},
{
"ID": "purger-versions-remplacees",
"Status": "Enabled",
"Filter": {"Prefix": ""},
"NoncurrentVersionExpiration": {"NoncurrentDays": 30}
},
{
"ID": "nettoyer-envois-abandonnes",
"Status": "Enabled",
"Filter": {"Prefix": ""},
"AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7}
}
]
}$ aws s3api put-bucket-lifecycle-configuration --bucket "$BUCKET" \
--lifecycle-configuration file://cycle-de-vie.json
$ aws s3api get-bucket-lifecycle-configuration --bucket "$BUCKET"
- Les photos de plus d'un an partent en Glacier : elles restent listées, mais il faut les restaurer (de quelques minutes à 24 heures avant que la restauration ne démarre, selon Scaleway) avant de les lire. Acceptable pour des signalements clos depuis un an, pas pour des photos consultées chaque jour.
- Depuis avril 2026, Scaleway impose une durée minimale avant transition : 30 jours vers Standard One Zone, 90 jours vers Glacier.
- Les transitions ne vont que « vers le bas » (Multi-AZ, One Zone, Glacier) ; on ne remonte un objet de Glacier qu'en le restaurant.
- Les règles sont évaluées chaque jour à minuit UTC, et leur application peut prendre jusqu'à 24 heures de plus : ne vous attendez pas à voir l'effet le jour même.
L'option la plus forte est Object Lock : un modèle WORM (write once, read many) qui interdit la suppression ou la réécriture d'une version pendant une durée de rétention. En mode Governance, des utilisateurs dotés de droits particuliers peuvent lever la protection ; en mode Compliance, personne ne le peut, pas même le propriétaire du compte, avant l'échéance. Object Lock exige le versionnement, et une fois activé sur un bucket, il ne peut plus être désactivé. C'est l'outil des sauvegardes qui doivent résister à un rançongiciel ou à un administrateur compromis ; ce n'est pas celui des photos de Signalements, qui doivent pouvoir être effacées sur demande au titre du RGPD.
Nettoyer
$ sudo umount /srv/exports # sur l'instance, puis retirer la ligne de /etc/fstab
$ scw instance server detach-volume server-id="$SERVEUR_ID" volume-id="$VOLUME_ID" zone=fr-par-1
$ scw block volume delete "$VOLUME_ID" zone=fr-par-1
$ scw block snapshot list zone=fr-par-1
Supprimez aussi les instantanés listés : ils survivent au volume et restent facturés. Gardez le bucket, qui sert dans la suite du cours.
Sous le capot
Comment un volume réseau se fait passer pour un disque. L'instance croit parler à un disque SCSI ou virtio. En réalité, l'hyperviseur intercepte chaque lecture et écriture de bloc et la transmet sur le réseau du centre de données à une grappe de stockage, qui la réplique sur trois disques avant d'acquitter l'écriture. Scaleway décrit cette architecture comme un SAN (Storage Area Network) indépendant de l'hyperviseur : c'est ce qui permet à un volume bloc de survivre à la panne de la machine physique qui faisait tourner l'instance, et d'être rattaché à une autre instance de la même zone. Le prix de ce découplage est la latence : chaque entrée-sortie traverse le réseau. Le tableau comparatif de Scaleway qualifie la latence du Block Storage de « moyenne », face au NVMe local.
Pourquoi le stockage objet ne sait pas renommer. Un service objet n'est pas un système de fichiers : c'est une base clé-valeur géante, répartie sur des milliers de disques, avec un index qui associe chaque clé à l'emplacement de ses fragments. Renommer a.jpg en b.jpg n'est pas une opération native : les clients la simulent par une copie suivie d'une suppression. Modifier dix octets au milieu d'un objet de 2 Go impose de réécrire l'objet entier. En échange de ces renoncements, le service n'a pas à gérer de verrous, de répertoires ni d'écritures partielles concurrentes, et peut croître presque sans limite : un objet atteint 5 To chez Scaleway, envoyé en au plus 1 000 parties.
Comment on obtient onze neuf de durabilité. Répliquer trois fois chaque objet coûte trois fois l'espace. Les grands systèmes de stockage objet utilisent plutôt des codes d'effacement (erasure coding). La documentation de Ceph, logiciel de stockage libre, l'explique avec deux paramètres : l'objet est découpé en k fragments de données, auxquels on ajoute m fragments de parité calculés. N'importe quels k fragments parmi k + m suffisent à reconstituer l'objet. Avec k = 4 et m = 2, on survit à la perte simultanée de deux disques pour un surcoût d'espace de 50 %, contre 200 % pour trois copies. Répartis sur trois zones, ces fragments survivent à la perte d'un centre de données entier : c'est la promesse de la classe Multi-AZ. Les fournisseurs ajoutent un contrôle d'intégrité permanent, par sommes de contrôle, qui détecte et reconstruit les fragments corrompus avant que les pertes ne s'accumulent. Scaleway ne publie pas les paramètres internes de son service ; le principe, lui, est commun.
Ce que signe une URL présignée. La signature V4 est un HMAC-SHA256 calculé, à partir de la clé secrète, sur la méthode HTTP, le chemin, certains en-têtes, la date et la durée de validité. Le service recalcule la même signature avec sa copie de la clé et compare. L'URL ne contient jamais la clé secrète, seulement l'identifiant d'accès et le résultat du calcul : on ne peut pas en déduire la clé, ni modifier l'URL (changer d'objet, prolonger l'expiration) sans invalider la signature.
Pièges courants
Écrire des données d'application sur le disque de l'instance. Le jour où l'instance est recréée par une nouvelle image (leçon 4), les fichiers disparaissent ; le jour où une seconde instance sert les requêtes, la moitié des photos est introuvable. Toute donnée qui doit survivre à l'instance va dans un service fait pour cela : base managée, bucket, ou à la rigueur volume bloc.
Oublier nofail, ou monter par /dev/sdX. Les deux mènent au même symptôme : une instance qui ne redémarre plus, ou qui monte le mauvais disque au mauvais endroit. Toujours l'UUID, toujours nofail pour un volume de données, toujours mount -a pour tester.
Croire qu'un volume se supprime avec l'instance, ou l'inverse. La documentation de Scaleway est précise : par la console, on vous demande si les volumes bloc doivent être supprimés avec l'instance ; par l'API, tous les volumes attachés sont supprimés. Si vous voulez garder un volume, détachez-le avant de supprimer l'instance. Et les instantanés, eux, ne sont jamais supprimés automatiquement : ils s'accumulent sur la facture.
Le bucket qui disparaît de votre vue après une politique. An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied juste après un put-bucket-policy : vous n'êtes pas dans la politique. Seul le propriétaire de l'organisation peut alors la supprimer.
Le nom de bucket refusé. Majuscules, soulignés, nom déjà pris par un autre client : create-bucket échoue. Après une suppression par la console, Scaleway bloque le nom pendant 24 heures.
La facture d'un bucket versionné. Une application qui réécrit souvent les mêmes clés (une miniature régénérée chaque nuit, par exemple) multiplie les versions. Sans NoncurrentVersionExpiration, chaque réécriture s'ajoute à la facture. Scaleway indique en outre ne plus garantir de bonnes performances au-delà de 1 000 versions d'un même objet.
L'URL présignée qui « ne marche pas ». Trois causes fréquentes : l'URL a expiré, l'horloge du client qui l'a signée dérive, ou la région du profil ne correspond pas au point d'accès (la signature est calculée pour une région, le service la vérifie pour une autre).
Sécurité
Les buckets publics sont la première source de fuites cloud. En juin 2017, un chercheur d'UpGuard découvre un bucket S3 configuré en lecture publique, tenu par un sous-traitant de Verizon : noms, adresses et codes PIN de comptes de plusieurs millions de clients (14 millions selon le chercheur, 6 millions selon Verizon). Le scénario s'est répété des dizaines de fois depuis, toujours le même : un bucket rendu public pour un besoin ponctuel, jamais refermé. AWS a fini par changer les valeurs par défaut : depuis avril 2023, le blocage de l'accès public est activé sur tout nouveau bucket. Chez Scaleway, buckets et objets sont privés par défaut, et la visibilité publique se règle séparément pour le bucket (la liste des objets) et pour chaque objet. Règle simple : aucun bucket de données d'utilisateurs n'est public, l'accès passe par l'application et des URL présignées. Si vous devez publier des fichiers statiques, faites-le depuis un bucket dédié, qui ne contient que cela.
Chiffrer au repos. Scaleway propose trois modes de chiffrement côté serveur : SSE-ONE (clés gérées par Scaleway, équivalent de SSE-S3 chez AWS, activable par défaut sur un bucket), SSE-KMS (clés de votre Key Manager Scaleway) et SSE-C (vous fournissez la clé à chaque requête, Scaleway ne la conserve pas). Pour des archives très sensibles en Glacier, la documentation de Scaleway recommande même de chiffrer côté client avant l'envoi. Le chiffrement côté serveur protège contre le vol d'un disque physique ; il ne protège pas contre une clé d'API volée, puisque le service déchiffre pour quiconque est autorisé.
Le moindre privilège, jusqu'au préfixe. La politique de l'exemple n'accorde à l'application que GetObject et PutObject sur photos/* : pas de DeleteObject, pas de ListBucket. Une clé d'API de l'application volée permet de lire une photo dont on connaît la clé, pas d'énumérer le bucket ni de l'effacer.
Se protéger d'un effacement malveillant. Un rançongiciel qui obtient des droits d'écriture chiffre ou supprime. Le versionnement permet de revenir aux versions précédentes ; Object Lock en mode Compliance rend ce retour garanti, même face à un administrateur compromis. Pour les sauvegardes, combinez les deux, dans un bucket et idéalement un projet distincts de ceux de la production.
Les instantanés sont des copies de vos données. Un instantané d'un volume contenant des données personnelles est soumis aux mêmes obligations que le volume : contrôle d'accès, durée de conservation, suppression. Un instantané « temporaire » de 2024 oublié dans un projet de test est une fuite en attente.
En production
- Le coût d'un bucket n'est pas que du stockage. Les prix comportent le volume stocké par classe, et parfois les requêtes et la bande passante sortante. Un site qui sert des milliers de miniatures par seconde directement depuis un bucket paie surtout en sortie de données ; un cache (Edge Services chez Scaleway, un CDN ailleurs) change l'équation. La leçon 8 revient sur ces postes.
- Un volume bloc se facture à la taille provisionnée, rempli ou vide. Surdimensionner « pour être tranquille » coûte chaque heure ; préférez un volume juste et un agrandissement quand la supervision l'annonce.
- Choisir la classe d'Object Storage selon ce que l'on peut perdre. Les originaux des photos, qui n'existent nulle part ailleurs, vont en Standard Multi-AZ. Des miniatures que l'on sait régénérer peuvent aller en One Zone, moins chère. Une copie de sauvegarde secondaire aussi, si la copie principale est ailleurs.
- La règle 3-2-1 reste la référence pour les sauvegardes : trois copies des données, sur deux supports différents, dont une hors site. Dans le cloud, « hors site » veut dire au moins une autre région, et souvent un autre fournisseur ou un autre compte. Le cours Sauvegarde, restauration et PRA la met en œuvre, avec ce qui compte le plus : les tests de restauration.
- L'état de Signalements vit dans deux services managés, la base PostgreSQL (leçon 2) et le bucket. Les instances n'ont plus rien à sauvegarder : on les recrée depuis une image et cloud-init (leçon 4). C'est ce qui rend possibles les déploiements par remplacement, l'autoscaling et la reprise rapide après une panne de zone.
- Kubernetes demande les mêmes arbitrages. Sur Kapsule, comme sur le cluster
lyneko-appsde Lyneko, un PersistentVolume est en général un volume Block Storage : zonal, attaché à un seul nœud à la fois. Le cours Kubernetes : stockage et état en tire les conséquences sur l'ordonnancement des pods.
Exercices
1. Choisir le bon stockage (niveau 100). Pour chacun des besoins suivants, indiquez le modèle de stockage (bloc, fichier, objet) et justifiez en une phrase : (a) les fichiers de données d'un PostgreSQL que vous installez vous-même sur une instance ; (b) les sauvegardes quotidiennes de cette base ; (c) un répertoire de modèles de documents lu et modifié par trois serveurs d'application ; (d) les images de conteneurs d'un registre ; (e) le disque système d'une instance.
Solution
(a) Bloc : PostgreSQL attend un système de fichiers local à faible latence, avec écritures partielles et fsync. (b) Objet, idéalement versionné et verrouillé, dans une autre région : une sauvegarde est un fichier écrit une fois et rarement relu. (c) Fichier : plusieurs machines doivent voir le même arbre et le modifier ; un bucket conviendrait aussi si l'application peut être adaptée à une API objet, ce qui supprime une dépendance zonale. (d) Objet : un registre OCI stocke des couches immuables adressées par leur empreinte, c'est exactement le modèle clé-valeur (Harbor, comme la plupart des registres, sait utiliser un bucket S3). (e) Bloc (ou disque local) : le système démarre sur un périphérique.
2. Le volume récalcitrant (niveau 200). Après le redémarrage de sig-app-1, l'instance ne répond plus en SSH. La console série montre un message d'attente de périphérique puis un shell de secours. Le dernier changement est l'ajout de cette ligne dans /etc/fstab : /dev/sdb /srv/exports ext4 defaults 0 2. Expliquez les deux défauts de cette ligne, et ce qui a pu se passer.
Solution
Premier défaut : le montage par nom de périphérique. Si un autre volume a été attaché ou détaché entre-temps, sdb peut désigner un autre disque, ou ne plus exister. Second défaut : l'absence de nofail. Un montage listé dans fstab sans nofail est requis pour atteindre la cible de démarrage normale ; si le périphérique est absent (volume détaché, par exemple avant un instantané, ou supprimé), systemd attend, puis bascule en mode de secours, où SSH ne démarre pas. Correction depuis la console série : commenter la ligne, redémarrer, puis la réécrire avec UUID=... et defaults,nofail, et tester avec mount -a avant le prochain redémarrage.
3. Une politique trop large (niveau 200). Un collègue propose cette politique pour le bucket des pièces jointes : un seul énoncé, principal application_id:<ID_APPLICATION_API>, action "*", ressources signalements-pj-xxxxxx et signalements-pj-xxxxxx/*. Il la pousse avec sa propre clé d'API d'utilisateur. Qu'arrive-t-il juste après, et quels sont les risques si la clé de l'application fuit ? Réécrivez l'énoncé.
Solution
Juste après, le collègue (et toute l'équipe) perd l'accès au bucket, puisqu'il n'est pas dans la politique : seul le propriétaire de l'organisation pourra la supprimer ou la corriger. Si la clé de l'application fuit, l'attaquant peut lister tout le bucket, télécharger toutes les photos, les supprimer, et même modifier ou supprimer la politique (l'action * couvre s3:PutBucketPolicy). Réécriture : l'application reçoit seulement s3:GetObject et s3:PutObject sur signalements-pj-xxxxxx/photos/*, et un second énoncé accorde l'administration à un groupe ou à des utilisateurs nommés de l'équipe.
4. Calculer une durabilité (niveau 200). Un système stocke chaque objet avec un code d'effacement k = 6, m = 3, fragments répartis à parts égales sur trois zones. Quel est le surcoût d'espace ? Combien de disques peuvent tomber simultanément sans perte ? L'objet reste-t-il lisible si une zone entière disparaît ? Comparez avec trois copies complètes, une par zone.
Solution
Surcoût : (6 + 3) / 6 = 1,5, soit 50 % d'espace en plus. N'importe quels 6 fragments sur 9 suffisent : on survit à la perte de 3 fragments, donc de 3 disques s'ils portent chacun un fragment. Une zone porte 3 fragments sur 9 ; si elle disparaît, il en reste 6, l'objet est reconstituable, mais toute perte supplémentaire le rend illisible tant que les fragments manquants ne sont pas reconstruits ailleurs. Trois copies complètes coûtent 200 % d'espace en plus et survivent à la perte de deux zones entières, mais pour un coût double. C'est l'arbitrage que font les fournisseurs, et la raison pour laquelle leurs paramètres réels ne sont pas toujours publiés.
Récapitulatif
- Le stockage bloc expose un disque (vous gérez le système de fichiers, une seule instance, une zone) ; le stockage fichier un partage monté par plusieurs instances ; le stockage objet une API HTTP de clés et d'objets entiers, régionale.
- Chez Scaleway : Local Storage sur l'hyperviseur, Block Storage
sbs_5ketsbs_15krépliqué trois fois dans une zone, File Storage monté envirtiofs, Object Storage compatible S3 en classes Multi-AZ, One Zone et Glacier. - La durabilité (ne pas perdre) n'est pas la disponibilité (pouvoir lire), et aucune des deux n'est une sauvegarde : la réplication copie aussi les erreurs.
- Un volume se monte par UUID avec
nofail; un instantané est cohérent après plantage par défaut, applicatif avecfsfreezeou les outils de la base. - Un bucket de données reste privé ; on partage par URL présignée, on restreint par politique de bucket (version
2023-04-17, autorisations seules), on protège par versionnement, Object Lock et cycle de vie. - L'état d'une application vit dans des services managés, pas sur le disque de l'instance.
Pour aller plus loin
- La FAQ Object Storage de Scaleway, en particulier les sections sur les classes, Glacier et le cycle de vie : elle répond à la plupart des questions de dimensionnement.
- La documentation de Ceph sur les codes d'effacement, pour comprendre les arbitrages entre espace, performance et tolérance aux pannes.
- La page Data protection in Amazon S3 d'AWS, qui distingue nettement durabilité, versionnement, réplication et verrouillage.
- La leçon suivante, Le réseau, qui retire les adresses publiques des instances et ne laisse joignable que le répartiteur de charge.
Sources
- Scaleway, Block Storage : concepts, FAQ et montage d'un volume
- Scaleway, File Storage : FAQ et montage d'un système de fichiers
- Scaleway, Object Storage : concepts, FAQ, politiques de bucket, cycle de vie, Object Lock
- Scaleway, Using Object Storage with the AWS-CLI
- Scaleway, modèle de responsabilité partagée des services de stockage
- scaleway/scaleway-cli, documentation des commandes block et instance
- AWS, Amazon S3 : protection des données et durabilité
- AWS, Amazon S3 now delivers strong read-after-write consistency (1er décembre 2020)
- AWS, Create Amazon EBS snapshots
- AWS SDKs and Tools Reference Guide, Data Integrity Protections for Amazon S3
- AWS, blocage de l'accès public et ACL désactivées par défaut (avril 2023)
- Ceph, documentation : erasure code
- The Register, 14 millions de clients Verizon exposés par un bucket S3 public (juillet 2017)
- util-linux, page de manuel fsfreeze(8)