βββ βββ ββββββ ββββββββ βββ βββββββ βββββββ ββββββ βββ
βββ ββββββββββββββββββββ βββ ββββββββββββββββββββββββββββ
βββββββ ββββββββββββββββ βββ βββ ββββββ βββββββββββ
βββββββ ββββββββββββββββ βββ βββ ββββββ βββββββββββ
βββ βββββββββββββββββββ ββββββββββββββββββββββββββββ βββββββββββ
βββ βββ ββββββ ββββββββ ββββββββ βββββββ ββββββββββ βββββββββββ
Local Kubernetes Cluster Manager (kind + talos + docker)
β οΈ IMPORTANT: FOR DEVELOPMENT AND TESTING ONLYThese clusters are designed for local development, testing, and learning purposes. DO NOT use in production environments. They lack the security hardening, high availability, and operational features required for production workloads.
New to Kubernetes? Start here: docs/kubernetes-101.md
Need more info about ArgoCD (perhaps the most central part except kubernetes?) & App-of-Apps pattern: docs/argocd-app-of-apps.md
Just need some information about the apps, see here: docs/kubernetes-apps-overview.md
Create and experiment with local Kubernetes clusters using kind or Talos + Docker, then bootstrap common platform components (ArgoCD, ingress, databases, security, storage, cost / monitoring, etc.) either directly with Helm or via ArgoCD Applications.
Currently supports macOS & Linux (also works under WSL2). Cygwin/MSYS shells may work but are not officially tested.
Choose your Kubernetes provider:
- kind (default) - Kubernetes in Docker, fast and lightweight
- talos - Talos Linux in Docker, immutable infrastructure
π Read the full Multi-Provider Guide
$ ./kl.sh
βββ βββ ββββββ ββββββββ βββ βββββββ βββββββ ββββββ βββ
βββ ββββββββββββββββββββ βββ ββββββββββββββββββββββββββββ
βββββββ ββββββββββββββββ βββ βββ ββββββ βββββββββββ
βββββββ ββββββββββββββββ βββ βββ ββββββ βββββββββββ
βββ βββββββββββββββββββ ββββββββββββββββββββββββββββ βββββββββββ
βββ βββ ββββββ ββββββββ ββββββββ βββββββ ββββββββββ βββββββββββ
Local Kubernetes Cluster Manager (kind + talos + docker)
Cluster Management:
list alias: ls Show all clusters (kind & talos)
create [cluster-name] alias: c Create a local cluster (kind or talos)
details <cluster-name> alias: dt Show details for a cluster
k8sdetails <cluster-name> alias: k8s Show detailed Kubernetes resources info
kubeconfig <cluster-name> alias: kc Get kubeconfig for a cluster by name
delete <cluster-name> alias: d Delete a cluster by name
help alias: h Print this Help
Provider Options:
--provider <kind|talos> Specify cluster provider (skips interactive prompt)
Examples:
./kl.sh create mycluster Create cluster (interactive provider selection)
./kl.sh create mycluster --provider talos Create talos cluster (skip provider prompt)
./kl.sh details mycluster Show details for cluster 'mycluster'
./kl.sh k8sdetails mycluster Show K8s resources for cluster 'mycluster'
./kl.sh delete mycluster Delete cluster 'mycluster'
Helm installations:
helm list List available Helm components
install helm valkey,nats Install one or more Helm components
install helm valkey --dry-run Dry run (show what would be installed)
ArgoCD application installations:
apps list List available ArgoCD app components
install apps nyancat,prometheus Install one or more ArgoCD apps
install apps nats,valkey --dry-run Dry run for ArgoCD apps
Notes:
- Parameters in [brackets] are optional
- Parameters in <brackets> are required
- Use comma-separated lists (no spaces): valkey,nats
- Components are installed in the order specified
- Use --dry-run to preview changes before applying
dependencies: docker, kind, kubectl, jq, base64 and helm
Current date and time in Linux Mon Oct 13 23:29:08 CEST 2025- Multiple script names: Use
./kl.sh(short),./k8s-local.sh, or./create-cluster.sh(legacy) - Dynamic shell completion: Bash, Zsh, Fish (commands + components discovered at runtime)
- Multi-Provider Support: Choose between kind and Talos providers (interactive or via
--providerflag) - Interactive cluster creation (name, control planes, workers, Kubernetes version, provider selection)
- Supported Kubernetes versions:
- kind: v1.25.x β v1.35.x (see
scripts/variables.shfor full list) - talos: Dynamically determined based on installed
talosctlversion (see support matrix)
- kind: v1.25.x β v1.35.x (see
- Organized cluster storage: Each cluster gets its own directory under
clusters/<cluster-name>/ - Automatic port mapping adjustment when multiple clusters run simultaneously (avoids 80/443 conflicts)
- Optional automatic ArgoCD + Nginx Ingress install during cluster creation
- Post-create helper to install a sample Nyancat app (demo ingress + ArgoCD)
- Rich subcommands to list, inspect, delete clusters & fetch kubeconfig
- Registry-based installers: List and install Helm/ArgoCD components with simple commands
- 22 Helm installers: ArgoCD, Crossplane, Rook Ceph, Falco, Trivy, OpenBao, MetalLB, MinIO, NFS, Local Path Provisioner, MongoDB Operator, CNPG, PgAdmin, Valkey, NATS, Kite, Keycloak, Metrics Server, Prometheus, Nginx Ingress
- 27 ArgoCD Application installers (GitOps style): monitoring (Prometheus), metrics (Metrics Server), databases, security, storage, cost monitoring, identity management, etc.
- Dry-run mode: Preview what will be installed with
--dry-run - Generates per-cluster info + kubeconfig files under
clusters/<cluster-name>/ - Consistent colored output & spinners, with readiness waits for core components
- Uses
localtest.mewildcard DNS (no /etc/hosts changes needed)
- Fast cluster creation (~30 seconds)
- Multiple Kubernetes versions supported (v1.25-v1.35)
- Port mapping for ingress access
- Multi-cluster support on same host
- Immutable Infrastructure: Talos Linux runs Kubernetes without a traditional OS
- API-Driven: All configuration via declarative YAML
- Secure by Default: Minimal attack surface, no SSH access
- Production-Like: Closer to real production Talos deployments
- Docker-Based: Runs Talos nodes as Docker containers for local development
Network Architecture:
- Single control plane: Uses hostNetwork mode with direct port exposure
- Multi control plane: Uses MetalLB + HAProxy proxy container for load balancing
- HAProxy container forwards traffic from host ports to MetalLB LoadBalancer IP
- Automatic port assignment to avoid conflicts with other clusters
Talos-Specific Commands:
# Get Talos node IPs
docker ps --filter "name=mycluster-" --format "{{.Names}}: {{.Ports}}"
# View ingress proxy container (multi-control-plane only)
docker logs mycluster-ingress-proxy
# Access Talos API directly
talosctl --talosconfig clusters/mycluster/talos/talosconfig \
--nodes <node-ip> get services
# View Talos logs
talosctl --talosconfig clusters/mycluster/talos/talosconfig \
--nodes <node-ip> logsKey Differences:
| Feature | kind | talos |
|---|---|---|
| Boot time | ~30s | ~60s |
| OS | Generic container | Talos Linux |
| Config format | kind YAML | Talos machine config |
| SSH access | Yes (to nodes) | No (API only) |
| K8s versions | v1.25-v1.34 | v1.30-v1.34 |
| Ingress (single CP) | Port mapping | hostNetwork mode |
| Ingress (multi CP) | Port mapping | MetalLB + HAProxy |
| Best for | Quick testing | Production-like testing |
kl.sh # Short entry point (recommended)
k8s-local.sh # Full name entry point
create-cluster.sh # Legacy entry point (backward compatible)
scripts/
variables.sh # Global defaults (versions, colors, flags)
core/
config.sh # Help + command routing + logo
cluster.sh # Cluster operations (provider-agnostic)
cluster-common.sh # Provider-agnostic K8s operations
utils.sh # Prereq & utility helpers
providers/
provider-interface.sh # Provider abstraction layer
kind-provider.sh # Kind provider implementation
talos-provider.sh # Talos provider implementation
installers/
registry.sh # Component registry (Helm + ArgoCD apps)
helm.sh # Helm installer functions
apps.sh # ArgoCD Application installer functions
completions/ # Shell completion scripts (bash, zsh, fish)
install-completion.sh # Automated completion installer
configs/apps/manifests/ # ArgoCD Application YAMLs & supporting manifests
clusters/ # Generated: kubeconfig & clusterinfo-* per cluster
docs/ # Additional documentation & diagram(s)
The script checks and will exit if any of these are missing. Install them first:
| Tool | Purpose | Install / Docs |
|---|---|---|
| Docker | Container runtime | https://docs.docker.com/get-docker/ |
| kubectl | Kubernetes CLI | https://kubernetes.io/docs/tasks/tools/ |
| Helm | Package manager for Kubernetes | https://helm.sh/docs/intro/install/ |
| jq | JSON processing in shell | https://jqlang.github.io/jq/download/ |
| base64 | Secret decoding (usually preinstalled via coreutils) | macOS/Linux: normally built-in (test with base64 --version) |
| Provider | Tool | Purpose | Install / Docs |
|---|---|---|---|
| kind | kind | Run Kubernetes in Docker | https://kind.sigs.k8s.io/docs/user/quick-start/ |
| talos | talosctl | Talos Linux management CLI | https://www.talos.dev/latest/introduction/getting-started/ |
Optional (used later): mongosh, pgcli, bao CLI, etc.
Homebrew (macOS/Linux) quick installs:
# Core tools
brew install kubectl helm jq
# Provider tools (install what you need)
brew install kind # for kind provider
brew install siderolabs/tap/talosctl # for talos providerDocker Desktop (macOS) via Homebrew Cask:
brew install --cask dockerAfter installing Docker Desktop, start it once so the daemon is running.
Optional: Install shell completion for better experience:
./completions/install-completion.sh
source ~/.zshrc # or ~/.bashrc for bashNow you'll have tab completion for all commands!
Show help (also printed when no args supplied):
./kl.sh help
# or use the full name
./k8s-local.sh help
# or legacy name
./create-cluster.sh helpCreate a cluster (interactive prompts follow):
# Interactive mode - choose provider during creation
./kl.sh create mycluster
# or shorthand
./kl.sh c mycluster
# You'll be prompted:
# Available providers:
# 1) kind - Kubernetes in Docker (fast, default)
# 2) talos - Talos Linux (immutable, production-like)
# Select provider (1 for kind, 2 for talos) [default: 1]:
# Or specify provider via flag (skip provider prompt)
./kl.sh create mycluster --provider talos
./kl.sh create mycluster --provider kindDuring the prompts you can choose:
- Provider (kind or talos)
- Kubernetes version (kind: v1.25-v1.35; talos: based on installed
talosctlversion) - CNI (Container Network Interface): default, cilium, or calico
- Multus CNI (optional add-on for multiple network interfaces per pod)
- Number of control planes & workers
- Whether to install ArgoCD (Helm) immediately
- (Nginx ingress is auto-installed for all providers)
Choose your networking layer during cluster creation:
| CNI | Description | Best For | Documentation |
|---|---|---|---|
| default | Provider's default CNI | Quick testing, simple setups | - |
| cilium | eBPF-based, high-performance networking | Observability, security, performance | docs/cilium.md |
| calico | Policy-driven networking | Network policies, multi-tenancy | docs/calico.md |
Multus CNI Add-on (available after selecting Cilium or Calico):
- Enables multiple network interfaces per pod
- thin plugin (recommended): Lightweight, delegates to primary CNI
- thick plugin: Standalone with built-in IPAM
- π Read Multus CNI Guide
Example cluster creation with CNI:
./kl.sh create mycluster --provider=talos
# Prompts will include:
# Use custom CNI? (default/cilium/calico) (default: default): cilium
# Install Multus CNI? (yes/no) (default: no): yes
# Multus plugin type? (thin/thick) (default: thin): thinπ See detailed cluster creation flow diagram
When finished you get:
clusters/clusterinfo-<name>.txtβ summarized settings, generated passwords, helpful commandsclusters/kubeconfig-<name>.configβ per-cluster kubeconfig file
Export kubeconfig for kubectl convenience:
export KUBECONFIG="$(pwd)/clusters/kubeconfig-mycluster.config"
kubectl get nodesOpen ArgoCD (if installed):
http://argocd.localtest.me # First / only cluster
http://argocd.localtest.me:<port> # If multiple clusters (see clusterinfo file)
Username: admin Password: Listed in clusterinfo file (extracted from the bootstrap secret)
Install Nyancat sample app after cluster creation (if you skipped initially):
./kl.sh install apps nyancatDelete the cluster:
./kl.sh delete mycluster
# or shorthand
./kl.sh d myclusterList clusters:
./kl.sh lsFetch (regenerate) kubeconfig file later:
./kl.sh kc myclusterSee full cluster details (cluster info + kind config used):
./kl.sh info mycluster # alias: i| Action / Aliases | Description |
|---|---|
| create (c) | Interactive creation workflow |
| list (ls) | List kind clusters |
| details (dt) | Live k8s cluster info (nodes, pods, services, ingresses) |
| info (i) | Show saved cluster configuration & kind config summary |
| kubeconfig (kc) | Write kubeconfig file for cluster |
| config | Show raw kind config used (if persisted) |
| start | Start a stopped cluster (noop if not supported) |
| stop | Stop a running cluster (noop if not supported) |
| delete (d) | Delete cluster (confirmation) |
| help (h) | Show help |
List available components:
./kl.sh helm list # List all Helm components
./kl.sh apps list # List all ArgoCD applicationsInstall components (single or multiple):
# Install single Helm component
./kl.sh install helm valkey
# Install multiple Helm components (comma-separated)
./kl.sh install helm valkey,nats,metallb
# Install ArgoCD application
./kl.sh install apps prometheus
# Install multiple apps
./kl.sh install apps nyancat,prometheus,mongodb
# Dry-run mode (preview what will be installed)
./kl.sh install helm valkey --dry-run
./kl.sh install apps prometheus,mongodb --dry-runAvailable Helm components (21):
argocd- ArgoCD GitOps controllercrossplane- Cloud native control planefalco- Runtime securitykeycloak- Keycloak identity and access managementkite- Kite Kubernetes dashboardlocal-path-provisioner- Local Path Provisioner (Rancher)metallb- Load balancermetrics-server- Metrics Server for resource metricsminio- S3-compatible storagemongodb-instance- MongoDB additional instance (Bitnami)mongodb-operator- MongoDB operator (Bitnami)nats- NATS messagingnfs- NFS provisionernginx- NGINX ingress controlleropenbao- OpenBao secrets manager (dev mode)pgadmin- PostgreSQL admin UIpostgres- CloudNativePG operator + clusterprometheus- Kube Prometheus Stack (Prometheus/Grafana/Alertmanager)rook-ceph-cluster- Rook Ceph clusterrook-ceph-operator- Rook Ceph operatortrivy- Security scannervalkey- Valkey key-value store
Available ArgoCD apps (26):
certmanager- Cert Manager for certificatescrossplane- Crossplane control planefalco- Falco runtime securitykeycloak- Keycloak identity and access managementkite- Kite Kubernetes dashboardkubeview- Kubeview UIlocal-path-provisioner- Local Path Provisioner (Rancher)metallb- MetalLB load balancermetrics-server- Metrics Server for resource metricsminio- MinIO operatormongodb-instance- MongoDB Instance CRmongodb-operator- MongoDB Operator (Community)nats- NATS messaging servernfs- NFS external provisionernginx- Ingress-Nginx controllernyancat- Sample Nyancat demo applicationopenbao- OpenBao secrets manager (dev mode)opencost- OpenCost cost monitoringpgadmin- PgAdmin4 UIpostgres- CloudNativePG operator + clusterprometheus- Kube Prometheus Stack (Grafana/Prometheus/Alertmanager)rook-ceph-cluster- Rook Ceph clusterrook-ceph-operator- Rook Ceph operatortrivy- Trivy operatorvalkey- Valkey key-value store
Use tab completion to discover available components! Run
./completions/install-completion.shto enable it.
localtest.meresolves every*.localtest.medomain to127.0.0.1, removing the need for editing/etc/hosts.- Single cluster: apps are directly at
http://<app>.localtest.me - Multiple clusters: first retains ports 80/443, subsequent clusters get randomly assigned host ports (recorded in the
clusterinfo-*file). Usehttp://<app>.localtest.me:<cluster_http_port>.
Common hostnames:
| Component | URL (single cluster) |
|---|---|
| ArgoCD | http://argocd.localtest.me |
| Nyancat sample | http://nyancat.localtest.me |
- ArgoCD admin password extracted from the initial secret and logged to the cluster info file.
- Generated cluster info files may contain credentials β treat the
clusters/folder as sensitive if you reuse values.
Port-forward Grafana (kube-prometheus-stack):
kubectl port-forward -n prometheus svc/prometheus-grafana 30000:80
open http://localhost:30000 # macOS helper (or xdg-open on Linux)Access Postgres (CloudNativePG):
kubectl port-forward -n postgres-cluster svc/postgres-cluster-rw 5432:5432
pgcli -h localhost -U postgres -p 5432 # password from cluster info or secretAccess MongoDB instance:
kubectl port-forward -n mongodb svc/mongodb-instance-svc 27017:27017
mongosh "mongodb://appuser:SuperSecret@localhost:27017/appdb?replicaSet=mongodb-instance&directConnection=true"Access OpenBao:
kubectl port-forward -n openbao svc/openbao 8201:8200
open http://localhost:8201Tab completion makes it easy to discover and use commands:
# Install completion (auto-detects your shell)
./completions/install-completion.sh
# Reload your shell
source ~/.zshrc # for zsh
source ~/.bashrc # for bashSupported shells: Bash 3.2+, Zsh 5.0+, Fish 3.0+
What you get:
- Tab completion for all commands
- Component name completion with descriptions (zsh/fish)
- Flag completion (--dry-run)
- Works with all script names:
./kl.sh,./k8s-local.sh,./create-cluster.sh - Dynamic extraction of commands (no manual sync needed)
- Live parsing of available Helm components & ArgoCD apps (
helm list/apps list)
See docs/shell-completion.md for detailed installation and usage.
./create-cluster.sh delete mycluster
kind get clusters # verify removalRemove generated artifacts:
rm clusters/clusterinfo-mycluster.txt clusters/kubeconfig-mycluster.config| Issue | Hint |
|---|---|
| Script says a prerequisite is missing | Install it & re-run (brew / apt etc.) |
| Ports 80/443 already in use | Likely another cluster β new cluster auto-uses random ports; check clusterinfo file |
| ArgoCD UI not reachable | Ensure ingress controller pods are Ready; kubectl get pods -n ingress-nginx |
| Talos multi-CP ingress not working | Check HAProxy proxy container: docker logs <cluster>-ingress-proxy |
| Application stuck syncing | Check ArgoCD argocd app list & pod logs in the target namespace |
| OpenBao unseal problems | Check logs, ensure dev mode is active |
PRs welcome! Suggested improvements:
- Add automated tests / linting
- Expand OS compatibility (Windows PowerShell native)
- Additional example ArgoCD apps
- Observability stack variants (e.g., Loki, Tempo, Jaeger)
This project is licensed under the terms of the LICENSE.
Getting Started:
- New to Kubernetes? Start here: docs/kubernetes-101.md
- Additional walkthrough & background: docs/k8s.md
Multi-Provider:
- Multi-Provider Guide: docs/providers.md
- Implementation details: MULTI_PROVIDER_IMPLEMENTATION.md
Components & Patterns:
- What do the optional apps provide? docs/kubernetes-apps-overview.md
- ArgoCD & App-of-Apps pattern: docs/argocd-app-of-apps.md
Shell Completion:
- Installation & usage guide: docs/shell-completion.md
- Quick install: completions/README.md
Happy clustering! π§ͺ