Skip to content

Run RustFS (S3)

This assumes you can already reach your cluster with kubectl (see the kubectl quickstart).

RustFS is an S3-compatible object store. You’ll deploy a single instance in its own namespace, backed by persistent storage so its buckets survive pod restarts. The cluster’s default StorageClass provisions the volume for you.

Create a dedicated namespace:

Terminal window
kubectl create namespace rustfs

Deploy RustFS, its storage, and a Service into the namespace:

Terminal window
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: rustfs
namespace: rustfs
stringData:
RUSTFS_ACCESS_KEY: rustfsadmin
RUSTFS_SECRET_KEY: change-me
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rustfs
namespace: rustfs
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rustfs
namespace: rustfs
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: rustfs
template:
metadata:
labels:
app: rustfs
spec:
securityContext:
# RustFS runs as uid/gid 10001; fsGroup lets it write the volume.
fsGroup: 10001
containers:
- name: rustfs
image: rustfs/rustfs:latest
envFrom:
- secretRef:
name: rustfs
env:
- name: RUSTFS_VOLUMES
value: /data
- name: RUSTFS_ADDRESS
value: 0.0.0.0:9000
- name: RUSTFS_CONSOLE_ENABLE
value: "true"
- name: RUSTFS_CONSOLE_ADDRESS
value: 0.0.0.0:9001
ports:
- containerPort: 9000
- containerPort: 9001
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: rustfs
---
apiVersion: v1
kind: Service
metadata:
name: rustfs
namespace: rustfs
spec:
selector:
app: rustfs
ports:
- name: s3
port: 9000
targetPort: 9000
- name: console
port: 9001
targetPort: 9001
EOF

This Service is ClusterIP, so the store is only reachable from inside the cluster. On a single-tenant skube cluster that’s the safe default: keep your app and the store in the cluster and connect over the Service.

If you need to reach it from outside the cluster:

  • For occasional access, prefer kubectl port-forward -n rustfs service/rustfs 9000:9000 over a public endpoint. It tunnels through the API server and exposes nothing.
  • The S3 API is plain HTTP, so you can publish it over HTTPS with an Ingress or Gateway. See Expose over HTTPS below.
  • Use a strong secret key, not change-me, and rotate the secret if it leaks.

Confirm the pod rolled out:

Terminal window
kubectl rollout status -n rustfs deploy/rustfs

Port-forward the S3 API:

Terminal window
kubectl port-forward -n rustfs service/rustfs 9000:9000

Point the MinIO Client (mc) at it, then create a bucket and list:

Terminal window
mc alias set rustfs http://localhost:9000 rustfsadmin change-me
mc mb rustfs/my-bucket
mc ls rustfs

The web console is on port 9001:

Terminal window
kubectl port-forward -n rustfs service/rustfs 9001:9001

Then open http://localhost:9001.

Other workloads in the cluster use the endpoint http://rustfs.rustfs.svc.cluster.local:9000 with the access and secret keys from the secret above.

The S3 API is plain HTTP, so you can publish it with the Ingress or Gateway guide for automatic TLS. Set up the DNS record as described there, then apply an Ingress for the S3 port only.

Terminal window
cat <<'EOF' | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rustfs
namespace: rustfs
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: traefik
tls:
- hosts:
- s3.example.com
secretName: rustfs-tls
rules:
- host: s3.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rustfs
port:
number: 9000
EOF

Clients then use https://s3.example.com as the endpoint:

Terminal window
mc alias set rustfs https://s3.example.com rustfsadmin change-me

This serves buckets in path-style form (https://s3.example.com/my-bucket). Virtual-host style (https://my-bucket.s3.example.com) would additionally need a wildcard DNS record and certificate.

Delete the namespace to remove everything at once:

Terminal window
kubectl delete namespace rustfs

This destroys the stored objects along with it.