k8s-operator/reconciler/peerrelay: add NET_ADMIN to peer relay pods (#21762)

The relay server force-sets its UDP socket buffer sizes. The kernel
requires the NET_ADMIN capability for this. Without it, tailscaled logs
a warning and uses the kernel defaults. Dogfooding showed lower
throughput and more dropped packets in that state.

This commit adds NET_ADMIN to the tailscaled container in peer relay
StatefulSets. A ProxyClass that sets a security context on the
Tailscale container replaces the default, as for other proxy types.

Fixes #21745

Change-Id: Ic84e243d7e6184afa4d0bb0c38c4be8eb899261b

Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit is contained in:
David Bond authored and GitHub committed 2026-10-14 11:43:53 +01:00
1 parent f61c868527
commit fd1cc09139
2 files changed
+25

No files matched your search

@@ -1228,6 +1228,18 @@ func assertStatefulSet(t *testing.T, fc client.Client, prName string, want *stat
}) {
t.Errorf("expected container to declare TCP port 9002 for the health check, got ports %v", c.Ports)
}
// The relay server needs NET_ADMIN to force-set its UDP socket buffer sizes.
if !hasCapability(c, "NET_ADMIN") {
t.Errorf("expected container to add the NET_ADMIN capability, got security context %+v", c.SecurityContext)
}
}
func hasCapability(c corev1.Container, capability corev1.Capability) bool {
if c.SecurityContext == nil || c.SecurityContext.Capabilities == nil {
return false
}
return slices.Contains(c.SecurityContext.Capabilities.Add, capability)
}
func assertConfigSecrets(t *testing.T, fc client.Client, prName string, want []string) {
@@ -2030,4 +2042,9 @@ func TestReconciler_AppliesProxyClass(t *testing.T) {
if !foundEnv {
t.Errorf("expected TS_DEBUG_FIREWALL_MODE=auto env, container env is %+v", c.Env)
}
// The ProxyClass does not set a security context, so the default NET_ADMIN capability must survive.
if !hasCapability(c, "NET_ADMIN") {
t.Errorf("expected container to keep the NET_ADMIN capability, got security context %+v", c.SecurityContext)
}
}
@@ -84,6 +84,14 @@ func (r *Reconciler) peerRelayStatefulSet(pr *tsapi.PeerRelay, replicas int32, p
},
})
// The relay server force-sets its UDP socket buffer sizes, which requires NET_ADMIN. Without it, tailscaled falls
// back to the kernel defaults and relay throughput suffers. A ProxyClass security context replaces this entirely.
ss.Spec.Template.Spec.Containers[0].SecurityContext = &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_ADMIN"},
},
}
return tailscaled.ApplyProxyClass(ss, pc, managedLabelKeys, nil)
}