𝔩𝔢𝔩𝕠𝔭𝔢𝔷
Theme
Connect With Me on LinkedIn Buy Me a Coffee

Homelab

Tailscale High Availability

Enabling High Availability for Tailscale Kubernetes Subnet Router

Overview

Enabling high availability1 for the Tailscale subnet router. With multiple replicas, if one pod fails (TPM issues, node failure, etc.), another takes over automatically within 15 seconds.

Tip:Having trouble? See v0.9.2 for what your setup should look like after completing this article.

Before You Begin

Prerequisites

Configure Connector for HA

Pin subnet router replicas to control plane nodes with anti-affinity to ensure one per node.

ProxyClass

k8s/core/tailscale/connector/proxyclass.yaml:

---
apiVersion: tailscale.com/v1alpha1
kind: ProxyClass
metadata:
  name: control-plane
spec:
  statefulSet:
    pod:
      nodeSelector:
        node-role.kubernetes.io/control-plane: ""
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchLabels:
                  tailscale.com/parent-resource: homelab-subnet
              topologyKey: kubernetes.io/hostname

Connector

Update the Connector2 to use multiple replicas.

k8s/core/tailscale/connector/connector.yaml:

---
apiVersion: tailscale.com/v1alpha1
kind: Connector
metadata:
  name: homelab-subnet
spec:
  replicas: 3
  proxyClass: control-plane
  hostnamePrefix: homelab-subnet
  subnetRouter:
    advertiseRoutes:
      - "192.168.1.30/32" # Control plane node
      - "192.168.1.31/32" # Control plane node
      - "192.168.1.32/32" # Control plane node
      - "192.168.1.40/29" # MetalLB pool .40-.47
      - "192.168.1.48/28" # MetalLB pool .48-.63
      - "192.168.1.64/28" # MetalLB pool .64-.79

Changes from single replica:

FieldBeforeAfter
replicas(default 1)3
proxyClass(not set)control-plane
hostnamehomelab-subnetremoved
hostnamePrefix(not set)homelab-subnet

Apply Changes

Commit Changes

git add k8s/core/tailscale/connector/
git commit -m "feat(tailscale): enable HA with 3 replicas on control plane nodes"
git push

Reconcile Flux

flux reconcile source git flux-system
flux reconcile kustomization sync

Verify Configuration

Pod Distribution

Check pods are distributed across nodes:

kubectl get pods -n tailscale -l tailscale.com/parent-resource=homelab-subnet -o wide

Should show 3 pods, one per control plane node.

Tip:If a pod CrashLoops with TPM_RC_INTEGRITY error, delete its state secret: kubectl delete secret -n tailscale ts-homelab-subnet-<replica>-<id> then delete the pod. Other replicas maintain access.

Tailscale Admin

Check Tailscale Machines:

  • Should see homelab-subnet-0, homelab-subnet-1, homelab-subnet-2
  • All should show subnets under "Approved"
  • Delete the old homelab-subnet device (will show offline)

Test Connectivity

ping 192.168.1.30

Next Steps

For emergency cluster access when all subnet router replicas are down, set up a bastion host.

See: Tailscale Mac Bastion Host

Resources

Footnotes

  1. Tailscale, "Set up high availability," tailscale.com. Accessed: Dec. 21, 2025. [Online]. Available: https://tailscale.com/kb/1115/high-availability

  2. Tailscale, "Deploy exit nodes and subnet routers on Kubernetes," tailscale.com. Accessed: Dec. 21, 2025. [Online]. Available: https://tailscale.com/kb/1441/kubernetes-operator-connector

Previous
Tailscale ACL and Subnet Routes