15 Min. Lesezeit

Lernziele

Am Ende dieses Moduls werden Sie in der Lage sein:

  • einen `boto3`-S3-Client gegen IONOS Cloud Object Storage mit dem richtigen regionalen Endpunkt und Access-Key- + Secret-Key-Authentifizierung konfigurieren
  • presigned URL-Flows implementieren, damit Browser Dateien direkt hoch- und herunterladen, ohne dass der API die Bytes zwischenspeichert
  • einen Mehrteil-Upload für große Dateien und Streaming-Downloads mit korrekter Content-Type-Verarbeitung implementieren
  • Bucket-Lebenszyklus-Richtlinien programmgesteuert konfigurieren, um Objekte ablaufen zu lassen und unvollständige Mehrteil-Uploads aufzuräumen
  • erkennen, welche S3-API-Funktionen IONOS Cloud Object Storage unterstützt und kompatibilitätsbedingt verteidigend coden

Einheit 4.2: Object Storage-Integration

Einführung

TaskBoard ermöglicht es Benutzern, Dateien zu Aufgaben anzuhängen: Screenshots, PDFs, Design-Mockups, gelegentlich auch mehrere Gigabyte große Videos. Sie möchten nicht, dass diese Bytes durch Ihren API-Prozess fließen. Sie verbrauchen Arbeitsspeicher, blockieren Worker-Threads und verwandeln einen zustandslosen API in eine Engstelle. Die Antwort ist IONOS Cloud Object Storage mit vorab unterzeichneten URLs: Der Browser spricht direkt mit Object Storage, und Ihr API bearbeitet nur kleine Metadaten-Sätze.

In dieser Einheit verbinden Sie den TaskBoard-API mit Object Storage über den S3-kompatiblen API mithilfe von boto3. Das Wichtigste, was Sie von vornherein internalisieren sollten: Object Storage verwendet nicht Ihren IONOS Cloud-Bearer-Token. Es authentifiziert sich mit einem separaten Zugriffsschlüssel- und Geheimnis-Schlüsselpaar, genau wie AWS-S3. Sie werden den Client einrichten, vorab unterzeichnete Upload- und Download-URLs generieren, große Dateien mit multipart-Upload bearbeiten und Lebenszyklusregeln anwenden, damit nicht abgebrochene Uploads nicht für immer Kosten ansammeln.

1. Authentifizierung und Verbindung mit boto3

Das Object Storage bietet eine AWS-S3-API-v2-Oberfläche, sodass die Standard-AWS-SDKs darauf funktionieren. Was sich ändert, ist der Endpunkt und die Anmeldedaten. Sie müssen einen expliziten endpoint_url übergeben (der SDK standardmäßig auf AWS und nicht auf IONOS festgelegt ist) und ein Zugriffsschlüssel- + Geheimschlüsselpaar. Diese Schlüssel sind nicht Ihr Cloud-API-Bearer-Token und kein IAM-Rolle. Sie werden separat generiert und authentifizieren jede S3-Anfrage über AWS-Signatur.

Das Object Storage authentifiziert Benutzer mit einem Paar von Schlüsseln: einem Zugriffsschlüssel und einem Geheimschlüssel. Ein Schlüssel muss manuell generiert werden, entweder im DCD unter Object Storage-Anmeldeinformationen und Verwaltung oder über die Object Storage-Verwaltungs-API. Die aktuelle Länge des Zugriffsschlüssels beträgt 92 Zeichen und die Länge des Geheimschlüssels 64 Zeichen, daher sollten Sie keine Feldbreitenannahmen aus älteren 20/40-Zeichen-Formaten hartcodieren. Jeder Benutzer kann bis zu 5 Zugriffsschlüssel besitzen.

1.1 Erstellung des S3-Clients

Bevor Sie irgendwelchen Client-Code schreiben, fixieren Sie Ihre boto3-Version: boto3 1.36.0 und später scheitern alle PutObject-Aufrufe gegen IONOS-Object Storage mit InvalidTrailer ("Invalid trailing header names in x-amz-trailer"), da IONOS die AWS-Trailing-Checksum-Erweiterung nicht unterstützt, die boto3 ab Version 1.36.0 ausgeliefert hat. Installieren Sie boto3<=1.35.99, oder wenn Sie eine neuere boto3-Version 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) wird funktionieren.

Wählen Sie den Endpunkt für die Region, in der Ihr Bucket gespeichert ist. Der Endpunktnamen kodiert die Region, und der SDK leitet die Signierungsregion daraus ab, sodass Sie die region_name minimal halten und den Endpunkt die Routing steuern 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"])

Nie sollten Anmeldeinformationen inline im Quellcode platziert werden. Stattdessen sollten sie aus Umgebungsvariablen oder einem Secret-Manager geholt werden. In TaskBoard werden der Access Key und der Secret Key aus dem Terraform-Zustand (der ionoscloud_s3_key-Ressource aus Einheit 2.4) ausgelesen und als Kubernetes-Geheimnisse 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 muss über den Endpunkt dieser Region angesprochen werden. 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 Benutzer, um die Latenz zu reduzieren, und eine geografisch separate Region für Sicherungen, damit ein lokaler Ausfall Ihre primären Daten nicht mit sich reißt. Beachten Sie die zwei Bucket-Typen: benutzerdefinierte Buckets leben in de, eu-central-2 und eu-south-2, während vertragsdefinierte Buckets in eu-central-4, eu-central-3 und us-central-1 leben. Die Grenzwerte unterscheiden sich je nach Typ: ein Benutzer kann bis zu 500 benutzerdefinierte Buckets und bis zu 1000 vertragsdefinierte Buckets halten. Die Obergrenze für den Upload in einer einzelnen Anfrage beträgt 4,65 GB für benutzerdefinierte Buckets und 5 GB für vertragsdefinierte Buckets, was den praktischen Auslöser für den in Abschnitt 3 behandelten Mehrteil-Upload darstellt.

2. Bucket-Operationen und Presigned-URLs

Mit einem Client können die alltäglichen Operationen standardmäßig durchgeführt werden: ein Bucket erstellen, Objekte auflisten, ACLs festlegen und Presigned-URLs generieren. Für TaskBoard sind Presigned-URLs das Zentrum. Sie ermöglichen es dem Browser, Anhänge direkt gegen Object Storage hochzuladen und herunterzuladen, sodass Ihre API niemals die Bytes streamt.

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

2.1 Erstellen von Buckets und Auflisten von Objekten

Bucket-Namen sind global eindeutig über alle Object Storage-Buckets hinweg, müssen zwischen 3 und 63 Zeichen lang sein und folgen den DNS-Benennungsregeln. 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 sollten immer paginiert werden. Ein einzelner Bucket kann bis zu 200.000.000 Objekte im nicht versionierten Fall enthalten, sodass eine nicht paginierte Liste stillschweigend auf der ersten Seite abgeschnitten wird.

2.2 Presigned-Upload- und Download-URLs

Generieren 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 jedoch 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 dann mit einer einfachen HTTP-Anfrage auf die signierte URL hoch. Der Content-Type muss mit dem übereinstimmen, was signiert wurde, sonst schlägt die Signaturprüfung fehl:

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

Presigned-URLs sind ideal, um anderen Benutzern zu ermöglichen, Objekte direkt in Ihren Bucket hochzuladen, ohne ihnen jemals Ihren Zugriffsschlüssel und Ihren geheimen Schlüssel zu übergeben. Sie sind auch das richtige Werkzeug, um ein privates Objekt mit jemandem zu teilen, der kein IONOS-Konto hat: die URL funktioniert für das konfigurierte Zeitfenster und läuft dann ab. Sowohl Signature v2 als auch v4 werden unterstützt, verwenden Sie v4.

3. Datei-Upload- und Download-Muster

Kleine Anhänge sind ein einzelnes put_object. Große Anhänge benötigen einen Mehrteil-Upload, sowohl um die Einzelanforderungs-Größenbegrenzung zu überwinden als auch um Teile parallel zum Upload zu übertragen, um die Geschwindigkeit zu erhöhen. Ein einzelnes Objekt kann bis zu 5 TB (5.497.558.138.880 Bytes) groß sein.

3.1 Mehrteil-Upload für große Dateien

