16 Min. Lesezeit

Lernziele

Am Ende dieses Moduls werden Sie in der Lage sein:

  • Einen `boto3` S3-Client für IONOS Cloud Object Storage mit dem korrekten regionalen Endpoint und der Authentifizierung über Access Key + Secret Key konfigurieren
  • Presigned-URL-Flows implementieren, damit Browser Dateien direkt hochladen und herunterladen, ohne dass die API die Bytes weiterleitet
  • Multipart-Uploads für große Dateien und Streaming-Downloads mit korrekter Content-Type-Verarbeitung implementieren
  • Lifecycle-Richtlinien für Buckets programmgesteuert konfigurieren, um Objekte ablaufen zu lassen und unvollständige Multipart-Uploads aufzuräumen
  • Zu erkennen, welche S3-API-Funktionen IONOS Cloud Object Storage unterstützt, und defensiv gegen Kompatibilitätslücken zu coden

Einheit 4.2: Object Storage Integration

Einführung

TaskBoard ermöglicht es Benutzern, Dateien an Aufgaben anzuhängen: Screenshots, PDFs, Design-Mockups, gelegentlich auch Videos mit mehreren Gigabyte. Sie möchten nicht, dass diese Bytes durch Ihren API-Prozess fließen. Sie verbrauchen Arbeitsspeicher, blockieren Worker-Threads und verwandeln eine stateless API in eine Engstelle. Die Lösung ist IONOS Cloud Object Storage mit presigned URLs: Der Browser kommuniziert direkt mit Object Storage, und Ihre API verarbeitet ausschließlich kleine Metadatensätze.

In dieser Einheit verbinden Sie die TaskBoard-API mit Object Storage über die S3-kompatible API mithilfe von boto3. Das Wichtigste, das Sie von Anfang an verinnerlichen sollten: Object Storage verwendet nicht Ihr IONOS CLOUD Bearer Token. Die Authentifizierung erfolgt über ein separates Access Key- und Secret Key-Paar, genau wie bei AWS S3. Sie richten den Client ein, generieren presigned Upload- und Download-URLs, verarbeiten große Dateien mit Multipart Upload und wenden Lifecycle-Regeln an, damit verwaiste Uploads nicht dauerhaft Kosten verursachen.

1. Authentifizierung und Verbindung mit boto3

Object Storage stellt eine AWS S3 API v2-Oberfläche bereit, sodass die standardmäßigen AWS SDKs damit funktionieren. Geändert werden lediglich der Endpunkt und die Zugangsdaten. Sie müssen einen expliziten endpoint_url übergeben (das SDK verwendet standardmäßig AWS, nicht IONOS CLOUD) sowie ein Access Key + Secret Key-Paar. Diese Schlüssel sind weder Ihr Cloud API Bearer Token noch eine IAM Rolle. Sie werden separat generiert und authentifizieren jede S3-Anfrage über AWS Signature.

Object Storage authentifiziert Benutzer mit einem Schlüsselpaar: einem Access Key und einem Secret Key. Ein Schlüssel muss manuell generiert werden, entweder im DCD unter Object Storage Credentials and Management oder über die Object Storage Management API. Die aktuelle Länge des Access Key beträgt 92 Zeichen und die Länge des Secret Key 64 Zeichen. Vermeiden Sie daher hart codierte Annahmen über Feldbreiten aus älteren 20/40-Zeichen-Formaten. Jeder Benutzer kann bis zu 5 Access Keys besitzen.

1.1 Erstellen des S3 Clients

Bevor Sie Client-Code schreiben, fixieren Sie Ihre boto3 Version: boto3 1.36.0 und neuer führen zu einem Fehlschlag jedes PutObject Aufrufs gegen IONOS CLOUD Object Storage mit InvalidTrailer („Invalid trailing header names in x-amz-trailer“), da IONOS CLOUD die AWS trailing-checksum-Erweiterung, die mit boto3 ab Version 1.36.0 ausgeliefert wurde, nicht unterstützt. Installieren Sie boto3<=1.35.99, oder wenn Sie eine neuere Version von boto3 benötigen, setzen Sie die Umgebungsvariablen AWS_REQUEST_CHECKSUM_CALCULATION=when_required und AWS_RESPONSE_CHECKSUM_VALIDATION=when_required vor jedem Upload-Pfad in dieser Einheit (presigned PUT, upload_file, upload_fileobj, multipart), damit diese funktionieren.

