Skip to content

Private clusters

kubelatch needs to reach the API server of every cluster it manages over https. If the API server is private (an EKS with a private endpoint, a k3s in an office), here are your options for reaching it.

kubelatch has no relay of its own and no tunnel-specific support. It uses your organization's network.

flowchart LR
  P[People and CI] -->|https| K[kubelatch<br/>management cluster]
  K -->|tunnel or VPN| A[Private API server]

The options

Option How When
VPN or peering Joins the management cluster's network with the private cluster's. The simplest option if it already exists.
Tailscale The Tailscale operator on the private cluster exposes the API server: tailscale up --advertise-routes on a node, or a ProxyGroup/Connector. kubelatch runs with a tailscale sidecar (extraContainers and extraVolumes in the chart's values), or the management cluster is on the tailnet. If you already use Tailscale. The kubelatch namespace applies the restricted Pod Security Admission level: a sidecar that asks for privileges (for example NET_ADMIN) won't start there.
Cloudflare Tunnel Only the network tunnel (WARP Connector or private networks), which gives IP reachability to the API server. If you already use Cloudflare Zero Trust.

Application-level Cloudflare Tunnel doesn't work

Publishing the API server as a Cloudflare Access application requires an Access service token on every request. kubelatch can't add that header, so its requests to the cluster would be rejected.

Register the cluster through the tunnel

Registration is the usual one (Register a cluster), with one difference: the API server address kubelatch uses is the one it can reach, not the one your kubectl uses.

  1. In the first step of the cluster's Enroll card, open Advanced options, type that address in API server URL for kubelatch, for example the one that resolves over the tailnet with Tailscale, and click Generate command. If you already have the command, add --server <url> at the end, after sh -s -- (add -s -- --server <url> if it ends in a plain sh): it wins over the field.
  2. Run the enrollment command as usual, with your kubectl's kubeconfig. The script shows both addresses (kubelatch will reach that API server at …) and asks for confirmation.
  3. The CA doesn't change: the script sends the one in your kubeconfig.

You don't edit any JSON. If kubelatch can't reach that address, it refuses the tokens, the script says so and the link stays valid (up to 10 refused attempts): rerun it with the right --server.

The URL only accepts https and never a literal link-local, metadata, or multicast IP (names aren't resolved to check this).

Check that it works

  • The cluster switches to Ready in Clusters.
  • Namespaces lists the cluster's namespaces.
  • A request through the proxy works. If the proxy responds 502 with could not talk to the cluster's API server, kubelatch can't reach the registered server: check the tunnel and the routes from the management cluster. The full error is in kubelatch's log.