Die Einzelanforderungs-Upload-Begrenzung beträgt 4,65 GB (benutzerdefiniert) oder 5 GB (vertragsdefiniert). Wenn diese Begrenzung überschritten wird, muss der Mehrteil-Upload API verwendet werden. boto3's hochstufige upload_file und upload_fileobj handhaben den Mehrteil-Upload automatisch, sobald eine Datei die konfigurierte Schwelle überschreitet, was der produktionsreife Pfad ist.

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 Mehrteil-Upload teilt ein großes Objekt in kleinere Teile auf und lädt sie parallel, um die Durchsatzrate zu maximieren. Er ist über den API und die SDKs verfügbar, nicht jedoch über die DCD-Weboberfläche. Wenn ein Mehrteil-Upload abgebrochen wird, bleiben die hochgeladenen Teile bestehen und verursachen Speicherungskosten, bis sie bereinigt werden, was genau das ist, was die Lebenszyklusregel in Abschnitt 4 handhabt.

3.2 Streaming-Downloads und Content-Type

Für Downloads sollte der Textkörper gestreamt werden, anstatt das gesamte Objekt in den Arbeitsspeicher zu laden. Der Textkörper 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 explizit beim Upload. Wenn Sie dies auslassen, werden Downloads standardmäßig auf einen generischen Binärtyp festgelegt und Browser bieten ein Download-Prompt an, anstatt die Datei inline darzustellen.

4. Lebenszyklus-Richtlinien und Kosteneinfluss

Object Storage berechnet die Kosten für das gespeicherte Daten, daher können verwaiste Objekte und abgebrochene Mehrteil-Uploads zu einer langsamen Kostenleistung führen. Lebenszyklus-Regeln ermöglichen es Ihnen, Objekte automatisch ablaufen zu lassen und unvollständige Uploads aufzuräumen. Sie konfigurieren sie über die S3 API.

Eine Lebenszyklus-Konfiguration unterstützt folgende Aktionen: Ablauf der aktuellen Versionen, dauerhaftes Löschen nicht aktueller Versionen, Löschen abgelaufener Objekt-Löschmarkierungen und Löschen unvollständiger Mehrteil-Uploads. Sie können bis zu 1000 Regeln in einer Konfiguration einrichten. Jede Regel gilt für ein anderes Objekt-Präfix, und Sie können nicht mehr als eine Regel für das gleiche Präfix einrichten.

4.1 Ablauf von Objekten und Aufräumen von Mehrteil-Uploads

Diese Konfiguration läuft temporäre Uploads nach 7 Tagen ab und bricht unvollständige Mehrteil-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, daher können Sie Lebenszyklus-Regeln nicht verwenden, um Objekte in eine kältere Ebene zu überführen. Die einzigen verfügbaren Aktionen sind Ablauf und Aufräumen. 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 Grade an S3-API-Unterstützung, aber es gibt keine 100%ige AWS-Parität. Überprüfen Sie ein Feature, bevor Sie sich darauf verlassen, anstatt anzunehmen, dass es genau wie AWS S3 funktioniert. Die folgende Tabelle fasst die wichtigsten Feature-Unterstützungen zusammen:

Feature Unterstützt Hinweise
Objekt-Kopie Ja Cross-Region-Kopie wird nicht unterstützt
Vorab unterzeichnete URLs Ja 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 benutzerdefinierte Buckets unterstützt (derzeit nicht verfügbar für vertragsbasierte Buckets)
Bucket-Verschlüsselung Ja Serverseitige Verschlüsselung (AES-256) wird standardmäßig in der Web-Oberfläche verwendet; kundenseitig verwaltete Schlüssel sind über die API verfügbar

Einige Einschränkungen, die bei der Codierung berücksichtigt werden müssen. Die Objekt-Kopie unterstützt keine cross-regionale Kopie, sodass ein "Bucket in eine andere Region verschieben"-Vorgang ein Download-und-Upload-Vorgang und kein serverseitiger Kopiervorgang ist. Object Lock (GOVERNANCE- und COMPLIANCE-Modus) kann nur bei der Bucket-Erstellung aktiviert werden, nie jedoch nachträglich auf ein bestehendes Bucket angewendet werden. Die Bucket-Richtlinie verwendet standardmäßig JSON mit einem Version von 2012-10-17. Die Verschlüsselung während der Übertragung ist TLS 1.2 oder 1.3.