Wählen Sie den Endpunkt für die Region, in der Ihr Bucket liegt. Der Endpunkt-Hostname kodiert die Region, und das SDK leitet die Signierungsregion daraus ab, sodass Sie region_name minimal halten und den Endpunkt die Routing-Entscheidung treffen lassen können.

import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    endpoint_url="https://s3.eu-central-1.ionoscloud.com",  # Frankfurt (de)
    aws_access_key_id="YOUR_ACCESS_KEY",       # 92-char Object Storage key
    aws_secret_access_key="YOUR_SECRET_KEY",   # 64-char Object Storage secret
    region_name="eu-central-1",
    config=Config(signature_version="s3v4"),
)

# Smoke test: list buckets you own
for b in s3.list_buckets()["Buckets"]:
    print(b["Name"], b["CreationDate"])

Legen Sie Zugangsdaten niemals direkt im Quellcode ab. Rufen Sie diese aus Umgebungsvariablen oder einem Secret Manager ab. In TaskBoard stammen der Access Key und der Secret Key aus dem Terraform State (das ionoscloud_s3_key-Ressource aus Einheit 2.4) und werden als Kubernetes Secrets injiziert.

import os

s3 = boto3.client(
    "s3",
    endpoint_url=os.environ["OBJSTORAGE_ENDPOINT"],
    aws_access_key_id=os.environ["OBJSTORAGE_ACCESS_KEY"],
    aws_secret_access_key=os.environ["OBJSTORAGE_SECRET_KEY"],
    region_name=os.environ.get("OBJSTORAGE_REGION", "eu-central-1"),
    config=Config(signature_version="s3v4"),
)

1.2 Auswahl des richtigen regionalen Endpunkts

Der Endpunkt ist nicht austauschbar. Ein Bucket existiert in genau einer Region, und Sie müssen es über den Endpunkt dieser Region adressieren. Object Storage ist in Berlin, Frankfurt, Logroño und Lenexa verfügbar. Die folgende Tabelle ordnet Rechenzentren ihren Regionen und S3-Endpunkten zu:

Rechenzentrum Region Endpunkt
Frankfurt, Deutschland de s3.eu-central-1.ionoscloud.com
Berlin, Deutschland eu-central-2 s3.eu-central-2.ionoscloud.com
Logroño, Spanien eu-south-2 s3.eu-south-2.ionoscloud.com
Frankfurt, Deutschland eu-central-4 s3.eu-central-4.ionoscloud.com
Berlin, Deutschland eu-central-3 s3.eu-central-3.ionoscloud.com
Lenexa, USA us-central-1 s3.us-central-1.ionoscloud.com

Wählen Sie eine Region in der Nähe Ihrer Anwendung und Ihrer Nutzer, um die Latenz zu reduzieren, und eine geografisch getrennte Region für Sicherungen, damit ein lokaler Ausfall Ihre primären Daten nicht mitnimmt. Beachten Sie die zwei Bucket-Typen: nutzerzugehörige Buckets befinden sich in de, eu-central-2 und eu-south-2, während vertragszugehörige Buckets in eu-central-4, eu-central-3 und us-central-1 liegen. Die Grenzen unterscheiden sich je nach Typ: Ein Nutzer kann bis zu 500 nutzerzugehörige Buckets und bis zu 1000 vertragszugehörige Buckets halten. Die Höchstgrenze für Uploads mit einer einzelnen Anfrage beträgt 4,65 GiB für nutzerzugehörige Buckets und 5 GiB für vertragszugehörige Buckets, was der praktische Auslöser für den Multipart-Upload ist, der in Abschnitt 3 behandelt wird.

2. Bucket-Operationen und Presigned URLs

Mit einem Client in der Hand sind die alltäglichen Operationen Standard-S3: Bucket erstellen, Objekte auflisten, ACLs setzen und Presigned URLs generieren. Für TaskBoard sind Presigned URLs der zentrale Baustein. Sie ermöglichen es dem Browser, Anhänge direkt mit Object Storage hoch- und herunterzuladen, sodass Ihre API die Bytes nie streamen muss.

Standardmäßig sind Objekte privat und nur der Bucket-Besitzer kann auf sie zugreifen. Eine Presigned URL gewährt zeitlich begrenzten Zugriff auf ein einzelnes Objekt, ohne die Berechtigungen des Objekts zu ändern und ohne Ihre Schlüssel freizugeben. Der Besitzer signiert die URL, übergibt sie dem Client, und der Client verwendet sie, bis sie abläuft.

