The Tailscale Kubernetes Operator enables seamless integration between Kubernetes clusters and Tailscale’s secure networking capabilities. In this deep dive, I’ll explore how to use the operator to manage Tailscale connectivity in a Kubernetes environment.
Live Kubernetes manifests for this setup can be found in my GitHub repository.
How Tailscale Works
Before diving into the operator specifics, it’s helpful to understand how Tailscale works. Tailscale creates a secure mesh network using WireGuard for encrypted tunnels between nodes. Instead of traditional hub-and-spoke VPN architecture, Tailscale enables direct peer-to-peer connections between nodes where possible, falling back to DERP (Designated Encrypted Relay for Packets) servers when direct connections aren’t possible.
Installation
Before we can use any of the Tailscale features, we need to install the operator.
Please follow the Tailscale Kubernetes Operator Installation Guide for more details.
API Server Proxy
One of the most powerful features of the Tailscale Kubernetes Operator is the API Server Proxy. This allows you to securely expose your Kubernetes control plane (kube-apiserver
) over Tailscale, eliminating the need for external management tools like Rancher.
Setting up API Server Access
Configure Tailscale ACLs
First, we need to set up appropriate access controls in the Tailscale ACLs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
{ "grants": [ { "src": ["autogroup:admin"], "dst": ["tag:k8s-operator"], "app": { "tailscale.com/cap/kubernetes": [ { "impersonate": { "groups": ["system:masters"] } } ] } }, { "src": ["autogroup:member"], "dst": ["tag:k8s-operator"], "app": { "tailscale.com/cap/kubernetes": [ { "impersonate": { "groups": ["tailnet-readers"] } } ] } } ] }
This configuration:
- Grants admin users (
autogroup:admin
) full cluster access via thesystem:masters
group - Gives regular users (
autogroup:member
) read-only access through thetailnet-readers
group - Uses Tailscale’s built-in group impersonation for RBAC integration
- Grants admin users (
Set up RBAC for Read-only Access
Create a
ClusterRoleBinding
for the read-only group:1 2 3 4 5 6 7 8 9 10 11 12
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: tailnet-readers-view roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view subjects: - kind: Group name: tailnet-readers apiGroup: rbac.authorization.k8s.io
Configure kubectl
Set up your local kubectl configuration:
1
tailscale configure kubeconfig tailscale-operator.your-tailnet.ts.net
Once configured, you can securely access your cluster from anywhere in your tailnet:
Egress Configuration
The operator enables pods within your cluster to access resources in your tailnet through Tailscale’s secure mesh network.
Here’s an example of exposing a Tailscale node to your cluster:
|
|
The operator creates:
- A StatefulSet running a Tailscale proxy pod
- A Service that routes traffic through the proxy
- A new node in your tailnet
You can verify the connectivity:
|
|
Subnet Routing
The Tailscale Connector resource allows you to advertise cluster subnets to your tailnet, enabling seamless access to cluster resources.
|
|
The Connector creates a Tailscale node that routes traffic between your tailnet and the advertised subnets:
Auto-approving Routes
To automatically approve subnet routes, add this to your Tailscale ACLs:
|
|
Advanced Topics
Pod Security and Privileges
The Tailscale operator requires privileged access to configure networking. To allow this in namespaces with Pod Security Policies:
|
|
Network Analysis
Using Hubble, we can observe the Tailscale traffic patterns: We can see the UDP flows to the world outbound to other Tailscale nodes, as well as the connections to the Tailscale Coordination servers over HTTPS.
NAT Behavior
The Connector pod operates in EasyNAT mode, enabling direct UDP connections when possible:
|
|
This direct connectivity indicates successful NAT traversal without requiring DERP relay servers.