5.1 CORS für Browser-Uploads

Da TaskBoards Browser-Uploads direkt an Object Storage über vorab unterzeichnete URLs durchführt, benötigt das Bucket eine CORS-Konfiguration, die PUT von Ihrem Web-Ursprung zulässt. 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 autoritative S3 API-Referenz befindet sich unter https://api.ionos.com/docs/s3/v2/, und die Schlüssel/Eimer-Verwaltung von API ist unter https://api.ionos.com/docs/s3-management/v1/ dokumentiert. Wenn Sie sich über eine Funktion unsicher sind, überprüfen Sie diese vor dem Schreiben von Code, der von ihr abhängt.

API Referenz-Quick-Card

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

Methode Operation Beschreibung
PUT /{bucket} Erstellen eines Buckets
GET /{bucket}?list-type=2 Auflisten von Objekten (Paginierung)
PUT /{bucket}/{key} Hochladen eines Objekts
GET /{bucket}/{key} Herunterladen eines Objekts
POST /{bucket}/{key}?uploads Initiieren eines Mehrteil-Uploads
PUT /{bucket}?lifecycle Festlegen der Lebenszyklus-Konfiguration

Endpunkt: https://s3.<region>.ionoscloud.com (z.B. s3.eu-central-1.ionoscloud.com) Authentifizierung: AWS-Signatur v4 mit Zugriffsschlüssel + Geheimschlüssel (kein Bearer-Token)

Code-Labor

Ziel: Hochladen und Abrufen einer TaskBoard-Anlage über boto3 mithilfe von presigned URLs und multipart-Upload, wobei die Authentifizierung mit Access Key + Secret Key bestätigt wird.

Voraussetzungen:

  • IONOS Cloud-Konto mit einem Object Storage-Zugriffsschlüssel + Geheimschlüssel, der generiert wurde
  • Python 3.9+ mit einem kompatiblen boto3-Modul (pip install "boto3<=1.35.99"); boto3 1.36.0 und später scheitern bei jedem PutObject-Aufruf gegen IONOS Object Storage mit InvalidTrailer, da IONOS die AWS-Nachprüfungserweiterung, die in dieser Version eingeführt wurde, nicht unterstützt, daher die Version festlegen oder AWS_REQUEST_CHECKSUM_CALCULATION=when_required und AWS_RESPONSE_CHECKSUM_VALIDATION=when_required setzen, wenn eine neuere boto3-Version verwendet werden muss
  • Ein Region-Endpunkt ausgewählt (in diesem Labor wird Frankfurt de / eu-central-1 verwendet)

Schritt 1: Anmeldedaten 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"

Die erwartete Ausgabe:

(no output; variables set)

Schritt 2: Erstellen des Clients und eines Buckets

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)

Die Erwartete Ausgabe:

created taskboard-lab-ct

Schritt 3: Generieren einer vorab unterzeichneten Upload-URL

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

Das erwartete Ergebnis:

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

Schritt 4: Hochladen über die vorab unterzeichnete URL mit curl

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

Die Erwartete Ausgabe:

(HTTP 200, empty body)

Schritt 5: Mehrteil-Upload einer großen Datei

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")

Das erwartete Ergebnis:

uploaded large file

Schritt 6: Download über eine vorab unterzeichnete 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())

Das erwartete Ergebnis:

hello taskboard

Schritt 7: Hinzufügen einer Lebenszyklusregel zum Bereinigen unvollständiger Uploads

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

Die Erwarteten Ausgaben:

lifecycle set

Validierungs-Checkliste:

  • [ ] Bucket erstellt und sichtbar in s3.list_buckets()
  • [ ] Datei über presigned URLs hochgeladen und heruntergeladen
  • [ ] Mehrteil-Upload einer großen Datei erfolgreich
  • [ ] Lebenszyklus-Regel 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 Fehlerquellen