2.1 Buckets erstellen und Objekte auflisten

Bucket-Namen sind in Object Storage global eindeutig, müssen zwischen 3 und 63 Zeichen lang sein und folgen den DNS-Namensregeln. Objektschlüssel können bis zu 1024 Zeichen lang sein.

bucket = "taskboard-attachments-prod"

# Create the bucket (idempotent-ish: catch the "already owned" case)
try:
    s3.create_bucket(Bucket=bucket)
except s3.exceptions.BucketAlreadyOwnedByYou:
    pass

# List objects under a prefix, paginated (collections can be huge)
paginator = s3.get_paginator("list_objects_v2")
for page in paginator.paginate(Bucket=bucket, Prefix="task-42/"):
    for obj in page.get("Contents", []):
        print(obj["Key"], obj["Size"])

Listen Sie immer paginiert ab. Ein einzelner Bucket kann im nicht versionierten Fall bis zu 200.000.000 Objekte enthalten, sodass eine nicht paginierte Liste stillschweigend bei der ersten Seite abgeschnitten wird.

2.2 Presigned Upload- und Download-URLs

Erzeugen Sie eine presigned PUT URL, damit der Browser die Datei direkt hochlädt. Ihre API gibt die URL und den Objektschlüssel zurück; sie sieht niemals den Dateiinhalt.

def presign_upload(key: str, content_type: str, expires: int = 900) -> str:
    return s3.generate_presigned_url(
        "put_object",
        Params={"Bucket": bucket, "Key": key, "ContentType": content_type},
        ExpiresIn=expires,  # seconds; keep short for uploads
    )

def presign_download(key: str, expires: int = 300) -> str:
    return s3.generate_presigned_url(
        "get_object",
        Params={"Bucket": bucket, "Key": key},
        ExpiresIn=expires,
    )

Der Browser lädt anschließend mit einer einfachen HTTP-Anforderung an die signierte URL hoch. Das Content-Type muss mit dem signierten Inhalt übereinstimmen, andernfalls schlägt die Signaturprüfung fehl:

await fetch(presignedUrl, {
  method: "PUT",
  headers: { "Content-Type": file.type },
  body: file,
});

Presigned URLs eignen sich ideal, um anderen Benutzern das direkte Hochladen von Objekten in Ihren Bucket zu ermöglichen, ohne dass Sie ihnen Ihren Access Key und Secret Key übergeben müssen. Sie sind auch das richtige Werkzeug, um ein privates Objekt mit jemandem zu teilen, der kein IONOS CLOUD-Konto hat: Die URL funktioniert für den konfigurierten Zeitraum und läuft anschließend ab. Sowohl Signature v2 als auch v4 werden unterstützt; verwenden Sie v4.

3. Muster für Datei-Uploads und -Downloads

Kleine Anhänge sind ein einzelner put_object. Große Anhänge erfordern einen Multipart-Upload, sowohl um die Größenbeschränkung für einzelne Anfragen zu umgehen als auch um Teile parallel hochzuladen und so die Geschwindigkeit zu erhöhen. Ein einzelnes Objekt kann bis zu 5 TB (5.497.558.138.880 Bytes) groß sein.

3.1 Multipart-Upload für große Dateien

Das Upload-Limit für eine einzelne Anfrage beträgt 4,65 GiB (benutzereigen) oder 5 GiB (vertragsgebunden). Darüber hinausgehend davon muss die Multipart-Upload-API verwendet werden. Die hochstufigen upload_file und upload_fileobj von boto3 handhaben Multipart automatisch, sobald eine Datei den konfigurierten Schwellenwert überschreitet. Dies ist der produktionsreife Weg.

from boto3.s3.transfer import TransferConfig

# Switch to multipart above 100 MB, 8 MB parts, up to 4 parallel uploads
transfer_cfg = TransferConfig(
    multipart_threshold=100 * 1024 * 1024,
    multipart_chunksize=8 * 1024 * 1024,
    max_concurrency=4,
)

s3.upload_file(
    Filename="/tmp/build-artifact.zip",
    Bucket=bucket,
    Key="task-42/build-artifact.zip",
    Config=transfer_cfg,
    ExtraArgs={"ContentType": "application/zip"},
)

