Welp, turns out Tailscale folks already did this. You should use their operator :)
katsnet lets you use kubectl over Tailscale. It runs as an impersonating
proxy
inside of the cluster and joins your tailnet as a node.
When your kubectl commands go through katsnet, they will appear with your Tailscale identity:
- for un-tagged nodes, Kubernetes will see your Tailscale login name (email) as
the
User; it will also see a group namednode:<name of the node you're connecting from> - for tagged nodes, Kubernetes will see groups named after the node tags, like
tag:prod
You can use the standard Kubernetes RBAC policies to grant these User and Group
subjects permissions within the cluster. For example,
user-rbac.yaml grants the admin ClusterRole to my login
name when I connect from an untagged node like my laptop.
For a local minikube setup:
- apply the base manifests:
kubectl apply -f katsnet.yaml - create a secret with your Tailscale auth key:
kubectl create secret generic -n katsnet auth-key --from-literal=key=YOUR_AUTH_KEY - create k8s RBAC policies for your Tailscale identity, similar to user-rbac.yaml
- update your
kubeconfig:katsnet update-kubeconfig minikube # or go run main.go update-kubeconfig minikube - done, now you can run
kubectlcommands through the tailnet!
Generic setup is pretty much like the minikube setup, you just have to update
TS_HOSTNAME in katsnet.yaml to the name you want your Tailscale node to
have.
Note that any process on any node within the tailnet can make k8s API requests
with this setup. katsnet doesn't do any additional authentication beyond
tailnet membership.
This means, for example, that you can open
http://<katsnet-node-name>/api/v1/namespaces/kube-system/secrets in the
browser and see all the secrets in kube-system namespace, as long as RBAC
allows you to. CORS should prevent any random site from making such requests
on your behalf, but there could be possibilities for attackers triggering
requests from your machine.
So don't go running this in production just yet.