Tailscale Operator
Running the Tailscale-operator on CoreWeave
About Tailscale
Tailscale is a convenient mesh network VPN Services that powers encrypted peer-to-peer private network communication. With native support for Kubernetes and a Kubernetes Operator, Tailscale is a popular choice for consumers of CoreWeave's Kubernetes Services to securely access in-cluster resources, and the Kubernetes API server, without exposing them publicly.
To function optimally in the CKS environment, CoreWeave packages a bespoke version of the tailscale-operator Helm chart, and a CoreWeave-specific container image.
Usage
Tailnet Configuration
Editing your Tailnet policy JSON may be required for use with CKS. The following sections outline the recommended changes to your Tailnet configuration.
Tailnet ipPool
Tailscale's default configuration assigns an IP address from the 100.64.0.0/10
range to each device joined to a Tailnet. Because CKS operates some control-plane Services in the 100.124.0.0/18
address range, a Tailnet used with CKS should allocate addresses from a smaller, non-overlapping pool.
Tailscale supports configurable IP Pools for this purpose. The largest contiguous non-overlapping address pool for use with CKS is 100.64.0.0/13
.
{"nodeAttrs": [{"ipPool": ["100.64.0.0/13"],},],}
CoreWeave's tailscale-operator
chart and container image provide the customizations necessary to support a non-overlapping ipPool
out of the box.
Tailnet derpMap
Tailscale runs relay servers worldwide to help establish direct connections to endpoints on your Tailnet. When direct connections are impossible, the relays help to forward traffic to your endpoints.
To compliment the Tailscale-hosted relays, CoreWeave hosts its own relays in select regions to provide a congestion-free, last-mile hop to your CKS workloads.
To consume CoreWeave hosted relays, they must be added to Tailnet's configuration.
By default, the Tailscale client chooses a relay closest to connection origin, which may only sometimes be a CoreWeave hosted relay. To ensure exclusive consumption of CoreWeave relays, enable OmitDefaultRegions
in your Tailnet configuration. Please note that this configuration may not be optimal when connecting to endpoints outside a CoreWeave Region.
A Policy JSON example
This example outlines all the recommended objects for your Tailnet's Policy JSON.
{// Included in the default Tailscale Policy file"acls": [{"action": "accept", "src": ["*"], "dst": ["*:*"]},],"ssh": [{"action": "check","src": ["autogroup:member"],"dst": ["autogroup:self"],"users": ["autogroup:nonroot", "root"],},],// nodeAttrs for tailnet ipPool"nodeAttrs": [{"ipPool": ["100.64.0.0/13"],},],// derpMap for Tailscale relays on CoreWeave"derpMap": {// Disable default Tailscale relays"OmitDefaultRegions": true,"Regions": {// To find a up to date, complete list of CoreWeave relays// https://raw.githubusercontent.com/coreweave/tailscale-derp/main/derpmap/derpmap.json"904": {"RegionID": 904,"RegionCode": "us-east-04","RegionName": "US-EAST-04","Nodes": [{"Name": "904a","RegionID": 904,"HostName": "derp.us-east-04.coreweave.com",},],},},},// For the tailscale-operator to use it's OAuth token for addding tailscale Nodes to the tailnet"tagOwners": {"tag:k8s-operator": [],"tag:k8s": ["tag:k8s-operator"],},}
Deploying the tailscale-operator
chart
The CoreWeave Charts tailscale-operator
chart is based on the upstream Tailscale chart, with optimizations that work best with CKS.
The CoreWeave tailscale-operator
Helm chart includes the following:
- A default
ProxyClass
applied to all exposed Services to configure proxy-specific settings - Support for CKS-specific
TS_CGNAT_OVERRIDE_RANGE
, to allow cluster-local communication in the100.124.0.0/18
address range - Default resource limits
- A convenient post-install hook to declaratively expose existing in-cluster Services to your Tailnet
To install the Helm chart, first provide an OAuth client and modify your Tailnet policy file so the tailscale-operator
can communicate with the Tailscale control plane. You can find detailed information about OAuth clients in Tailscale's documentation.
"tagOwners": {"tag:k8s-operator": [],"tag:k8s": ["tag:k8s-operator"],}
Install the tailscale-operator
chart using one of these methods:
Install with the Secret pre-created
In this method, the tailscale
namespace is pre-created, and the Kubernetes Secret operator-oauth
is populated with the credentials that the tailscale-operator
expects and consumes.
First, create the tailscale
namespace.
$kubectl create namespace tailscale
Next, create a Secret from the OAuth secret generated in the admin console.
$kubectl create secret generic operator-oauth \--from-literal=client_id=<YOUR_CLIENT_ID> \--from-literal=client_secret=<YOUR_CLIENT_SECRET>
After adding the secret to the namespace, install the Helm chart.
$helm upgrade --install tailscale-operator \--namespace tailscale coreweave-charts/tailscale-operator
Install by setting the OAuth secret in Helm values
This method installs the Secrets, and creates the tailscale
namespace, during the Helm chart installation.
$helm upgrade --install \--create-namespace tailscale-operator \--namespace tailscale \--set tailscale-operator.oauth.clientId=[Insert Client ID] \--set tailscale-operator.oauth.clientSecret=[Insert Client Secret] \coreweave-charts/tailscale-operator
Verify the installation
After the installation is complete, verify that the tailscale-operator
is running in the tailscale
namespace.
$kubectl get pods -n tailscale
Output:
NAME READY STATUS RESTARTS AGEoperator-54f98f5c6f-jwjmr 1/1 Running 0 9m18s
Check the Tailscale admin console to see the connected clients.
Exposing Services
To expose Kubernetes Services to Tailnet, you can annotate a Kubernetes service, or configure the Services in Helm values.
Annotate a Kubernetes Service
To expose a Services to Tailnet, annotate the Services with the tailscale.com/expose: true
annotation.
$kubectl annotate Services kubernetes tailscale.com/expose="true" -n default
After the Services is exposed, a new Pod is created in the tailscale
namespace.
$kubectl get pods -n tailscale
Output, with the newly created Pod highlighted:
NAME READY STATUS RESTARTS AGEoperator-54f98f5c6f-jwjmr 1/1 Running 6 (55m ago) 59mts-kubernetes-6f9dq-0 1/1 Running 0 8m7s
You can access the Services through the Tailscale IP address or MagicDNS hostname. By default, MagicDNS names are formatted as <namespace>-<service-name>.<magicDNS-hostname>
.
Configuring Services in Helm
To expose a Services to Tailnet, modify your Helm values to include the Service.
$helm upgrade -i tailscale-operator -n tailscale coreweave-charts/tailscale-operator \--set exposedServices.[0].name=kubernetes \--set exposedServices.[0].namespace=default
This leverages a Helm post-install/upgrade hook during upgrade or installation.
Learn more
For additional information on Tailscale usage, see:
- Tailscale documentation: Using the Tailscale Kubernetes Operator
- Tailscale documentation: Managing egress traffic and managing ingress traffic from your cluster with Tailscale