Tailscale Operator provides private access to cluster services and kubectl via VPN.
- Open ACL Editor
- Add or merge these sections:
{
"tagOwners": {
"tag:k8s-operator": ["autogroup:admin"],
"tag:k8s": ["tag:k8s-operator"],
"tag:server": ["autogroup:admin"],
// ... other tags
},
"acls": [
{"action": "accept", "src": ["autogroup:admin"], "dst": ["*:*"]},
{"action": "accept", "src": ["autogroup:admin"], "dst": ["tag:server:22,2222"]},
{"action": "accept", "src": ["autogroup:member"], "dst": ["tag:k8s:443"]},
// ... other rules
],
"grants": [
{
"src": ["autogroup:admin"],
"dst": ["tag:k8s-operator"],
"ip": ["*:*"],
"app": {
"tailscale.com/cap/kubernetes": [{
"impersonate": {"groups": ["system:masters"]},
}],
},
},
// ... other grants
],
"autoApprovers": {
"services": {
"tag:k8s": ["tag:k8s"],
},
// ... other auto approvers
},
"ssh": [
{
"action": "check",
"src": ["autogroup:admin"],
"dst": ["tag:server"],
"users": ["autogroup:nonroot", "root"],
},
// ... other ssh rules
],
// ... other sections
}What each section does
| Section | Purpose |
|---|---|
tagOwners |
Defines who can assign tags to devices |
acls[0] |
Admins — full access to all devices |
acls[1] |
Server SSH — only admins can SSH (port 22, 2222) |
acls[2] |
K8s services — members can access HTTPS only |
grants |
Admin kubectl access via API Server Proxy |
autoApprovers |
Auto-approve Tailscale Services |
Security model:
autogroup:admin→ full access (SSH, kubectl, all services)autogroup:member→ only HTTPS services (:443)- Others → no access
Required for API Server Proxy (kubectl via Tailscale).
- Open DNS Settings
- Scroll to HTTPS Certificates
- Click Enable HTTPS
- Open OAuth Clients
- Click Generate OAuth client
- Select scopes:
- Devices: Core → Write
- Auth Keys → Write
- Services → Write
- Add tag:
tag:k8s-operator - Click Generate client
- Save Client ID as
<TS_CLIENT_ID> - Add to Doppler:
TS_OAUTH_CLIENT_SECRET
Find in Machines — shown in hostnames (e.g., server.tail123456.ts.net)
Note: Want to change tailnet name? Do it now — see Tailscale Server Setup.
Save as <TAILNET_NAME> (just the tail123456 part).
Operator not joining tailnet
kubectl get secret tailscale-oauth -n tailscale -o yaml
kubectl logs -n tailscale -l app.kubernetes.io/name=tailscale-operatorCheck Machines for tailscale-operator with tag:k8s-operator.
kubectl access denied
- Verify HTTPS enabled in DNS settings
- Check ACL grants include your user/group
- Verify
apiServerProxyConfig.mode: "true"in operator values
Service "Pending approval"
Add autoApprovers to ACL (see step 1).
Ingress not appearing in Services
Check Services — ingress should appear as ts-ingress-0, ts-ingress-1 with tag:k8s.
kubectl get pods -n tailscale
kubectl logs -n tailscale -l app.kubernetes.io/name=tailscale-operator