7.0 KiB
homelab-operator
A Kubernetes operator designed for homelab environments that simplifies the management of PostgreSQL databases and Kubernetes secrets. Built with TypeScript and designed to run efficiently in resource-constrained environments.
Features
- PostgreSQL Database Management: Automatically create and manage PostgreSQL databases and roles
- Secret Management: Generate and manage Kubernetes secrets with configurable data
- Owner References: Automatic cleanup when resources are deleted
- Status Tracking: Comprehensive status conditions and error reporting
- Lightweight: Minimal resource footprint suitable for homelab environments
Architecture
The operator manages two main Custom Resource Definitions (CRDs):
PostgresDatabase
Manages PostgreSQL databases and their associated roles:
- Creates a PostgreSQL role with a secure random password
- Creates a database owned by that role
- Generates a Kubernetes secret containing database credentials
- Ensures proper cleanup through owner references
SecretRequest
Generates Kubernetes secrets with configurable data:
- Supports custom secret names
- Configurable data fields with various encodings
- Automatic secret lifecycle management
Installation
Prerequisites
- Kubernetes cluster (1.20+)
- PostgreSQL instance accessible from the cluster
- Helm 3.x (for chart-based installation)
Using Helm Chart
- Clone the repository:
git clone <repository-url>
cd homelab-operator
- Install using Helm:
helm install homelab-operator ./chart \
--set-string env.POSTGRES_HOST=<your-postgres-host> \
--set-string env.POSTGRES_USER=<admin-user> \
--set-string env.POSTGRES_PASSWORD=<admin-password>
Using kubectl
- Build and push the Docker image:
docker build -t your-registry/homelab-operator:latest .
docker push your-registry/homelab-operator:latest
- Apply the Kubernetes manifests:
kubectl apply -f chart/templates/
Configuration
The operator is configured through environment variables:
| Variable | Description | Required | Default |
|---|---|---|---|
POSTGRES_HOST |
PostgreSQL server hostname | Yes | - |
POSTGRES_USER |
PostgreSQL admin username | Yes | - |
POSTGRES_PASSWORD |
PostgreSQL admin password | Yes | - |
POSTGRES_PORT |
PostgreSQL server port | No | 5432 |
LOG_LEVEL |
Logging level (debug, info, warn, error) | No | info |
Usage
PostgreSQL Database
Create a PostgreSQL database with an associated role:
apiVersion: homelab.mortenolsen.pro/v1
kind: PostgresDatabase
metadata:
name: my-app-db
namespace: my-namespace
spec: {}
This will create:
- A PostgreSQL role named
my-app-db - A PostgreSQL database named
my-namespace_my-app-dbowned by the role - A Kubernetes secret
postgres-database-my-app-dbcontaining:name: Base64-encoded database nameuser: Base64-encoded usernamepassword: Base64-encoded password
Secret Request
Generate a Kubernetes secret with custom data:
apiVersion: homelab.mortenolsen.pro/v1
kind: SecretRequest
metadata:
name: my-secret
namespace: my-namespace
spec:
secretName: app-config
data:
- key: api-key
value: "my-api-key"
encoding: base64
- key: database-url
value: "postgresql://user:pass@host:5432/db"
- key: random-token
length: 32
chars: "abcdefghijklmnopqrstuvwxyz0123456789"
Accessing Created Resources
To retrieve database credentials:
# Get the secret
kubectl get secret postgres-database-my-app-db -o jsonpath='{.data.user}' | base64 -d
kubectl get secret postgres-database-my-app-db -o jsonpath='{.data.password}' | base64 -d
kubectl get secret postgres-database-my-app-db -o jsonpath='{.data.name}' | base64 -d
Development
Prerequisites
- Bun runtime
- pnpm package manager
- Docker (for building images)
- Access to a Kubernetes cluster for testing
Setup
- Clone the repository:
git clone <repository-url>
cd homelab-operator
- Install dependencies:
pnpm install
- Set up development environment:
cp .env.example .env
# Edit .env with your PostgreSQL connection details
Running Locally
For development, you can run the operator locally against a remote cluster:
# Ensure kubectl is configured for your development cluster
export KUBECONFIG=~/.kube/config
# Set PostgreSQL connection environment variables
export POSTGRES_HOST=localhost
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=yourpassword
# Run the operator
bun run src/index.ts
Development with Docker Compose
A development environment with PostgreSQL is provided:
docker-compose -f docker-compose.dev.yaml up -d
Building
Build the Docker image:
docker build -t homelab-operator:latest .
Testing
# Run linting
pnpm run test:lint
# Apply test resources
kubectl apply -f test.yaml
Contributing
- Fork the repository
- Create a feature branch:
git checkout -b feature/new-feature - Make your changes and add tests
- Run linting:
pnpm run test:lint - Commit your changes:
git commit -am 'Add new feature' - Push to the branch:
git push origin feature/new-feature - Submit a pull request
Project Structure
├── chart/ # Helm chart for deployment
├── src/
│ ├── crds/ # Custom Resource Definitions
│ │ ├── postgres/ # PostgreSQL database management
│ │ └── secrets/ # Secret generation
│ ├── custom-resource/ # Base CRD framework
│ ├── database/ # Database migrations
│ ├── services/ # Core services
│ │ ├── config/ # Configuration management
│ │ ├── k8s.ts # Kubernetes API client
│ │ ├── log/ # Logging service
│ │ ├── postgres/ # PostgreSQL service
│ │ └── secrets/ # Secret management
│ └── utils/ # Utilities and constants
├── Dockerfile # Container build configuration
└── docker-compose.dev.yaml # Development environment
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For support and questions:
- Create an issue in the GitHub repository
- Check existing issues for similar problems
- Review the logs using
kubectl logs -l app=homelab-operator
Status Monitoring
Monitor the operator status:
# Check operator logs
kubectl logs -l app=homelab-operator -f
# Check CRD status
kubectl get postgresdatabases
kubectl get secretrequests
# Describe resources for detailed status
kubectl describe postgresdatabase my-app-db
kubectl describe secretrequest my-secret