Der Multipart-Upload zerlegt ein großes Objekt in kleinere Teile und lädt diese parallel hoch, um die Durchsatzrate zu maximieren. Er ist über die API und die SDKs verfügbar, nicht jedoch über die DCD-Weboberfläche. Wenn ein Multipart-Upload abgebrochen wird, verbleiben die hochgeladenen Teile und verursachen Speicherkosten, bis Sie sie bereinigen. Genau dafür ist die Lifecycle-Regel in Abschnitt 4 vorgesehen.

3.2 Streaming-Downloads und Content-Type

Bei Downloads sollte der Body gestreamt werden, anstatt das gesamte Objekt in den Arbeitsspeicher zu laden. Der Response-Body ist ein dateiähnlicher Stream, den Sie in Blöcken iterieren können.

resp = s3.get_object(Bucket=bucket, Key="task-42/report.pdf")
content_type = resp["ContentType"]  # set at upload time

with open("/tmp/report.pdf", "wb") as f:
    for chunk in resp["Body"].iter_chunks(chunk_size=1024 * 1024):
        f.write(chunk)

Setzen Sie ContentType beim Hochladen explizit fest. Wenn Sie diesen Schritt überspringen, verwenden Downloads standardmäßig einen generischen Binärdateityp, und Browser zeigen einen Download-Dialog an, anstatt die Datei inline darzustellen.

4. Lifecycle-Richtlinien und Kostenkontrolle

Object Storage berechnet Gebühren für die gespeicherten Daten. Daher stellen verwaiste Objekte und aufgegebene Multipart-Uploads eine schleichende Kostenquelle dar. Lifecycle-Regeln ermöglichen es, Objekte automatisch ablaufen zu lassen und unvollständige Uploads zu bereinigen. Sie werden über die S3 API konfiguriert.

Eine Lifecycle-Konfiguration unterstützt folgende Aktionen: Ablauf von aktuellen Versionen, endgültige Löschung nicht aktueller Versionen, Löschung abgelaufener Objekt-Löschmarker sowie Löschung unvollständiger Multipart-Uploads. In einer Konfiguration können bis zu 1000 Regeln eingerichtet werden. Jede Regel gilt für ein anderes Objekt-Präfix, und es können nicht mehr als eine Regel für dasselbe Präfix festgelegt werden.

4.1 Objekte ablaufen lassen und Multipart-Uploads bereinigen

Diese Konfiguration lässt temporäre Uploads nach 7 Tagen ablaufen und bricht unvollständige Multipart-Uploads nach 1 Tag ab:

s3.put_bucket_lifecycle_configuration(
    Bucket=bucket,
    LifecycleConfiguration={
        "Rules": [
            {
                "ID": "expire-temp-uploads",
                "Filter": {"Prefix": "tmp/"},
                "Status": "Enabled",
                "Expiration": {"Days": 7},
            },
            {
                "ID": "abort-incomplete-multipart",
                "Filter": {"Prefix": ""},
                "Status": "Enabled",
                "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 1},
            },
        ]
    },
)

Object Storage unterstützt derzeit nur die STANDARD-Speicherklasse, sodass Sie keine Lebenszyklusregeln verwenden können, um Objekte in eine kühlere Ebene zu verschieben. Die einzigen verfügbaren Aktionen sind Ablauf und Bereinigung. Wenn ein Bucket Object Lock verwendet, können nicht aktuelle Versionen nicht gelöscht werden, bevor ihre Aufbewahrungsfrist abgelaufen ist.

5. S3-Kompatibilität: Was unterstützt wird und was nicht

Object Storage bietet einen der höchsten Unterstützungsgrade für die S3 API, erreicht jedoch keine 100-prozentige Parität mit AWS. Prüfen Sie eine Funktion, bevor Sie sich darauf verlassen, anstatt vorauszusetzen, dass sie sich exakt wie AWS S3 verhält. Die folgende Tabelle fasst die Unterstützung wesentlicher Funktionen zusammen:

