Skip to main content

Use S3-compatible storage from workloads

Inspect 1.36

Some data does not belong in a block volume. User uploads, build artifacts, generated reports, and data exports grow without a clear ceiling, and they rarely need the low latency of an attached disk. Point the application at an S3-compatible endpoint instead. The app writes objects to a bucket, the block volume stays small and fast, and the large blobs live in object storage that any node can reach. This is also the recommended way for pods across different nodes to share data, ahead of a shared filesystem: any node reaches the same bucket, with no ReadWriteMany volume to run.

An app needs four things to talk to S3: the endpoint, a region, the forcePathStyle setting, and credentials. Run for the endpoint, or use any S3-compatible bucket.

Endpoint, region, and path style#

The endpoint is the address of the S3 gateway. The in-cluster SeaweedFS endpoint uses path-style addressing, where the bucket name sits in the URL path rather than in the hostname, so set forcePathStyle (some SDKs call it s3ForcePathStyle) to true. The region is often required by the SDK even for a self-hosted store; a placeholder like us-east-1 is fine when the store does not use regions.

Mount credentials from a Secret#

Keep the access key ID and secret in a Kubernetes Secret and pass them into the pod as environment variables. Never bake them into the image or the Deployment manifest:

s3-workload.yamlyaml
		apiVersion: apps/v1
kind: Deployment
metadata:
  name: uploader
spec:
  replicas: 1
  selector:
    matchLabels:
      app: uploader
  template:
    metadata:
      labels:
        app: uploader
    spec:
      containers:
        - name: uploader
          image: your-app:latest
          env:
            - name: S3_ENDPOINT
              value: http://seaweedfs-s3.seaweedfs.svc.cluster.local:8333
            - name: S3_REGION
              value: us-east-1
            - name: S3_FORCE_PATH_STYLE
              value: "true"
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: s3-credentials
                  key: AWS_ACCESS_KEY_ID
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: s3-credentials
                  key: AWS_SECRET_ACCESS_KEY
	

The app then reads these variables and builds an S3 client from them.

Three ways to reach the objects#

How the app talks to the bucket depends on what it does. Expand the one that matches your workload:

When object storage replaces a PVC#

Reach for object storage over a PVC when the data is large, append-mostly, and read by many. A photo service storing user uploads, a CI system keeping build artifacts, a reporting job writing nightly exports: all of these fit object storage better than a growing block volume. Keep the PVC for data the application needs at low latency and treats as a live working set, like a database's files.

Tip

Moving large blobs to object storage keeps your block volumes small. Small volumes attach faster, back up faster, and cost less. Store the metadata (which object, who owns it, when it was written) in your database, and store the blob itself in the bucket.

Portability#

The S3 API is the same wherever the store runs. Code written against your in-cluster SeaweedFS talks to any other S3-compatible store by changing the endpoint and credentials. That keeps you from being locked to one provider: you can move the store, or move to a hosted bucket, without rewriting the application.

Next, stand up the store these workloads talk to in , or push backups to a bucket outside the cluster with .