Some checks failed
Run Check Script / check (pull_request) Failing after 12s
116 lines
3.2 KiB
Markdown
116 lines
3.2 KiB
Markdown
# Use Case: PostgreSQL on Local K3D
|
|
|
|
Deploy a production-grade PostgreSQL cluster on a local Kubernetes cluster (K3D) using Harmony. This is the fastest way to get started with Harmony and requires no external infrastructure.
|
|
|
|
## What you'll have at the end
|
|
|
|
A fully operational PostgreSQL cluster with:
|
|
- 1 primary instance with 1 GiB of storage
|
|
- CloudNativePG operator managing the cluster lifecycle
|
|
- Automatic failover support (foundation for high-availability)
|
|
- Exposed as a Kubernetes Service for easy connection
|
|
|
|
## Prerequisites
|
|
|
|
- Rust 2024 edition
|
|
- Docker running locally
|
|
- ~5 minutes
|
|
|
|
## The Score
|
|
|
|
The entire deployment is expressed in ~20 lines of Rust:
|
|
|
|
```rust
|
|
use harmony::{
|
|
inventory::Inventory,
|
|
modules::postgresql::{PostgreSQLScore, capability::PostgreSQLConfig},
|
|
topology::K8sAnywhereTopology,
|
|
};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let postgres = PostgreSQLScore {
|
|
config: PostgreSQLConfig {
|
|
cluster_name: "harmony-postgres-example".to_string(),
|
|
namespace: "harmony-postgres-example".to_string(),
|
|
..Default::default()
|
|
},
|
|
};
|
|
|
|
harmony_cli::run(
|
|
Inventory::autoload(),
|
|
K8sAnywhereTopology::from_env(),
|
|
vec![Box::new(postgres)],
|
|
None,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
}
|
|
```
|
|
|
|
## What Harmony does
|
|
|
|
When you run this, Harmony:
|
|
|
|
1. **Connects to K8sAnywhereTopology** — this auto-provisions a K3D cluster if none exists
|
|
2. **Installs the CloudNativePG operator** — one-time setup that enables PostgreSQL cluster management in Kubernetes
|
|
3. **Creates a PostgreSQL cluster** — Harmony translates the Score into a `Cluster` CRD and applies it
|
|
4. **Exposes the database** — creates a Kubernetes Service for the PostgreSQL primary
|
|
|
|
## Running it
|
|
|
|
```bash
|
|
cargo run -p example-postgresql
|
|
```
|
|
|
|
## Verifying the deployment
|
|
|
|
```bash
|
|
# Check pods
|
|
kubectl get pods -n harmony-postgres-example
|
|
|
|
# Get the password
|
|
PASSWORD=$(kubectl get secret -n harmony-postgres-example \
|
|
harmony-postgres-example-db-user \
|
|
-o jsonpath='{.data.password}' | base64 -d)
|
|
|
|
# Connect via port-forward
|
|
kubectl port-forward -n harmony-postgres-example svc/harmony-postgres-example-rw 5432:5432
|
|
psql -h localhost -p 5432 -U postgres -W "$PASSWORD"
|
|
```
|
|
|
|
## Customizing the deployment
|
|
|
|
The `PostgreSQLConfig` struct supports:
|
|
|
|
| Field | Default | Description |
|
|
|-------|---------|-------------|
|
|
| `cluster_name` | — | Name of the PostgreSQL cluster |
|
|
| `namespace` | — | Kubernetes namespace to deploy to |
|
|
| `instances` | `1` | Number of instances |
|
|
| `storage_size` | `1Gi` | Persistent storage size per instance |
|
|
|
|
Example with custom settings:
|
|
|
|
```rust
|
|
let postgres = PostgreSQLScore {
|
|
config: PostgreSQLConfig {
|
|
cluster_name: "my-prod-db".to_string(),
|
|
namespace: "database".to_string(),
|
|
instances: 3,
|
|
storage_size: "10Gi".to_string().into(),
|
|
..Default::default()
|
|
},
|
|
};
|
|
```
|
|
|
|
## Extending the pattern
|
|
|
|
This pattern extends to any Kubernetes-native workload:
|
|
|
|
- Add **monitoring** by including a `Monitoring` feature alongside your Score
|
|
- Add **TLS certificates** by including a `CertificateScore`
|
|
- Add **tenant isolation** by wrapping in a `TenantScore`
|
|
|
|
See [Scores Catalog](../catalogs/scores.md) for the full list.
|