{"slug":"deploy-app-connectors-on-kubernetes-using-the-kubernetes-operator","title":"Deploy app connectors on Kubernetes using the Kubernetes Operator","tags":["tailscale","containers"],"agent_summary":"Last validated: Oct 29, 2025","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Deploy app connectors on Kubernetes using the Kubernetes Operator\r\n\r\nLast validated: Oct 29, 2025\r\n\r\nDeploying app connectors on Kubernetes using the Kubernetes Operatoris currently [in beta](https://tailscale.com/docs/reference/tailscale-release-stages#beta).\r\n\r\nIn Tailscale v1.78 and later, you can deploy [`app connector`](https://tailscale.com/docs/features/app-connectors) to your Kubernetes cluster using the Kubernetes Operator and its [`Connector` Custom Resource Definition](https://github.com/tailscale/tailscale/blob/main/k8s-operator/api.md#connector).\r\n\r\nThe only tested and supported use case is to deploy an app connector to access SaaS applications available on the public internet. Using the app connector to expose cluster workloads or other internal workloads might work, but this is not a use case that we have tested or optimized for.\r\n\r\nIf you are using the app connector to access SaaS applications because you need a predictable egress IP address that you can add to an allowlist, it's also your responsibility to ensure that cluster traffic from the connector flows using that predictable IP address. For example, by ensuring cluster egress traffic is routed using an egress NAT device with a static IP address.\r\n\r\n## [Prerequisites](https://tailscale.com/docs/features/kubernetes-operator/how-to/app-connector\\#prerequisites)\r\n\r\n1. Set up the [Kubernetes operator](https://tailscale.com/docs/features/kubernetes-operator).\r\n\r\n2. (Optional) Create a [tag](https://tailscale.com/docs/features/tags) (for example, `tag:github-connector`) to attach to the connector device.\r\nIf you do not specify a custom tag, the operator will tag the connector device with `tag:k8s`.\r\nMake sure the operator is one of the [tag owners](https://tailscale.com/docs/reference/syntax/policy-file#tag-owners) for the connector tag:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```json\r\n\"tagOwners\": {\r\n     \"tag:k8s-operator\":     [],\r\n     \"tag:github-connector\": [\"tag:k8s-operator\"],\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n\r\nYou can use the [visual policy editor](https://tailscale.com/docs/features/visual-editor) to manage your tailnet policy file. Refer to the [visual editor reference](https://tailscale.com/docs/reference/visual-editor) for guidance on using the visual editor.\r\n\r\n3. Configure the domains that route through the app connector in [Apps](https://tailscale.com/docs/features/app-connectors#add-apps).\r\n\r\n4. Follow steps three through five in [app connector policy configuration instructions](https://tailscale.com/docs/features/app-connectors#policy) to set up permissions to route traffic for the required domains using the app connector.\r\n\r\n\r\n## [Deploy](https://tailscale.com/docs/features/kubernetes-operator/how-to/app-connector\\#deploy)\r\n\r\n1. Create your `Connector` resource based on the below and save it as `connector.yaml`.\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```yaml\r\napiVersion: tailscale.com/v1alpha1\r\nkind: Connector\r\nmetadata:\r\n     name: appc-github\r\nspec:\r\n     appConnector: {}\r\n```\r\n\r\n2. (Optional) Add [preconfigured routes](https://tailscale.com/docs/reference/best-practices/app-connectors#preconfiguration)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```yaml\r\napiVersion: tailscale.com/v1alpha1\r\nkind: Connector\r\nmetadata:\r\n     name: appc-github\r\nspec:\r\n     appConnector:\r\n       routes:\r\n    - 140.82.114.4/32\r\n```\r\n\r\nYou can find [all available `Connector` configuration options on GitHub →](https://github.com/tailscale/tailscale/blob/main/k8s-operator/api.md#connector)\r\n\r\n3. Apply the file:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nkubectl apply -f connector.yaml\r\n```\r\n\r\n4. (Optional) Wait for the recorder to become ready:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```shell\r\nkubectl wait --for condition=ConnectorReady=true Connector appc-github\r\nconnector.tailscale.com/appc-github condition met\r\n```\r\n\r\n5. (Optional) [Add the app connector's egress IP address to an IP allowlist](https://tailscale.com/docs/features/app-connectors#ip-allowlist).\r\n\r\n\r\n## [Known issues and limitations](https://tailscale.com/docs/features/kubernetes-operator/how-to/app-connector\\#known-issues-and-limitations)\r\n\r\n- The setup flow involves a large number of manual steps to configure the tailnet policy file and apps.\r\nWe welcome feedback for further improvements for automating this workflow.\r\n\r\n- There is no way to auto-discover the egress IP of the app connector - you need to look it up in the admin console.\r\n\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>Deploy app connectors on Kubernetes using the Kubernetes Operator</h1>\n<p>Last validated: Oct 29, 2025</p>\n<p>Deploying app connectors on Kubernetes using the Kubernetes Operatoris currently <a href=\"https://tailscale.com/docs/reference/tailscale-release-stages#beta\">in beta</a>.</p>\n<p>In Tailscale v1.78 and later, you can deploy <a href=\"https://tailscale.com/docs/features/app-connectors\"><code>app connector</code></a> to your Kubernetes cluster using the Kubernetes Operator and its <a href=\"https://github.com/tailscale/tailscale/blob/main/k8s-operator/api.md#connector\"><code>Connector</code> Custom Resource Definition</a>.</p>\n<p>The only tested and supported use case is to deploy an app connector to access SaaS applications available on the public internet. Using the app connector to expose cluster workloads or other internal workloads might work, but this is not a use case that we have tested or optimized for.</p>\n<p>If you are using the app connector to access SaaS applications because you need a predictable egress IP address that you can add to an allowlist, it's also your responsibility to ensure that cluster traffic from the connector flows using that predictable IP address. For example, by ensuring cluster egress traffic is routed using an egress NAT device with a static IP address.</p>\n<h2><a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/app-connector#prerequisites\">Prerequisites</a></h2>\n<ol>\n<li>\n<p>Set up the <a href=\"https://tailscale.com/docs/features/kubernetes-operator\">Kubernetes operator</a>.</p>\n</li>\n<li>\n<p>(Optional) Create a <a href=\"https://tailscale.com/docs/features/tags\">tag</a> (for example, <code>tag:github-connector</code>) to attach to the connector device.\r\nIf you do not specify a custom tag, the operator will tag the connector device with <code>tag:k8s</code>.\r\nMake sure the operator is one of the <a href=\"https://tailscale.com/docs/reference/syntax/policy-file#tag-owners\">tag owners</a> for the connector tag:</p>\n</li>\n</ol>\n<pre><code class=\"language-json\">\"tagOwners\": {\r\n     \"tag:k8s-operator\":     [],\r\n     \"tag:github-connector\": [\"tag:k8s-operator\"],\r\n}\n</code></pre>\n<p>You can use the <a href=\"https://tailscale.com/docs/features/visual-editor\">visual policy editor</a> to manage your tailnet policy file. Refer to the <a href=\"https://tailscale.com/docs/reference/visual-editor\">visual editor reference</a> for guidance on using the visual editor.</p>\n<ol start=\"3\">\n<li>\n<p>Configure the domains that route through the app connector in <a href=\"https://tailscale.com/docs/features/app-connectors#add-apps\">Apps</a>.</p>\n</li>\n<li>\n<p>Follow steps three through five in <a href=\"https://tailscale.com/docs/features/app-connectors#policy\">app connector policy configuration instructions</a> to set up permissions to route traffic for the required domains using the app connector.</p>\n</li>\n</ol>\n<h2><a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/app-connector#deploy\">Deploy</a></h2>\n<ol>\n<li>Create your <code>Connector</code> resource based on the below and save it as <code>connector.yaml</code>.</li>\n</ol>\n<pre><code class=\"language-yaml\">apiVersion: tailscale.com/v1alpha1\r\nkind: Connector\r\nmetadata:\r\n     name: appc-github\r\nspec:\r\n     appConnector: {}\n</code></pre>\n<ol start=\"2\">\n<li>(Optional) Add <a href=\"https://tailscale.com/docs/reference/best-practices/app-connectors#preconfiguration\">preconfigured routes</a></li>\n</ol>\n<pre><code class=\"language-yaml\">apiVersion: tailscale.com/v1alpha1\r\nkind: Connector\r\nmetadata:\r\n     name: appc-github\r\nspec:\r\n     appConnector:\r\n       routes:\r\n    - 140.82.114.4/32\n</code></pre>\n<p>You can find <a href=\"https://github.com/tailscale/tailscale/blob/main/k8s-operator/api.md#connector\">all available <code>Connector</code> configuration options on GitHub →</a></p>\n<ol start=\"3\">\n<li>Apply the file:</li>\n</ol>\n<pre><code class=\"language-shell\">kubectl apply -f connector.yaml\n</code></pre>\n<ol start=\"4\">\n<li>(Optional) Wait for the recorder to become ready:</li>\n</ol>\n<pre><code class=\"language-shell\">kubectl wait --for condition=ConnectorReady=true Connector appc-github\r\nconnector.tailscale.com/appc-github condition met\n</code></pre>\n<ol start=\"5\">\n<li>(Optional) <a href=\"https://tailscale.com/docs/features/app-connectors#ip-allowlist\">Add the app connector's egress IP address to an IP allowlist</a>.</li>\n</ol>\n<h2><a href=\"https://tailscale.com/docs/features/kubernetes-operator/how-to/app-connector#known-issues-and-limitations\">Known issues and limitations</a></h2>\n<ul>\n<li>\n<p>The setup flow involves a large number of manual steps to configure the tailnet policy file and apps.\r\nWe welcome feedback for further improvements for automating this workflow.</p>\n</li>\n<li>\n<p>There is no way to auto-discover the egress IP of the app connector - you need to look it up in the admin console.</p>\n</li>\n</ul>\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"}