Expose cluster workloads to your tailnet with Ingress

Last validated:

Cluster ingress lets you expose cluster workloads to your tailnet, making them accessible to other devices on your Tailscale network. The operator deploys ingress proxy Pods that forward traffic to backend Services.

You can expose Kubernetes Services to your tailnet at two different layers:

At either layer, you can run ingress in standalone mode using a single proxy pod, or in high availability mode using a ProxyGroup with multiple replicas. Tailscale recommends high availability mode for production use cases.

This page explains the ingress architecture for both layers, proxy modes, and TLS certificate provisioning.

Ingress does not expose services to the public internet by default. For more information, refer to Expose a Cluster Workload to the Internet.

Standalone layer 7 ingress for HTTP and HTTPS

Layer 7 Ingress lets you expose web applications and APIs.

You configure this with an Ingress object with ingressClassName: tailscale. The proxy uses Tailscale Serve to accept traffic.

On creation of an Ingress, the operator:

  • Creates a (combined) config and state Secret.
  • Creates an ingress proxy Pod (single replica StatefulSet) that forwards traffic, letting devices anywhere on the tailnet access the Ingress.
  • Automatically provisions a secure MagicDNS name with a valid TLS certificate for each Ingress.
Architecture diagram showing the Tailscale Kubernetes Operator creating a Secret and StatefulSet for a Layer 7 ingress proxy. The proxy pod forwards traffic from a tailnet client to a Kubernetes Service.

L7 Ingress can also be used with High availability configuration.

For more information about exposing a layer 7 workload, refer to Expose a cluster workload to your tailnet at layer 7.

Standalone layer 3 ingress for TCP/UDP

You can use Layer 3 ingress to expose services like databases or message queues.

You configure this with a Service object that selects the application's pods, using either:

  • The annotation tailscale.com/expose: "true".
  • .spec.type set to LoadBalancer and .spec.loadBalancerClass set to tailscale.

The operator creates:

  • A combined config and state Secret.
  • An ingress proxy Pod using a single replica StatefulSet that forwards traffic, letting devices anywhere on the tailnet access the Service.

This Pod uses iptables or nftables rules to DNAT traffic bound for the proxy's tailnet IP address to the Service's internal cluster IP address instead.

Architecture diagram showing the Tailscale Kubernetes Operator creating a Secret and StatefulSet for a Layer 3 ingress proxy. The proxy pod forwards traffic from a tailnet client to a Kubernetes Service.

You can use L3 Ingress with high availability configuration, and on new or existing Services.

For more information about exposing a layer 3 workload, refer to Expose a cluster workload to your tailnet at layer 3.

High availability (HA) ingress

A high availability L7 or L3 Ingress is similar to the standalone variant, but uses a ProxyGroup to deploy multiple replicas. This lets you:

  • Expose a Kubernetes Service or Ingress resource to your tailnet through multiple active ingress proxies, to prevent downtime during proxy Pod restarts.
  • Expose many Service and Ingress resources to your tailnet using a smaller number of proxy Pods.

You configure HA by adding a tailscale.com/proxy-group annotation to the Ingress or Service.

On creation of an Ingress or Service, the operator:

  • Configures a config Secret per replica.
  • Configures a ConfigMap with either Tailscale Serve config (L7) or iptables/nftables DNAT rules (L3).
  • Configures the Ingress ProxyGroup, which forwards traffic, letting devices anywhere on the tailnet access the Service your Ingress points to.
  • Creates a Tailscale Service for the Ingress ProxyGroup.
Architecture diagram showing the Tailscale Kubernetes Operator creating a per-replica Secret, a ConfigMap, and a Service for the Ingress ProxyGroup. The Operator configures the Ingress ProxyGroup to forward traffic from a tailnet client to a Kubernetes Service.

To get started with Ingress in HA mode, refer to the L7 or L3 setup guides linked above. Ingress ProxyGroup pods require additional permissions.

TLS certificates and limits

The operator provisions certificates from Let's Encrypt automatically.

Rate limits

  • 50 certificates per week: Unique hostnames per tailnet.
  • 5 duplicate certificates per week: Hostnames across different clusters.

Test with staging

To avoid limits during testing, use the Let's Encrypt staging environment through a ProxyClass:

apiVersion: tailscale.com/v1alpha1
kind: ProxyClass
metadata:
  name: letsencrypt-staging
spec:
  useLetsEncryptStagingEnvironment: true

When using a ProxyGroup, the -0 Pod is always the replica that issues a certificate from Let's Encrypt.

Further exploration