Skip to content

feat(cluster): host-usable kubeconfig for local tenants (PR 2.5) + auto-derive lb-pool - #60

Merged
atbagan merged 1 commit into
mainfrom
feat/local-host-usable-kubeconfig
Jun 12, 2026
Merged

atbagan merged 1 commit into
mainfrom
feat/local-host-usable-kubeconfig

Conversation

@atbagan

@atbagan atbagan commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Problem

The local laptop path's headline step hung on macOS. butlerctl cluster kubeconfig <tenant> returned a kubeconfig pointing at the docker-bridge LoadBalancer IP (e.g. 172.18.255.201:6443), which is not routable from the macOS/Windows host, so kubectl get nodes hung. Two smaller copy-paste hazards in the documented create command: it required --provider (2 local PCs) and a machine-specific --lb-pool.

Changes

  • Host-usable kubeconfig (PR 2.5). For local-provider tenants on macOS/Windows, cluster kubeconfig establishes a background kubectl port-forward to the tenant API server service (via the host-reachable management cluster) and rewrites the kubeconfig to https://127.0.0.1:<port>, preserving the original host as tls-server-name so the server cert (SANs include the bridge IP) still verifies. Reused across runs, detached so the follow-up kubectl works. On Linux the bridge IP is reachable directly, so the kubeconfig is emitted verbatim. Applies to stdout, -o, and --merge.
  • Auto-derive lb-pool. cluster create derives the LoadBalancer pool from the kind docker network for local clusters when --lb-pool is omitted (mirrors bootstrap local), so the documented create command works without a machine-specific flag.
  • TUI access hint in the cluster-detail view pointing at cluster kubeconfig.
  • Unit test for the kubeconfig endpoint rewrite.

Verification (macOS, published artifacts, no --from-source)

Full literal walkthrough, copy-paste as documented:

butlerctl cluster create toy --provider butler-local-provider --workers 1   # auto-derives lb-pool -> Ready
butlerctl cluster kubeconfig toy > toy.yaml                                  # 127.0.0.1 + tls-server-name, tunnel auto-started
kubectl --kubeconfig toy.yaml get nodes                                      # Ready node, NO manual port-forward

All three kubeconfig output paths (stdout / -o / --merge) verified. go vet clean, tests pass.

Pairs with the docs fix in butlerdotdev/butler (local.mdx).

… lb-pool

On macOS/Windows a local-provider tenant kubeconfig points at a docker-bridge
LoadBalancer IP the host cannot route to, so `kubectl get nodes` hangs. For local
tenants on those platforms, `cluster kubeconfig` now establishes a background
port-forward to the tenant API server and rewrites the kubeconfig to 127.0.0.1
(keeping the original host as tls-server-name so the server cert still verifies),
so the documented walkthrough works with no manual steps. On Linux the bridge IP is
reachable directly, so the kubeconfig is emitted verbatim.

`cluster create` now derives the LoadBalancer pool from the kind docker network for
local clusters when --lb-pool is omitted, so the documented create command works
without a machine-specific flag. The cluster-detail TUI gains an access hint.
@atbagan
atbagan merged commit b0601b2 into main Jun 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant