{"slug":"use-multiple-tailnets-for-devices-running-on-kubernetes","title":"Use multiple tailnets for devices running on Kubernetes","tags":["tailscale","containers","devices"],"agent_summary":"Last validated: Mar 6, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Use multiple tailnets for devices running on Kubernetes\r\n\r\nLast validated: Mar 6, 2026\r\n\r\nUsing multiple tailnets with a single operator deploymentis currently [in alpha](https://tailscale.com/docs/reference/tailscale-release-stages#alpha).\r\n\r\nWhen deploying the Tailscale operator's [custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources), you may want workloads to not only be\r\nable to communicate across clusters, but also across tailnets. For operator versions 1.96 and later you can now use the\r\n`Tailnet` custom resource definition to specify which tailnet should be used by `ProxyGroup`, `Connector` and `Recorder`\r\ninstances.\r\n\r\n## [Prerequisites](https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet\\#prerequisites)\r\n\r\nBefore you begin, you will need access to multiple tailnets. This can either be through separate logins or managed by\r\na single organization. For more information on managing multiple tailnets within a single organization, refer to the\r\ndocumentation for [managing multiple tailnets](https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet).\r\n\r\nEach tailnet you wish to expose requires the appropriate `tagOwners` set in your ACL policy file for the Kubernetes\r\noperator:\r\n\r\n```json\r\n\"tagOwners\": {\r\n\t\"tag:k8s-operator\": [],\r\n\t\"tag:k8s\": [\"tag:k8s-operator\"],\r\n}\r\n```\r\n\r\nIf you're using different tags to the default `tag:k8s-operator`, use those in place of the example given\r\nabove.\r\n\r\nFinally, each tailnet requires an [OAuth client](https://tailscale.com/docs/features/oauth-clients) that can be used by the operator to generate\r\nauth keys for workloads. Before attempting to create a `Tailnet` resource, create a new OAuth client in the\r\n[Trust credentials](https://login.tailscale.com/admin/settings/trust-credentials) page of the admin console for the tailnet you wish to provide\r\naccess to. Create the client with `Devices Core`, `Auth Keys`, `Services` write scopes, and the tag `tag:k8s-operator`.\r\n\r\n## [Creating a Tailnet resource](https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet\\#creating-a-tailnet-resource)\r\n\r\nEach `Tailnet` resource references a set of OAuth credentials that must be stored as a Kubernetes `Secret` within the\r\nsame namespace as the operator.\r\n\r\nOnce you have the client id and secret, create a `Secret` resource:\r\n\r\n```yaml\r\napiVersion: v1\r\nkind: Secret\r\nmetadata:\r\n  name: example-tailnet\r\n  namespace: tailscale\r\nstringData:\r\n  client_id: \"<CLIENT_ID>\"\r\n  client_secret: \"<CLIENT_SECRET>\"\r\n```\r\n\r\nIf you deployed the Kubernetes operator into a different namespace, use the name of that namespace instead of\r\n`tailscale`.\r\n\r\nNext, create a `Tailnet` resource that references the secret containing the OAuth credentials:\r\n\r\n```yaml\r\napiVersion: tailscale.com/v1alpha\r\nkind: Tailnet\r\nmetadata:\r\n  name: example-tailnet\r\nspec:\r\n  credentials:\r\n    secretName: example-tailnet\r\n```\r\n\r\n`Tailnet` resources are cluster-scoped and do not require a value in the `namespace` field.\r\n\r\nOnce deployed, the operator will perform checks that ensure the specified credentials exist and have access to the\r\nTailscale API. If successful, the `Tailnet` resource will transition into the `TailnetReady` state, and can be used\r\nby other resources. Use the `kubectl get tailnet` command to view the status of your tailnet.\r\n\r\n## [Choosing a Tailnet](https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet\\#choosing-a-tailnet)\r\n\r\nOnce you have one or more `Tailnet` resources in your cluster, you can create `ProxyGroup`, `Connector` and `Recorder`\r\nresources that connect to that tailnet using the `spec.tailnet` field. This field is immutable, with a blank tailnet\r\ndenoting that the resource should use the tailnet that the operator was originally configured with.\r\n\r\nBelow are some basic examples of how to configure these resources to use a specific tailnet:\r\n\r\n```yaml\r\napiVersion: tailscale.com/v1alpha1\r\nkind: Connector\r\nmetadata:\r\n\tname: example-connector\r\nspec:\r\n\treplicas: 3\r\n\ttailnet: example-tailnet\r\n\texitNode: true\r\n```\r\n\r\nFor more information on `Connector` resources, refer to the [subnet routers and exit nodes](https://tailscale.com/docs/features/kubernetes-operator/how-to/connector) documentation.\r\n\r\n```yaml\r\napiVersion: tailscale.com/v1alpha1\r\nkind: Recorder\r\nmetadata:\r\n\tname: example-recorder\r\nspec:\r\n\treplicas: 3\r\n\ttailnet: example-tailnet\r\n\tstorage: {}\r\n```\r\n\r\nFor more information on `Recorder` resources, refer to the [recorder nodes](https://tailscale.com/docs/features/kubernetes-operator/how-to/tsrecorder) documentation.\r\n\r\n```yaml\r\napiVersion: tailscale.com/v1alpha1\r\nkind: ProxyGroup\r\nmetadata:\r\n\tname: example-proxygroup\r\nspec:\r\n\treplicas: 3\r\n\ttailnet: example-tailnet\r\n\ttype: kube-apiserver\r\n```\r\n\r\nFor more information on `ProxyGroup` resources, refer to the [ingress](https://tailscale.com/docs/features/kubernetes-operator/how-to/cluster-ingress) or [egress](https://tailscale.com/docs/features/kubernetes-operator/how-to/cluster-egress) documentation and\r\ntheir relevant sections on using `ProxyGroup` resources.\r\n\r\nOnce started and ready, your devices should appear across your tailnets in the respective [Machines](https://login.tailscale.com/admin/machines)\r\npages of your tailnets.\r\n\r\n![Project Logo](https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed)\r\n\r\nAsk AI\r\n\r\nreCAPTCHA\r\n\r\nRecaptcha requires verification.\r\n\r\nprotected by **reCAPTCHA**\r\n","html":"<h1>Use multiple tailnets for devices running on Kubernetes</h1>\n<p>Last validated: Mar 6, 2026</p>\n<p>Using multiple tailnets with a single operator deploymentis currently <a href=\"https://tailscale.com/docs/reference/tailscale-release-stages#alpha\">in alpha</a>.</p>\n<p>When deploying the Tailscale operator's <a href=\"https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources\">custom resources</a>, you may want workloads to not only be\r\nable to communicate across clusters, but also across tailnets. For operator versions 1.96 and later you can now use the\r\n<code>Tailnet</code> custom resource definition to specify which tailnet should be used by <code>ProxyGroup</code>, <code>Connector</code> and <code>Recorder</code>\r\ninstances.</p>\n<h2><a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet#prerequisites\">Prerequisites</a></h2>\n<p>Before you begin, you will need access to multiple tailnets. This can either be through separate logins or managed by\r\na single organization. For more information on managing multiple tailnets within a single organization, refer to the\r\ndocumentation for <a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet\">managing multiple tailnets</a>.</p>\n<p>Each tailnet you wish to expose requires the appropriate <code>tagOwners</code> set in your ACL policy file for the Kubernetes\r\noperator:</p>\n<pre><code class=\"language-json\">\"tagOwners\": {\r\n\t\"tag:k8s-operator\": [],\r\n\t\"tag:k8s\": [\"tag:k8s-operator\"],\r\n}\n</code></pre>\n<p>If you're using different tags to the default <code>tag:k8s-operator</code>, use those in place of the example given\r\nabove.</p>\n<p>Finally, each tailnet requires an <a href=\"https://tailscale.com/docs/features/oauth-clients\">OAuth client</a> that can be used by the operator to generate\r\nauth keys for workloads. Before attempting to create a <code>Tailnet</code> resource, create a new OAuth client in the\r\n<a href=\"https://login.tailscale.com/admin/settings/trust-credentials\">Trust credentials</a> page of the admin console for the tailnet you wish to provide\r\naccess to. Create the client with <code>Devices Core</code>, <code>Auth Keys</code>, <code>Services</code> write scopes, and the tag <code>tag:k8s-operator</code>.</p>\n<h2><a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet#creating-a-tailnet-resource\">Creating a Tailnet resource</a></h2>\n<p>Each <code>Tailnet</code> resource references a set of OAuth credentials that must be stored as a Kubernetes <code>Secret</code> within the\r\nsame namespace as the operator.</p>\n<p>Once you have the client id and secret, create a <code>Secret</code> resource:</p>\n<pre><code class=\"language-yaml\">apiVersion: v1\r\nkind: Secret\r\nmetadata:\r\n  name: example-tailnet\r\n  namespace: tailscale\r\nstringData:\r\n  client_id: \"&#x3C;CLIENT_ID>\"\r\n  client_secret: \"&#x3C;CLIENT_SECRET>\"\n</code></pre>\n<p>If you deployed the Kubernetes operator into a different namespace, use the name of that namespace instead of\r\n<code>tailscale</code>.</p>\n<p>Next, create a <code>Tailnet</code> resource that references the secret containing the OAuth credentials:</p>\n<pre><code class=\"language-yaml\">apiVersion: tailscale.com/v1alpha\r\nkind: Tailnet\r\nmetadata:\r\n  name: example-tailnet\r\nspec:\r\n  credentials:\r\n    secretName: example-tailnet\n</code></pre>\n<p><code>Tailnet</code> resources are cluster-scoped and do not require a value in the <code>namespace</code> field.</p>\n<p>Once deployed, the operator will perform checks that ensure the specified credentials exist and have access to the\r\nTailscale API. If successful, the <code>Tailnet</code> resource will transition into the <code>TailnetReady</code> state, and can be used\r\nby other resources. Use the <code>kubectl get tailnet</code> command to view the status of your tailnet.</p>\n<h2><a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/multi-tailnet#choosing-a-tailnet\">Choosing a Tailnet</a></h2>\n<p>Once you have one or more <code>Tailnet</code> resources in your cluster, you can create <code>ProxyGroup</code>, <code>Connector</code> and <code>Recorder</code>\r\nresources that connect to that tailnet using the <code>spec.tailnet</code> field. This field is immutable, with a blank tailnet\r\ndenoting that the resource should use the tailnet that the operator was originally configured with.</p>\n<p>Below are some basic examples of how to configure these resources to use a specific tailnet:</p>\n<pre><code class=\"language-yaml\">apiVersion: tailscale.com/v1alpha1\r\nkind: Connector\r\nmetadata:\r\n\tname: example-connector\r\nspec:\r\n\treplicas: 3\r\n\ttailnet: example-tailnet\r\n\texitNode: true\n</code></pre>\n<p>For more information on <code>Connector</code> resources, refer to the <a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/connector\">subnet routers and exit nodes</a> documentation.</p>\n<pre><code class=\"language-yaml\">apiVersion: tailscale.com/v1alpha1\r\nkind: Recorder\r\nmetadata:\r\n\tname: example-recorder\r\nspec:\r\n\treplicas: 3\r\n\ttailnet: example-tailnet\r\n\tstorage: {}\n</code></pre>\n<p>For more information on <code>Recorder</code> resources, refer to the <a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/tsrecorder\">recorder nodes</a> documentation.</p>\n<pre><code class=\"language-yaml\">apiVersion: tailscale.com/v1alpha1\r\nkind: ProxyGroup\r\nmetadata:\r\n\tname: example-proxygroup\r\nspec:\r\n\treplicas: 3\r\n\ttailnet: example-tailnet\r\n\ttype: kube-apiserver\n</code></pre>\n<p>For more information on <code>ProxyGroup</code> resources, refer to the <a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/cluster-ingress\">ingress</a> or <a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/cluster-egress\">egress</a> documentation and\r\ntheir relevant sections on using <code>ProxyGroup</code> resources.</p>\n<p>Once started and ready, your devices should appear across your tailnets in the respective <a href=\"https://login.tailscale.com/admin/machines\">Machines</a>\r\npages of your tailnets.</p>\n<p><img src=\"https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed\" alt=\"Project Logo\"></p>\n<p>Ask AI</p>\n<p>reCAPTCHA</p>\n<p>Recaptcha requires verification.</p>\n<p>protected by <strong>reCAPTCHA</strong></p>\n"}