Expose a cluster workload to your tailnet (layer 7)
Last validated:
This guide covers exposing a service running in your Kubernetes cluster to your tailnet with high availability. You use a ProxyGroup and a Kubernetes Ingress resource to create multiple ingress proxies, ensuring your service remains available even if one of the proxies fails.
Prerequisites
- Install the Tailscale Kubernetes Operator.
- Configure the necessary permissions for Ingress.
Create a ProxyGroup
Create a ProxyGroup custom resource to manage a set of Tailscale proxies for your Ingress.
Create a file named ingress-proxygroup.yaml with the following content:
apiVersion: tailscale.com/v1alpha1
kind: ProxyGroup
metadata:
name: ingress-proxies
spec:
type: ingress
replicas: 2
Apply this manifest to your cluster:
kubectl apply -f ingress-proxygroup.yaml
This creates a ProxyGroup named ingress-proxies with two replicas. The operator creates a StatefulSet with 2 replicas in the tailscale namespace.
Deploy a sample application
Deploy an nginx application. This is the workload you expose.
Create a file named nginx-deployment.yaml with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
Apply this manifest to your cluster:
kubectl apply -f nginx-deployment.yaml
Expose the service with an Ingress and ProxyGroup
Expose the nginx-service using a Kubernetes Ingress resource that references your ProxyGroup.
Create a file named nginx-ha-ingress.yaml with the following content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ha-ingress
annotations:
tailscale.com/proxy-group: ingress-proxies
spec:
ingressClassName: tailscale
tls:
- hosts:
- nginx-ha
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
Apply this manifest to your cluster:
kubectl apply -f nginx-ha-ingress.yaml
The key fields in this manifest are:
ingressClassName: tailscale: Instructs the Tailscale operator to manage thisIngress.tailscale.com/proxy-group: ingress-proxies: Instructs the operator to configure the ingress using theingress-proxiesProxyGroup.tls.hosts: Sets the desired MagicDNS name for the Tailscale service that maps to theIngressthrough advertisement on theProxyGroup.
Access your service
The operator configures a Tailscale Service and the proxies to route traffic to your nginx application. You can find the MagicDNS name in the ADDRESS field of the Ingress resource:
kubectl get ingress nginx-ha-ingress
The output displays similar to following:
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ha-ingress tailscale * nginx-ha.tailxxxxx.ts.net 443 1m
After the ADDRESS field is populated with a MagicDNS name, you can access your nginx service from any device on your tailnet by navigating to https://nginx-ha.tailxxxxx.ts.net (full URI found in the ADDRESS field) in your browser.
For more information, refer to the Expose cluster workloads to your tailnet with Ingress.