4.5 KiB
4.5 KiB
Use Case: RustFS (S3-Compatible Store) on Local K3D
Deploy a RustFS object store on a local Kubernetes cluster (K3D) using Harmony. RustFS is a Rust-based S3-compatible storage server, a modern alternative to MinIO for local development.
What you'll have at the end
A fully operational S3-compatible object store with:
- 1 standalone instance with 1 GiB of storage
- S3 API endpoint on port 9000
- Web console on port 9001
- Ingress-based access at
http://rustfs.local - Default credentials:
rustfsadmin/rustfsadmin
Prerequisites
- Rust 2024 edition
- Docker running locally
- ~5 minutes
The Score
The entire deployment is expressed in ~20 lines of Rust:
use harmony::{
inventory::Inventory,
modules::rustfs::{K8sRustFsScore, RustFsConfig},
topology::K8sAnywhereTopology,
};
#[tokio::main]
async fn main() {
let rustfs = K8sRustFsScore {
config: RustFsConfig {
release_name: "harmony-rustfs".to_string(),
namespace: "harmony-rustfs".to_string(),
..Default::default()
},
};
harmony_cli::run(
Inventory::autoload(),
K8sAnywhereTopology::from_env(),
vec![Box::new(rustfs)],
None,
)
.await
.unwrap();
}
What Harmony does
When you run this, Harmony:
- Connects to K8sAnywhereTopology — auto-provisions a K3D cluster if none exists
- Creates a namespace —
harmony-rustfs(or your custom namespace) - Creates credentials secret — stores the access/secret keys securely
- Deploys via Helm — installs the RustFS chart in standalone mode
- Configures Ingress — sets up routing at
rustfs.local
Running it
cargo run -p example-rustfs
Verifying the deployment
# Check pods
kubectl get pods -n harmony-rustfs
# Check ingress
kubectl get ingress -n harmony-rustfs
# Access the S3 API
# Add rustfs.local to your /etc/hosts
echo "127.0.0.1 rustfs.local" | sudo tee -a /etc/hosts
# Use the AWS CLI or any S3 client
AWS_ACCESS_KEY_ID=rustfsadmin \
AWS_SECRET_ACCESS_KEY=rustfsadmin \
aws s3 ls --endpoint-url http://rustfs.local:9000
# Or via the web console
open http://rustfs.local:9001
Customizing the deployment
The RustFsConfig struct supports:
| Field | Default | Description |
|---|---|---|
release_name |
rustfs |
Helm release name |
namespace |
harmony-rustfs |
Kubernetes namespace |
storage_size |
1Gi |
Data storage size |
mode |
Standalone |
Deployment mode (standalone only for now) |
access_key |
None |
S3 access key (default: rustfsadmin) |
secret_key |
None |
S3 secret key (default: rustfsadmin) |
ingress_class |
None |
Ingress class to use (default: nginx) |
Example with custom credentials:
let rustfs = K8sRustFsScore {
config: RustFsConfig {
release_name: "my-rustfs".to_string(),
namespace: "storage".to_string(),
access_key: Some("myaccess".to_string()),
secret_key: Some("mysecret".to_string()),
ingress_class: Some("traefik".to_string()),
..Default::default()
},
};
Architecture
The RustFS module follows the same pattern as PostgreSQL:
┌─────────────────────────────────────────────────────────────┐
│ K8sRustFsScore (user-facing) │
│ └── K8sRustFsInterpret │
│ ├── ensure_namespace() │
│ ├── ensure_secret() → K8sResourceScore │
│ └── HelmChartScore → HelmChartInterpret │
│ └── Installs rustfs/rustfs chart │
└─────────────────────────────────────────────────────────────┘
Future: Unified S3 Capability
This is the first step toward a unified S3 capability that will work with:
- RustFS — local development (this example)
- Ceph RGW — production S3 via Rook/Ceph
- AWS S3 — cloud-native S3
The pattern will be:
// Future: unified S3 interface
trait S3Store: Send + Sync {
async fn deploy_bucket(&self, config: &BucketConfig) -> Result<(), String>;
async fn get_endpoint(&self) -> Result<S3Endpoint, String>;
}
See the Scores Catalog for related components.