Funktion Unterstützt Hinweise
Objekt-Kopie Ja Kopieren über Regionen hinweg wird nicht unterstützt
Pre-Signed URLs Ja Die Signaturtypen v2 und v4 werden unterstützt
CORS-Konfiguration Ja
Bucket-Versionierung Ja
Bucket-Replikation Ja Intraregionale Replikation wird für beide Bucket-Typen unterstützt; cross-regionale Replikation wird nur für benutzereigene Buckets unterstützt (derzeit nicht für vertragsgebundene Buckets verfügbar)
Bucket-Verschlüsselung Ja Serverseitige Verschlüsselung (AES-256) wird standardmäßig in der Web-Oberfläche verwendet; kundengesteuerte Schlüssel sind über die API verfügbar

Einige Einschränkungen, die bei der Codeerstellung zu berücksichtigen sind. Objekt-Kopie unterstützt keine Kopien über Regionen hinweg, daher ist eine Operation wie „Bucket in eine andere Region verschieben“ ein Download gefolgt von einem Upload und keine serverseitige Kopie. Object Lock (Modi GOVERNANCE und COMPLIANCE) kann nur zum Zeitpunkt der Bucket-Erstellung aktiviert werden und nie nachträglich auf ein bestehendes Bucket angewendet werden. Bucket Policy verwendet standardmäßiges JSON mit einem Version von 2012-10-17. Verschlüsselung während der Übertragung erfolgt über TLS 1.2 oder 1.3.

5.1 CORS für Browser-Uploads

Da TaskBoard Browser-Uploads direkt über Pre-Signed URLs an Object Storage sendet, benötigt das Bucket eine CORS-Konfiguration, die PUT von Ihrem Web-Origin erlaubt. Ohne diese Konfiguration blockiert der Browser die cross-origin Anfrage, bevor sie Object Storage erreicht.

s3.put_bucket_cors(
    Bucket=bucket,
    CORSConfiguration={
        "CORSRules": [
            {
                "AllowedOrigins": ["https://app.taskboard.example"],
                "AllowedMethods": ["PUT", "GET"],
                "AllowedHeaders": ["*"],
                "MaxAgeSeconds": 3000,
            }
        ]
    },
)

Die maßgebliche S3 API-Referenz befindet sich unter https://api.ionos.com/docs/s3/v2/, und die API für die Verwaltung von Keys und Buckets ist unter https://api.ionos.com/docs/s3-management/v1/ dokumentiert. Im Zweifel zu einer Funktion, prüfen Sie diese Quellen, bevor Sie Code schreiben, der von ihr abhängt.

API-Referenz Schnellkarte

Wichtige S3-Operationen für Object Storage (über boto3 oder signierte HTTP-Anfragen):

Methode Operation Beschreibung
PUT /{bucket} Bucket erstellen
GET /{bucket}?list-type=2 Objekte auflisten (paginiert)
PUT /{bucket}/{key} Objekt hochladen
GET /{bucket}/{key} Objekt herunterladen
POST /{bucket}/{key}?uploads Multipart-Upload starten
PUT /{bucket}?lifecycle Lifecycle-Konfiguration festlegen

Endpunkt: https://s3.<region>.ionoscloud.com (z. B. s3.eu-central-1.ionoscloud.com) Authentifizierung: AWS Signature v4 mit Access Key und Secret Key (kein Bearer Token)

Code Lab

Ziel: Hochladen und Abrufen eines TaskBoard-Anhangs über boto3 unter Verwendung von presigned URLs und Multipart-Upload, um die Authentifizierung mit Access Key + Secret Key zu bestätigen.

Voraussetzungen:

  • IONOS CLOUD-Konto mit einem generierten Object Storage Access Key + Secret Key
  • Python 3.9+ mit einer kompatiblen Version von boto3 installiert (pip install "boto3<=1.35.99"); boto3 1.36.0 und neuere Versionen führen bei jedem PutObject-Aufruf gegen IONOS CLOUD Object Storage zu InvalidTrailer, da IONOS CLOUD die in dieser Version eingeführte AWS trailing-checksum-Erweiterung nicht unterstützt. Daher die Version festlegen oder AWS_REQUEST_CHECKSUM_CALCULATION=when_required und AWS_RESPONSE_CHECKSUM_VALIDATION=when_required setzen, falls eine neuere boto3-Version verwendet werden muss
  • Ein Region-Endpunkt ausgewählt (dieses Lab verwendet Frankfurt de / eu-central-1)

Schritt 1: Zugangsdaten exportieren

