A Kubernetes operator that manages common infrastructure dependencies required by Multi-Tenant Operator (MTO) as Custom Resources using Helm charts.
The MTO Dependencies Operator simplifies the deployment and management of essential infrastructure components needed by the Multi-Tenant Operator ecosystem. Instead of manually managing multiple Helm releases, this operator provides a declarative way to deploy and configure dependencies through Kubernetes Custom Resources.
| Component | Custom Resource | Description |
|---|---|---|
| Dex | Dex |
OpenID Connect (OIDC) identity provider with pluggable connectors |
| Prometheus | Prometheus |
Monitoring and alerting system with time series database |
| Kube State Metrics | KubeStateMetrics |
Kubernetes object metrics exporter |
| PostgreSQL | Postgres |
Production-ready PostgreSQL database with high availability |
| OpenCost | OpenCost |
Kubernetes cost monitoring and management platform |
| FinOps Operator | FinOps Operator |
MTO cost monitoring and management platform |
┌─────────────────┐ ┌───────────────────┐ ┌─────────────────┐
│ User/GitOps │ │ MTO Dependencies │ │ Infrastructure│
│ │ │ Operator │ │ Components │
│ │────▶ │────▶ │
│ Custom Resource │ │ (Helm Operator) │ │ Helm Releases │
│ (Dex, etc.) │ │ │ │ (Pods, SVCs) │
└─────────────────┘ └───────────────────┘ └─────────────────┘
The operator watches for Custom Resource changes and automatically:
- Validates the configuration
- Deploys the corresponding Helm chart
- Manages the lifecycle of the infrastructure components
- Handles upgrades and configuration changes
- Kubernetes cluster (v1.14+)
- kubectl configured to access your cluster
- Operator Lifecycle Manager (OLM) installed (optional)
# Install the operator
kubectl apply -f https://raw.githubusercontent.com/stakater-ab/mto-dependencies-operator/refs/heads/main/dist/install.yaml
# Verify installation
kubectl get pods -n mto-dependencies-operator-system# Clone the repository
git clone https://github.com/stakater-ab/mto-dependencies-operator.git
cd mto-dependencies-operator
# Deploy to your cluster
make deployCreate a simple Dex identity provider:
apiVersion: dependencies.tenantoperator.stakater.com/v1alpha1
kind: Dex
metadata:
name: my-dex
namespace: auth-system
spec:
config:
issuer: https://dex.example.com
storage:
type: kubernetes
config:
inCluster: true
staticClients:
- id: my-app
name: 'My Application'
redirectURIs:
- 'https://my-app.example.com/callback'
secret: my-secret-keyApply the resource:
kubectl apply -f dex-example.yamlThe operator will automatically deploy and configure Dex using the embedded Helm chart.
apiVersion: dependencies.tenantoperator.stakater.com/v1alpha1
kind: Dex
metadata:
name: dex-example
spec:
config:
issuer: https://dex.example.com
storage:
type: kubernetes
config:
inCluster: true
connectors:
- type: oidc
id: keycloak
name: Keycloak
config:
issuer: https://keycloak.example.com/realms/mto
clientID: mto-console
redirectURI: https://dex.example.com/callback
staticClients:
- id: my-app
redirectURIs: ['https://my-app.example.com/callback']
name: 'My App'
secret: my-secretapiVersion: dependencies.tenantoperator.stakater.com/v1alpha1
kind: Prometheus
metadata:
name: prometheus-example
spec:
server:
retention: "15d"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
alertmanager:
enabled: true
nodeExporter:
enabled: true
kubeStateMetrics:
enabled: trueapiVersion: dependencies.tenantoperator.stakater.com/v1alpha1
kind: Postgres
metadata:
name: postgres-example
spec:
auth:
postgresPassword: "secure-password"
username: "myuser"
password: "mypass"
database: "mydb"
primary:
persistence:
enabled: true
size: 10Gi
resources:
requests:
cpu: 100m
memory: 128MiapiVersion: dependencies.tenantoperator.stakater.com/v1alpha1
kind: KubeStateMetrics
metadata:
name: kube-state-metrics-example
spec:
replicas: 1
resources:
requests:
cpu: 10m
memory: 32Mi
collectors:
- deployments
- pods
- servicesapiVersion: dependencies.tenantoperator.stakater.com/v1alpha1
kind: OpenCost
metadata:
name: opencost-example
spec:
opencost:
exporter:
defaultClusterId: "my-cluster"
prometheus:
external:
enabled: true
url: "http://prometheus-server.monitoring.svc.cluster.local"Use provided sample to deploy FinOps Operator:
kubectl apply -f config/samples/dependencies_v1alpha1_finopsoperator.yaml- Go 1.21+
- Docker
- kubectl
- kind (for local testing)
- Helm 3.x
# Clone the repository
git clone https://github.com/stakater-ab/mto-dependencies-operator.git
cd mto-dependencies-operator
# Install dependencies
make kind # Install kind locally
make cluster # Create local test cluster
make install # Install CRDs
# Run the operator locally
make run
# In another terminal, test with sample resources
kubectl apply -f examples/- Dowload the desired Helm chart and place it in the
helm-charts/directory. - Create a new API type
# make sure you have create a feature branch prior to running below commands.
# downloads operator sdk and places it in ./bin/operator-sdk if not already present
make operator-sdk
# Create a new API
./bin/operator-sdk create api \
--plugins=helm \
--group=dependencies \
--version=v1alpha1 \
--kind=<name-of-operator-kind> \
--helm-chart=helm-charts/<name-of-helm-chart>
# commit your changes.The operator includes comprehensive integration tests:
# Lint Helm charts
make lint
# Run all integration tests
make test
# Run specific tests
make test-dex
make test-prometheus
make test-postgres
# Run tests in parallel
make test-integration-parallel# Build Docker image
make docker-build IMG=your-registry/mto-dependencies-operator:latest
# Push image
make docker-push IMG=your-registry/mto-dependencies-operator:latest
# Deploy to cluster
make deploy IMG=your-registry/mto-dependencies-operator:latestThe operator can be configured through environment variables:
| Variable | Default | Description |
|---|---|---|
WATCH_NAMESPACE |
"" |
Namespace to watch (empty = all namespaces) |
LEADER_ELECTION_NAMESPACE |
mto-dependencies-operator-system |
Namespace for leader election |
ANSIBLE_VERBOSITY |
0 |
Ansible verbosity level |
Each Custom Resource spec is passed directly to the underlying Helm chart. Refer to individual chart documentation:
- Dex Helm Chart
- Prometheus Helm Chart
- PostgreSQL Helm Chart
- OpenCost Helm Chart
- FinOps Operator Helm Chart
The operator exposes metrics and supports monitoring through:
- Metrics: Prometheus metrics on port 8443
- Health Checks: Liveness and readiness probes
- Logging: Structured logging with configurable verbosity
controller_runtime_reconcile_total: Total reconciliations per Custom Resourcecontroller_runtime_reconcile_errors_total: Failed reconciliationsworkqueue_adds_total: Items added to work queuerest_client_requests_total: Kubernetes API requests
-
Custom Resource not reconciling
# Check operator logs kubectl logs -n mto-dependencies-operator-system deployment/mto-dependencies-operator-controller-manager # Check Custom Resource status kubectl describe dex my-dex-instance
-
Helm chart deployment failing
# List Helm releases helm list -A # Check release status helm status my-dex-instance -n target-namespace
-
Resource conflicts
# Check for existing resources kubectl get all -l app.kubernetes.io/managed-by=Helm
Enable debug logging:
kubectl patch deployment mto-dependencies-operator-controller-manager \
-n mto-dependencies-operator-system \
--type='json' \
-p='[{"op": "replace", "path": "/spec/template/spec/containers/0/env/0/value", "value": "2"}]'We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite:
make test - Submit a pull request
- Follow Go best practices
- Add comprehensive tests
- Update documentation
- Use conventional commit messages
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Slack: Stakater Community
- Built on the Operator SDK
- Uses the Helm Operator approach
- Integrates community-maintained Helm charts for each dependency