Flux
Deliver Kubernetes manifests to Flux CD from RustFS through the Bucket source API.
This guide connects Flux CD — the GitOps toolkit for Kubernetes — to RustFS through the source-controller Bucket API. You will seed a RustFS bucket with Kubernetes manifests, register the bucket as a Flux Bucket source with the generic provider, and let a Kustomization apply everything it contains. The workflow was verified with flux v2.9.5 (source-controller) on k3s v1.36.4+k3s1 against rustfs/rustfs-x86-musl:v2.3.1.
You need a Kubernetes cluster with Flux installed (flux install) and the rc client. This deployment is intended for local integration testing, not production.
Architecture
The source-controller lists and downloads objects from the bucket over the S3 API, packs them into an artifact, and the kustomize-controller applies the manifests from that artifact. RustFS acts as the pull-based source of truth for the cluster.
Seed the bucket
Store a Kustomize overlay in the bucket, replacing all connection placeholders:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- rustfs-demo-configmap.yamlapiVersion: v1
kind: ConfigMap
metadata:
name: rustfs-flux-demo
namespace: default
data:
storage: rustfs
source: s3-bucketUpload the files:
rc mb rustfs/flux-src
rc cp --recursive ./clusters rustfs/flux-src/
rc ls rustfs/flux-src/ -rstaging/kustomization.yaml
staging/rustfs-demo-configmap.yamlCreate the credentials secret
Flux reads the credentials from a secret in the same namespace as the source, using lowercase keys:
kubectl -n flux-system create secret generic rustfs-creds \
--from-literal=accesskey=<your-access-key> \
--from-literal=secretkey=<your-secret-key>The field names must be accesskey and secretkey — capitalization such as accessKey fails with an AuthenticationFailed status.
Register the Bucket source
Create the Bucket source with the generic provider:
flux create source bucket rustfs-demo \
--bucket-name=flux-src \
--endpoint=<your-rustfs-endpoint>:9000 \
--insecure \
--secret-ref=rustfs-creds \
--provider=generic \
--interval=30s \
--namespace=flux-system✔ Bucket source reconciliation completedIf reconciliation is still running, check the status with flux get sources bucket:
NAME REVISION SUSPENDED READY MESSAGE
rustfs-demo sha256:481816d1 False True stored artifact: revision 'sha256:481816d1'The generic provider uses path-style requests and plain HTTP with --insecure, so the endpoint is the bare host:port.
Apply the manifests
Create a Kustomization that consumes the artifact:
flux create kustomization rustfs-demo \
--source=Bucket/rustfs-demo \
--path="./staging" \
--prune=true \
--interval=30s \
--namespace=flux-system✔ applied revision sha256:481816d1Confirm the manifest landed on the cluster:
kubectl -n default get configmap rustfs-flux-demo -o jsonpath="{.data}"{"source":"s3-bucket","storage":"rustfs"}Stop or reset
Suspend or delete the Flux resources without touching the bucket:
flux suspend source bucket rustfs-demo --namespace=flux-system
flux delete kustomization rustfs-demo --namespace=flux-systemTo delete the bucket contents:
rc rm rustfs/flux-src/ --recursive --forceTroubleshooting
invalid 'rustfs-creds' secret data: required fields 'accesskey' and 'secretkey'
The secret keys are lowercase. Recreate the secret with accesskey and secretkey as literal key names.
Reconciliation never becomes ready
Confirm the endpoint is reachable from inside the cluster — pods cannot use localhost, so point the source at the host IP or the Docker bridge gateway (commonly 172.17.0.1) that publishes the RustFS port. --insecure is required for plain HTTP.
AuthenticationFailed despite valid credentials
Check that the secret lives in the same namespace as the Bucket source and that the keys have no trailing whitespace or quoting.
Next steps
- Review S3 compatibility notes before adopting additional source types.
- Create dedicated production credentials with Access Key Management.
- Follow the Flux Bucket source documentation to combine bucket sources with Helm releases and image automation.