export OBJSTORAGE_ENDPOINT="https://s3.eu-central-1.ionoscloud.com"
export OBJSTORAGE_ACCESS_KEY="<your-92-char-access-key>"
export OBJSTORAGE_SECRET_KEY="<your-64-char-secret-key>"
export OBJSTORAGE_REGION="eu-central-1"

Erwartete Ausgabe:

(no output; variables set)

Schritt 2: Erstellen Sie den Client und einen Bucket

import os, boto3
from botocore.config import Config

s3 = boto3.client("s3",
    endpoint_url=os.environ["OBJSTORAGE_ENDPOINT"],
    aws_access_key_id=os.environ["OBJSTORAGE_ACCESS_KEY"],
    aws_secret_access_key=os.environ["OBJSTORAGE_SECRET_KEY"],
    region_name=os.environ["OBJSTORAGE_REGION"],
    config=Config(signature_version="s3v4"))

bucket = "taskboard-lab-<your-initials>"
s3.create_bucket(Bucket=bucket)
print("created", bucket)

Erwartete Ausgabe:

created taskboard-lab-ct

Schritt 3: Eine presigned Upload-URL generieren

url = s3.generate_presigned_url("put_object",
    Params={"Bucket": bucket, "Key": "task-1/note.txt", "ContentType": "text/plain"},
    ExpiresIn=900)
print(url)

Erwartete Ausgabe:

https://s3.eu-central-1.ionoscloud.com/taskboard-lab-ct/task-1/note.txt?X-Amz-Algorithm=...

Schritt 4: Hochladen über die presigned URL mit curl

echo "hello taskboard" > note.txt
curl -X PUT -H "Content-Type: text/plain" --upload-file note.txt "<PASTE_PRESIGNED_URL>"

Erwartete Ausgabe:

(HTTP 200, empty body)

Schritt 5: Hochladen einer großen Datei per Multipart-Upload

from boto3.s3.transfer import TransferConfig
cfg = TransferConfig(multipart_threshold=5*1024*1024, multipart_chunksize=5*1024*1024)
s3.upload_file("bigfile.bin", bucket, "task-1/bigfile.bin", Config=cfg,
               ExtraArgs={"ContentType": "application/octet-stream"})
print("uploaded large file")

Erwartete Ausgabe:

uploaded large file

Schritt 6: Download über eine presigned GET-URL

get_url = s3.generate_presigned_url("get_object",
    Params={"Bucket": bucket, "Key": "task-1/note.txt"}, ExpiresIn=300)
import urllib.request
print(urllib.request.urlopen(get_url).read().decode())

Erwartete Ausgabe:

hello taskboard

Schritt 7: Eine Lebenszyklusregel hinzufügen, um unvollständige Uploads bereitzustellen

