Use multiple tailnets for devices running on Kubernetes
Last validated:
When deploying the Tailscale Kubernetes Operator's custom resources, you may want workloads to communicate across clusters and across tailnets. In Tailscale v1.96 and later, you can use the Tailnet custom resource definition to specify which tailnet a ProxyGroup, Connector, or Recorder instance should use.
Prerequisites
You need access to multiple tailnets, either through separate logins or managed by a single organization. For more information on managing multiple tailnets within a single organization, refer to managing multiple tailnets.
Each tailnet you want to expose requires the appropriate tagOwners set in your ACL policy file for the Tailscale Kubernetes Operator:
"tagOwners": {
"tag:k8s-operator": [],
"tag:k8s": ["tag:k8s-operator"],
}
If you use different tags from the default tag:k8s-operator, use those in place of the example given
above.
Each tailnet also requires an OAuth client that the operator uses to generate auth keys for workloads. Before creating a Tailnet resource, create a new OAuth client in the OAuth clients for the tailnet you want to provide access to. Create the client with Devices Core, Auth Keys, Services write scopes, and the tag tag:k8s-operator.
Create a Tailnet resource
Each Tailnet resource references a set of OAuth credentials stored as a Kubernetes Secret within the same namespace as the operator.
Once you have the client ID and secret, create a Secret resource:
apiVersion: v1
kind: Secret
metadata:
name: example-tailnet
namespace: tailscale
stringData:
client_id: "<CLIENT_ID>"
client_secret: "<CLIENT_SECRET>"
If you deployed the Tailscale Kubernetes Operator into a different namespace, use the name of that namespace instead of
tailscale.
Next, create a Tailnet resource that references the secret containing the OAuth credentials:
apiVersion: tailscale.com/v1alpha
kind: Tailnet
metadata:
name: example-tailnet
spec:
credentials:
secretName: example-tailnet
Tailnet resources are cluster-scoped and do not require a value in the namespace field.
Once deployed, the operator checks that the specified credentials exist and have access to the Tailscale API. If successful, the Tailnet resource transitions into the TailnetReady state and can be used by other resources. Use the kubectl get tailnet command to view the status of your tailnet.
Configure resources to use a specific tailnet
Once you have one or more Tailnet resources in your cluster, you can create ProxyGroup, Connector, and Recorder resources that connect to that tailnet using the spec.tailnet field. This field is immutable, with a blank tailnet denoting that the resource should use the tailnet that the operator was originally configured with.
The following examples show how to configure these resources to use a specific tailnet.
A Connector resource using a specific tailnet:
apiVersion: tailscale.com/v1alpha1
kind: Connector
metadata:
name: example-connector
spec:
replicas: 3
tailnet: example-tailnet
exitNode: true
For more information on Connector resources, refer to create exit nodes and subnet routers on Kubernetes.
A Recorder resource using a specific tailnet:
apiVersion: tailscale.com/v1alpha1
kind: Recorder
metadata:
name: example-recorder
spec:
replicas: 3
tailnet: example-tailnet
storage: {}
For more information on Recorder resources, refer to session recording.
A ProxyGroup resource using a specific tailnet:
apiVersion: tailscale.com/v1alpha1
kind: ProxyGroup
metadata:
name: example-proxygroup
spec:
replicas: 3
tailnet: example-tailnet
type: kube-apiserver
For more information on ProxyGroup resources, refer to the ingress or egress documentation.
Once started and ready, your devices appear across your tailnets in the respective Machines pages.