Tutorial
Run a local cluster
Bring up a three-instance middleware cluster with Kiwi Vault, Redis, MongoDB and sample workers on one machine.
Prerequisites
- Docker Desktop running
- .NET SDK 8 and 9
- Kiwi Launch and the Kiwi Vault repository built
- Optional: Node.js 22.18 or newer, Python 3.11 or newer, JDK 17 and Maven for the extra-language workers
Note
Kiwi Distro is currently in private preview. Interfaces and behaviour described here can change before general availability. Contact Kiwify Labs for access.
The local cluster is a development and learning environment. It is launched with Kiwi Launch, which runs a dependency graph of tasks.
client / worker --HTTPS 8443--> nginx (L4 TLS pass-through) --> 3 x middleware (7001-7003 HTTP, 7401-7403 HTTPS)
--HTTP 8080 (/ca)--> | Redis pub/sub between instances
Kiwi Vault (CA, config store) Redis MongoDB 4 sample workers
What each part does#
- Kiwi Vault is the configuration store (it holds the shared module settings for Redis and MongoDB, so each instance carries only a
kiwiconfig://connection string) and the PKI that issues each instance's TLS certificate from one root CA. - Redis provides the transaction cache and the peer message bus.
- MongoDB stores data, secrets and feedback.
- nginx does layer-4 TLS pass-through on 8443 so the Vault certificate reaches the client end to end, and serves the CA endpoint over HTTP on 8080.
- Sample workers for .NET, Node.js, Python and Java register for a sample service in lazy mode (each is skipped, with a warning, if its toolchain is missing).
Run it#
dotnet <path-to>/Kiwify.Kiwi.Launch.Cli.dll apply --script .\deploy\cluster\kiwi-cluster.launch.json
dotnet <path-to>/Kiwify.Kiwi.Launch.Cli.dll status -e <execution-id>
dotnet <path-to>/Kiwify.Kiwi.Launch.Cli.dll kill -e <execution-id> --force
.\deploy\cluster\teardown-cluster.ps1
apply stages (builds and publishes every component and Kiwi Vault), starts MongoDB and Redis containers on named volumes (so data survives relaunches), starts Vault and bootstraps it, starts three middleware instances 8 seconds apart (so they do not hit Vault at once), starts nginx, bootstraps a super-admin client, service and worker profile, and launches the sample workers. Output is staged under %USERPROFILE%\kiwi-cluster\, which records every URL, id and key.
Try it#
With the staged bootstrap.json:
$bs = Get-Content "$env:USERPROFILE\kiwi-cluster\bootstrap.json" -Raw | ConvertFrom-Json
$h = @{ Authorization = "Bearer $($bs.accessToken)" }
Invoke-RestMethod -Method Post "$($bs.lb)/client/api/request" -Headers $h -ContentType application/json `
-Body '{"method":"clustersvc/progress","target":"any","params":{"Job":"demo"}}'
Invoke-RestMethod "$($bs.lb)/client/feedback?service_id=$($bs.serviceId)" -Headers $h
Or use the CLI, which is a Kiwi shell product:
kiwi distro signin --credentials-file "$env:USERPROFILE\kiwi-cluster\cli-creds.json"
kiwi distro list-services
kiwi distro list-workers --output json
kiwi distro request-method --method clustersvc/hello --target any --params-file params.json --output raw
The CLI token is cached under %LOCALAPPDATA%\kiwi\distro\.
Configuration#
Common parameters in the launch script: MW_INSTANCES (3), MW_BASE_PORT and MW_BASE_TLS (7000 and 7400), MONGO_PORT and REDIS_PORT (27017 and 6379), VAULT_HTTP and VAULT_HTTPS (5080 and 5443), LB_HTTP and LB_HTTPS (8080 and 8443) and CONFIGURATION (Debug, or Release for a faster middleware). If you change the instance count, update the instance parameters in the script too.
Notes and limits#
- The database is reused across launches.
teardown-cluster.ps1 -RemoveVolumewipes volumes, caches and bootstrap state for a clean slate. - After removing the volumes, if
signinfails on TLS, delete the cached CA files in%LOCALAPPDATA%\kiwi\ca\and~\.kiwi\ca\and retry. - The Vault connection string uses
127.0.0.1, notlocalhost, because the Vault client resolveslocalhostto IPv6 first while the server binds IPv4. - The launcher opens visible windows, so run it from a normal interactive terminal, not a service or CI.
- The SideCar and HybridWorker are not started automatically; they need their own mapping or script configuration.
Expected result
- Three middleware instances behind a load balancer, with workers registered for a sample service