s3.put_bucket_lifecycle_configuration(Bucket=bucket,
    LifecycleConfiguration={"Rules": [{
        "ID": "abort-mpu", "Filter": {"Prefix": ""}, "Status": "Enabled",
        "AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 1}}]})
print("lifecycle set")

Erwartete Ausgabe:

lifecycle set

Prüfliste:

  • [ ] Bucket erstellt und in s3.list_buckets() sichtbar
  • [ ] Datei über presigned URLs hochgeladen und heruntergeladen
  • [ ] Multipart-Upload einer großen Datei war erfolgreich
  • [ ] Lifecycle-Regel wurde ohne Fehler angewendet

Aufräumen:

for obj in s3.list_objects_v2(Bucket=bucket).get("Contents", []):
    s3.delete_object(Bucket=bucket, Key=obj["Key"])
s3.delete_bucket(Bucket=bucket)
print("cleaned up")

Häufige Fehler

Entwicklertätigkeiten, die bei der Integration von Object Storage zu vermeiden sind:

  1. Versuch der Authentifizierung mit dem Bearer-Token der Cloud API

    • Problem: Jede S3-Anfrage gibt 403 SignatureDoesNotMatch oder InvalidAccessKeyId zurück.
    • Ursache: Object Storage verwendet AWS Signature mit einem Access Key + Secret Key-Paar, nicht das Bearer-Token von IONOS CLOUD, das der Rest der API verwendet, und auch keine IAM-Rollen. Es handelt sich um völlig separate Berechtigungssysteme.
    • Lösung: Erstellen Sie einen dedizierten Object Storage-Schlüssel (DCD oder Management API) und übergeben Sie ihn als aws_access_key_id / aws_secret_access_key. Die aktuellen Schlüssel sind 92 und 64 Zeichen lang; verwerfen Sie ältere Annahmen von 20/40 Zeichen.
  2. Weglassen von endpoint_url und versehentliches Erreichen von AWS

    • Problem: Anfragen laufen in ein Timeout, scheitern an DNS oder landen bei dem eigentlichen AWS S3.
    • Ursache: boto3 verwendet standardmäßig AWS-Endpunkte. Ohne endpoint_url kommuniziert das SDK nie mit IONOS CLOUD.
    • Lösung: Übergeben Sie immer den regionsspezifischen Endpunkt, z. B. endpoint_url="https://s3.eu-central-1.ionoscloud.com", und stimmen Sie region_name mit der Region dieses Endpunkts ab.
  3. Content-Type-Ungereimtheit, die presigned Uploads stört

    • Problem: Der Browser PUT an eine presigned URL gibt 403 SignatureDoesNotMatch zurück.
    • Ursache: Der Content-Type wurde beim Signieren der URL einbezogen, aber der Client hat einen anderen (oder keinen) Content-Type-Header gesendet. Signierte Header müssen exakt übereinstimmen.
    • Lösung: Signieren Sie mit dem exakten Content-Type und senden Sie den identischen Header vom Client, oder lassen Sie ContentType aus Params vollständig weg, damit er nicht Teil der Signatur ist.

Zusammenfassung

Sie können IONOS Cloud Object Storage nun über seine S3-kompatible API in Anwendungscode integrieren. Sie konfigurieren einen boto3-Client mit dem korrekten regionalen Endpoint sowie Access Key + Secret Key-Authentifizierung, verlagern Datei-Bytes von Ihrem API-Pfad mit presignierten Upload- und Download-URLs, verarbeiten große Dateien mit Multipart Upload, streamen Downloads und wenden Lifecycle-Regeln an, um die Speicherkosten unter Kontrolle zu halten. Der Anhang-Flow von TaskBoard ermöglicht es Browsern nun, direkt in Object Storage hochzuladen, während die API nur Metadaten erfasst.

Wichtige Punkte:

  • Object Storage authentifiziert sich mit einem 92 Zeichen langen Access Key und einem 64 Zeichen langen Secret Key über AWS Signature v4, niemals mit dem Bearer Token der Cloud API oder IAM-Rollen
  • Übergeben Sie immer einen expliziten endpoint_url, der der Region des Buckets entspricht; Bucket-Namen sind global eindeutig und 3 bis 63 Zeichen lang
  • Presignierte URLS gewähren zeitlich begrenzte, schlüssellose Zugriffe, sodass Clients direkt mit Object Storage hochladen und herunterladen
  • Verwenden Sie Multipart Upload für Dateien über dem Limit eines einzelnen Requests (4,65 GiB für benutzergehörige, 5 GiB für vertragsgehörige Objekte); Objekte können bis zu 5 TB groß sein
  • Object Storage bietet eine hohe S3-Kompatibilität, aber keine vollständige Parität: Cross-Region-Kopieren wird nicht unterstützt, Object Lock ist nur zum Erstellungszeitpunkt möglich, und es existiert nur die STANDARD-Speicherklasse

Wichtige Begriffe:

  • Access Key / Secret Key: Das S3-Zugangsdatenpaar (92 und 64 Zeichen), das jeden Object Storage-Request über AWS Signature authentifiziert.
  • Presignierte URL: Eine zeitlich begrenzte, signierte URL, die Zugriff auf ein einzelnes Objekt gewährt, ohne Schlüssel zu teilen oder Berechtigungen zu ändern; die Grundlage für direkte Browser-Uploads und Downloads.
  • Multipart Upload: Aufteilen eines großen Objekts in Teile, die parallel hochgeladen werden; erforderlich über dem Größenlimit eines einzelnen Requests und über Lifecycle-Regeln aufgeräumt.
  • Lifecycle-Regel: Eine Bucket-Konfiguration (bis zu 1000 Regeln), die Objekte abläuft und unvollständige Multipart Uploads automatisch abbricht.
  • Bucket-Typ: Benutzergehörige versus vertragsgehörige Buckets, die sich in regionaler Verfügbarkeit, benutzerbezogenen Bucket-Limits und Upload-Limits für einzelne Requests unterscheiden.

Nächste Schritte

Weiter lernen: Einheit 4.3: Event Streaming Integration

Verwandte Themen: