Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

S3 et compatibles

Le backend s3 range les fichiers comme objets d’un bucket AWS S3 ou d’un stockage compatible (MinIO, Garage, Scaleway…).

[[backends]]
name = "archives"
type = "s3"
bucket = "archives"
region = "eu-west-3"
prefix = "sftp/"
endpoint_url = "https://minio.interne.example:9000"   # sans la cle : AWS

[backends.credentials]
type = "static"
access_key_id = "AKIAEXEMPLE"
secret_access_key = "changez-moi"

[[roles]]
name = "archivistes"

[[roles.mounts]]
backend = "archives"
home_dir = "/{username}"
acl = [{ path = "/", rights = ["read", "write", "list"], recursive = true }]

alice envoie /in/x.txt : l’objet est la cle sftp/alice/in/x.txt.

Les cles

Toutes les cles : Reference [[backends]] type = “s3”.

iam_role : variables AWS_*, profil, role de l’instance ou du pod. Cles communes : Les backends.

Fichiers et repertoires

Ce que voit le clientSur le stockage
un fichierune cle
un repertoireun marqueur <cle>/, ou toute cle sous <cle>/
un mkdirecrit le marqueur
parents manquants d’un envoiun marqueur par niveau, chacun juge par l’ACL comme un mkdir
un repertoire sans marqueurtaille 0, sans date

Une cle et un repertoire du meme nom peuvent coexister, sauf avec refuse_upload_over_directory = true.

OperationRequetes S3
lecture SFTPun HeadObject a l’ouverture, puis un GetObject avec Range par lecture
telechargement RESTun GetObject lu en flux
envoi de moins de 8 Mioun PutObject avec If-None-Match: *, a la fin
envoi de 8 Mio ou plusun upload multipart, une part de 8 Mio a la fois
renommage d’un fichierCopyObject avec If-None-Match: *, puis DeleteObject de la source
listageListObjectsV2 avec le delimiteur /, page apres page
suppression d’un arbreListObjectsV2 par 1 000 cles, puis DeleteObjects par lot

Un objet s’ecrit en entier : ni reprise (reput), ni ajout. Seul un fichier se renomme.

Les droits du bucket

Sur le bucket et <prefix>/* :

ActionPour
s3:ListBucketlister, distinguer un repertoire, trouver les parents manquants, mkdir, renommer, supprimer un arbre
s3:GetObjecttelecharger, stat, et l’examen qui precede une suppression ou un renommage
s3:PutObjectenvoyer, mkdir, renommer, l’auto-test des ecritures conditionnelles
s3:DeleteObjectsupprimer, renommer, nettoyer la cle de l’auto-test
s3:AbortMultipartUploadannuler un upload multipart qui ne sera pas complete
s3:ListBucketMultipartUploadsbalayer les uploads multipart abandonnes
s3:ListMultipartUploadPartsdater la derniere part d’un candidat au balayage

Un backend en lecture seule n’a besoin que de s3:ListBucket et s3:GetObject.

Les uploads multipart

Un upload multipart jamais complete reste facture jusqu’a son annulation :

QuandAnnulation
un envoi finit sans completeraussitot, quelle qu’en soit la cause
arret propreceux encore en vol, 5 s au plus
un processus tuele balayage sous <prefix>/ : au demarrage, toutes les grace_secs et a chaque envoi, quand la derniere part a plus de grace_secs sur l’horloge du service
  • Donnez un prefix a chaque backend : le balayage ne travaille que sous lui.
  • Un upload lent envoie une part vide toutes les 15 s, qui le date pour les autres instances ; celles-ci ont le meme uploads.idle_timeout_secs.
  • Une regle de cycle de vie reste conseillee :
{"Rules": [{"ID": "abort-incomplete-multipart", "Status": "Enabled", "Filter": {"Prefix": ""},
            "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 2}}]}

Son delai, compte depuis l’initiation, depasse le plus long envoi. MinIO expire de lui-meme les uploads incomplets (stale_uploads_expiry).

Les ecritures conditionnelles

replaced dans l’audit et le marqueur de reservation reposent sur If-None-Match: * et If-Match de PutObject. Derriere un endpoint_url (et sur AWS avec cross_instance_reservation), le serveur les mesure au demarrage, sur la cle <prefix>/.craftfilegate-upload-precondition.<16 hex> ensuite supprimee ; le verdict tient jusqu’au redemarrage. MinIO : honoured.

Les cles communes sur S3

CleSur S3
home_dir (montage)un prefixe : la cle est <prefix>/<home_dir>/<chemin>, parties vides omises
create_home (montage)sans effet : un prefixe existe des qu’une cle est dessous
refuse_upload_over_directorytrue : un envoi sur un nom qui est aussi un repertoire est refuse ; cout : un listage d’une cle a l’ouverture de chaque envoi
cross_instance_reservationun objet marqueur <lock_prefix><nom>, pose avec If-None-Match: *
lock_prefixle nom de ces marqueurs
stale_partialsle balayage des uploads multipart abandonnes
case_insensitivefalse par defaut : les cles sont sensibles a la casse
hidden_storessans objet : un objet n’apparait qu’une fois complet

Performances et limites

  • Chaque envoi en cours retient un tampon de 8 Mio (Memoire) ; ses ecritures sont sequentielles.
  • Un envoi hors de la racine paie un listage par niveau parent.
  • Le client adresse le bucket dans le chemin de l’URL (path-style), AWS compris.
  • 10 000 parts au plus par objet, soit environ 78 Gio a 8 Mio la part.
  • Sur un bucket versionne, l’auto-test laisse deux versions vides et un marqueur de suppression par demarrage.

Ce que vous verrez

QuandLigne
demarrageINFO S3 backend initialized, champs bucket, prefix, endpoint
demarrage, auto-testINFO S3 upload precondition self-test, champs backend, verdict = honoured, probe_key
balayageINFO aborted an abandoned multipart upload: ..., champs bucket, key, upload_id, age_secs
arretINFO uncompleted S3 multipart uploads aborted before the shutdown completes, champ aborted