Entwicklerfehler, die bei der Integration von Object Storage vermieden werden sollten:

  1. Versuch, sich mit Ihrem Cloud API-Bearer-Token zu authentifizieren

    • Problem: Jede S3-Anfrage gibt 403 SignatureDoesNotMatch oder InvalidAccessKeyId zurück.
    • Warum es passiert: Object Storage verwendet AWS-Signatur mit einem Zugriffsschlüssel + Geheimschlüsselpaar, nicht das IONOS Cloud-Bearer-Token, das von der REST der API und nicht IAM-Rollen verwendet wird. Sie sind völlig separate Anmeldeinformationen-Systeme.
    • 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; ältere Annahmen von 20/40 Zeichen sollten abgelehnt werden.
  2. Auslassen des endpoint_url und stattdessen AWS ansprechen

    • Problem: Anfragen timeouten, schlagen DNS fehl oder landen auf echten AWS-S3-Seiten.
    • Warum es passiert: boto3 standardmäßig auf AWS-Endpunkte. Ohne endpoint_url spricht die SDK nie mit IONOS.
    • Lösung: Übergeben Sie immer den regionspezifischen Endpunkt, z. B. endpoint_url="https://s3.eu-central-1.ionoscloud.com", und passen Sie region_name an die Region dieses Endpunkts an.
  3. Inkompatibilität des Content-Typs, die vorab unterzeichnete Uploads unterbricht

    • Problem: Der Browser PUT zu einer vorab unterzeichneten URL gibt 403 SignatureDoesNotMatch zurück.
    • Warum es passiert: Der Content-Type wurde bei der Unterzeichnung der URL eingeschlossen, aber der Client sendete einen anderen (oder keinen) Content-Type-Header. Unterzeichnete Header müssen genau übereinstimmen.
    • Lösung: Unterzeichnen Sie mit dem genauen Inhaltstyp und senden Sie den identischen Header vom Client, oder lassen Sie ContentType von Params ganz aus, damit es nicht Teil der Signatur ist.

Zusammenfassung

Sie können jetzt IONOS Cloud Object Storage in Anwendungscodes über dessen S3-kompatibles API integrieren. Sie konfigurieren einen boto3-Client mit dem korrekten regionalen Endpunkt und einer Authentifizierung mit Access Key + Secret Key, verschieben Dateibyteteile von Ihrem API-Pfad mit presigned Upload- und Download-URLs, behandeln große Dateien mit multipart-Upload, streamen Downloads und wenden Lebenszyklusregeln an, um die Speicherkosten unter Kontrolle zu halten. Der TaskBoard-Anhangsfluss ermöglicht es jetzt Browsern, direkt auf Object Storage hochzuladen, während das API nur Metadaten aufzeichnet.

Wichtige Punkte:

  • Object Storage authentifiziert sich mit einem 92-zeichen langen Access Key und einem 64-zeichen langen Secret Key via AWS Signature v4, niemals mit dem Cloud API-Bearer-Token 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
  • Presigned URLs gewähren zeitlich begrenzten, berechtigungsfreien Zugriff, sodass Clients direkt auf Object Storage hochladen und herunterladen können
  • Verwenden Sie multipart-Upload für Dateien über der Einzelanforderungsgrenze (4,65 GB benutzerdefiniert, 5 GB vertragsdefiniert); Objekte können bis zu 5 TB erreichen
  • Object Storage hat eine hohe S3-Kompatibilität, aber keine vollständige Parität: cross-regionale Kopie wird nicht unterstützt, Object Lock ist nur bei der Erstellung möglich, und es existiert nur die STANDARD-Speicherklasse

Wichtige Begriffe:

  • Access Key / Secret Key: Das S3-Anmeldeinformationenpaar (92 und 64 Zeichen) authentifiziert jede Object Storage-Anfrage via AWS-Signatur.
  • Presigned 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: Die Aufteilung eines großen Objekts in Teile, die parallel hochgeladen werden; erforderlich über der Einzelanforderungsgrenze und wird über Lebenszyklusregeln bereinigt.
  • Lebenszyklusregel: Eine Bucket-Konfiguration (bis zu 1000 Regeln), die Objekte abläuft und unvollständige Multipart-Uploads automatisch abbricht.
  • Bucket-Typ: Benutzerdefinierte versus vertragsdefinierte Buckets, die sich in regionaler Verfügbarkeit, pro Benutzer Bucket-Limits und Einzelanforderungshochladegrenzen unterscheiden.

Nächste Schritte

Weiterlernen: Einheit 4.3: Event-Streaming-Integration

Verwandte Themen: