Quick Start with Minikube
Get Lynq running on Minikube in under 5 minutes using automated scripts.
Multi-Node Example
As the most common use case for Lynq, this guide uses Multi-Node infrastructure (SaaS application with multiple customers/nodes) as an example. The pattern shown here can be adapted for any database-driven infrastructure automation scenario.
Overview
This guide uses automated scripts to set up a complete local environment:
- Minikube cluster with cert-manager (automatically installed)
- Lynq deployed and running with webhooks enabled
- MySQL test database for node data
- Sample LynqHub and LynqForm
- Live node provisioning from database
Time required
Full setup typically completes in around 5 minutes.
cert-manager Included
cert-manager is automatically installed by the setup script. It's required for webhook validation and defaulting in all environments (including local development).
Prerequisites
Required Tools
| Tool | Version | Install on macOS | Install on Linux |
|---|---|---|---|
| Minikube | v1.28.0+ | brew install minikube | Installation Guide |
| kubectl | v1.28.0+ | brew install kubectl | Installation Guide |
| Docker (driver) | Latest | Docker Desktop | Docker Engine |
System Requirements
- CPU: 1+ core
- Memory: 1+ GB RAM
- Disk: 5+ GB free space
Step-by-Step Setup
Step 1: Setup Minikube Cluster
Create a Minikube cluster with all prerequisites:
cd /path/to/lynq
./scripts/setup-minikube.shWhat this does:
- ✅ Creates Minikube cluster (2 CPUs, 2GB RAM)
- ✅ Installs cert-manager v1.13.2 (required for webhooks)
- ✅ Installs Lynq CRDs
- ✅ Creates namespaces:
lynq-system,lynq-test
cert-manager is Essential
cert-manager provides webhook TLS certificates for validation and defaulting. It's no longer optional, even for local development, to ensure consistency with production environments.
Time: ~2 minutes
Step 2: Deploy Lynq
Build and deploy the operator to Minikube:
./scripts/deploy-to-minikube.shWhat this does:
- ✅ Builds operator Docker image with timestamp tag
- ✅ Loads image into Minikube's internal registry
- ✅ Deploys operator to
lynq-systemnamespace - ✅ Waits for operator to be ready
Time: ~2 minutes
Step 3: Deploy MySQL Test Database
Deploy a MySQL database with sample node data:
./scripts/deploy-mysql.shWhat this does:
- ✅ Deploys MySQL 8.0 to
lynq-testnamespace - ✅ Creates
nodesdatabase andnode_configstable - ✅ Inserts 3 sample node rows
- ✅ Creates read-only user
node_reader - ✅ Creates Kubernetes Secret with credentials
Sample data inserted:
node_id node_url is_active subscription_plan
----------- ----------------------------- --------- -----------------
acme-corp https://acme.example.com 1 enterprise
beta-inc https://beta.example.com 1 startup
gamma-llc https://gamma.example.com 0 trialTime: ~1 minute
Step 4: Deploy LynqHub
Create a LynqHub that connects to the MySQL database:
./scripts/deploy-lynqhub.shWhat this does:
- ✅ Creates LynqHub CR named
test-hub - ✅ Configures MySQL connection to test database
- ✅ Sets up column mappings (uid, hostOrUrl, activate)
- ✅ Starts syncing every 30 seconds
Time: ~30 seconds
Step 5: Deploy LynqForm
Create a LynqForm that provisions resources for each node:
./scripts/deploy-lynqform.shWhat this does:
- ✅ Creates LynqForm CR named
test-template - ✅ Defines resource blueprints (Deployment, Service)
- ✅ Links to
test-hub - ✅ Triggers automatic node provisioning
Time: ~30 seconds
🎉 Success! You're Running Lynq
You now have:
- ✅ Minikube cluster with cert-manager (for webhook TLS)
- ✅ Lynq managing nodes with webhooks enabled
- ✅ MySQL database with 3 node rows
- ✅ 2 Active Nodes (acme-corp, beta-inc) fully provisioned
- ✅ Live sync between database and Kubernetes
- ✅ Admission validation catching errors at apply time
What Was Created?
For each active node (acme-corp, beta-inc):
LynqNode CR: acme-corp-test-template
├── Deployment: acme-corp-app
└── Service: acme-corp-appVerify your setup:
# Check LynqNode CRs
kubectl get lynqnodes
# Check node resources
kubectl get deployments,services -l lynq.sh/node
# View operator logs
kubectl logs -n lynq-system -l control-plane=controller-manager -fReal-World Example
Let's see the complete lifecycle of a node from database to Kubernetes.
Adding a Node
Insert a new row into the database:
INSERT INTO node_configs (node_id, node_url, is_active, subscription_plan)
VALUES ('acme-corp', 'https://acme.example.com', 1, 'enterprise');What happens automatically:
Within 30 seconds (syncInterval), the operator creates:
# 1. LynqNode CR
kubectl get lynqnode acme-corp-test-template
# 2. Namespace (if configured)
kubectl get namespace acme-corp-namespace
# 3. Deployment
kubectl get deployment acme-corp-app
# 4. Service
kubectl get service acme-corp-app
# 5. Ingress (if configured)
kubectl get ingress acme-corp-ingressAll without writing any YAML files. The template defines the blueprint, the database row provides the variables.
Deactivating a Node
Update the database:
UPDATE node_configs SET is_active = 0 WHERE node_id = 'acme-corp';What happens automatically:
Within 30 seconds:
- LynqNode CR is deleted
- All associated resources are cleaned up (based on
DeletionPolicy) - Namespace is removed (if created)
No manual kubectl delete commands needed. The database is your source of truth.
Explore the System
Test Node Lifecycle
1. Add a New Node
Add a row to the database:
# Connect to MySQL
kubectl exec -it deployment/mysql -n lynq-test -- \
mysql -u root -p$(kubectl get secret mysql-root-password -n lynq-test -o jsonpath='{.data.password}' | base64 -d) nodes
# Insert new node
INSERT INTO node_configs (node_id, node_url, is_active, subscription_plan)
VALUES ('delta-co', 'https://delta.example.com', 1, 'enterprise');
exitWait 30 seconds (syncInterval), then verify:
kubectl get lynqnode delta-co-test-template
kubectl get deployment delta-co-app2. Deactivate a Node
# Update database
kubectl exec -it deployment/mysql -n lynq-test -- \
mysql -u root -p$(kubectl get secret mysql-root-password -n lynq-test -o jsonpath='{.data.password}' | base64 -d) -e \
"UPDATE nodes.node_configs SET is_active = 0 WHERE node_id = 'acme-corp';"Wait 30 seconds, then verify resources are cleaned up:
kubectl get lynqnode acme-corp-test-template # Not found
kubectl get deployment acme-corp-app # Not found3. Modify Template
Edit the template to add more resources:
kubectl edit lynqform test-templateChanges automatically apply to all nodes. Monitor reconciliation:
kubectl get lynqnodes --watchView Metrics
# Port-forward metrics endpoint
kubectl port-forward -n lynq-system deployment/lynq-controller-manager 8080:8080
# View metrics
curl http://localhost:8080/metrics | grep lynqnode_Cleanup
Option 1: Clean Resources Only
Keep the cluster, remove operator and nodes:
kubectl delete lynqnodes --all
kubectl delete lynqform test-template
kubectl delete lynqhub test-hub
kubectl delete deployment,service,pvc mysql -n lynq-test
kubectl delete deployment lynq-controller-manager -n lynq-systemOption 2: Full Cleanup
Delete everything including Minikube cluster:
./scripts/cleanup-minikube.shThis script interactively prompts for MySQL, operator, cluster, context, and image cache cleanup. Answer 'y' to all prompts for complete cleanup.
Troubleshooting
Quick Diagnostics
# Check operator status
kubectl get pods -n lynq-system
kubectl logs -n lynq-system -l control-plane=controller-manager
# Check hub sync
kubectl get lynqhub test-hub -o yaml
# Check node status
kubectl get lynqnode <lynqnode-name> -o yaml
# Check database connection
kubectl exec -it deployment/mysql -n lynq-test -- \
mysql -u node_reader -p$(kubectl get secret mysql-credentials -n lynq-test -o jsonpath='{.data.password}' | base64 -d) \
-e "SELECT * FROM nodes.node_configs;"Common issues:
- Operator not starting: Check cert-manager is ready (
kubectl get pods -n cert-manager) - Nodes not created: Verify MySQL is ready and
is_active = 1in database - Resources missing: Check LynqNode CR status and operator logs
Detailed Troubleshooting
For comprehensive troubleshooting, see Troubleshooting Guide.
Customizing Scripts
All scripts support environment variables for customization:
# Example: Custom cluster configuration
MINIKUBE_CPUS=8 MINIKUBE_MEMORY=16384 ./scripts/setup-minikube.sh
# Example: Custom image tag
IMG=lynq:my-tag ./scripts/deploy-to-minikube.sh
# Example: Custom namespace
MYSQL_NAMESPACE=my-test-ns ./scripts/deploy-mysql.shRun any script with --help for full options.
What's Next?
Now that you have Lynq running, explore these topics:
Concepts & Configuration
- Templates Guide - Template syntax and 200+ functions
- Policies Guide - CreationPolicy, DeletionPolicy, ConflictPolicy, PatchStrategy
- DataSource Guide - MySQL configuration, VIEWs, and extraValueMappings
- Dependencies - Resource ordering with dependency graphs
Operations
- Installation Guide - Deploy to production clusters
- Security Guide - RBAC and secrets management
- Performance Guide - Scaling and optimization
- Monitoring Guide - Prometheus metrics, alerts, and Grafana dashboards
Advanced Topics
- Local Development - Development workflow and debugging
- Integration with External DNS - Automatic DNS per node
- Integration with Terraform Operator - Cloud resource provisioning
Summary
You've successfully:
- ✅ Set up Minikube with Lynq in ~5 minutes
- ✅ Deployed MySQL with sample node data
- ✅ Created LynqHub and LynqForm
- ✅ Provisioned nodes automatically from database
- ✅ Tested node lifecycle (create, update, delete)
Next: Experiment with templates, policies, and template functions to build your database-driven platform!
Need Help?
- 📖 Documentation: See documentation site for detailed guides
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
