[ci skip] Add skill: traefik-udp-cross-namespace
Extracted from debugging DNS forwarding through Traefik v3. Documents two non-obvious requirements for custom UDP entrypoints in the Helm chart: expose.default=true (port not added to Service by default) and allowCrossNamespace=true (IngressRouteUDP cross-namespace refs blocked by default). Both issues compound silently.
This commit is contained in:
parent
936607ac4f
commit
f8c25d9c23
1 changed files with 137 additions and 0 deletions
137
.claude/skills/traefik-udp-cross-namespace/SKILL.md
Normal file
137
.claude/skills/traefik-udp-cross-namespace/SKILL.md
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
---
|
||||
name: traefik-udp-cross-namespace
|
||||
description: |
|
||||
Fix Traefik v3 (Helm chart v39+) UDP entrypoints not working for cross-namespace
|
||||
IngressRouteUDP resources. Use when: (1) Traefik pod listens on a UDP port internally
|
||||
but the LoadBalancer service doesn't expose it, (2) IngressRouteUDP logs show
|
||||
"udp service <namespace>/<service> is not in the parent resource namespace" error,
|
||||
(3) DNS or other UDP traffic through Traefik times out despite correct IngressRouteUDP
|
||||
config, (4) Custom entrypoints added to Traefik Helm values don't appear in the
|
||||
Service ports. Requires two fixes: expose the port AND enable cross-namespace CRD refs.
|
||||
author: Claude Code
|
||||
version: 1.0.0
|
||||
date: 2026-02-07
|
||||
---
|
||||
|
||||
# Traefik v3 UDP Entrypoint + Cross-Namespace Routing
|
||||
|
||||
## Problem
|
||||
Adding a custom UDP entrypoint (e.g., DNS on port 53) to Traefik v3 via Helm chart values
|
||||
doesn't work out of the box. Traffic times out even though the Traefik pod listens on the
|
||||
port internally. Two separate issues compound:
|
||||
|
||||
1. The Helm chart defaults `expose` to `false` for custom entrypoints — the port is never
|
||||
added to the LoadBalancer Service
|
||||
2. `allowCrossNamespace` defaults to `false` — IngressRouteUDP in namespace A can't
|
||||
reference a Service in namespace B
|
||||
|
||||
## Context / Trigger Conditions
|
||||
- Traefik Helm chart v39.0.0+ (Traefik v3.x)
|
||||
- Custom UDP entrypoint defined in `ports` values
|
||||
- `IngressRouteUDP` referencing a service in a different namespace
|
||||
- Symptoms:
|
||||
- `kubectl get svc traefik` doesn't show your custom UDP port
|
||||
- UDP traffic to the LoadBalancer IP times out
|
||||
- Traefik logs show: `"udp service <namespace>/<service> is not in the parent resource namespace <traefik-namespace>"`
|
||||
- `netstat -ulnp` inside Traefik pod confirms it IS listening on the port
|
||||
|
||||
## Solution
|
||||
|
||||
### Fix 1: Expose the UDP port on the Service
|
||||
|
||||
In the Helm values, add `expose = { default = true }` to the entrypoint:
|
||||
|
||||
```hcl
|
||||
# Terraform HCL
|
||||
ports = {
|
||||
dns-udp = {
|
||||
port = 5353
|
||||
exposedPort = 53
|
||||
protocol = "UDP"
|
||||
expose = { default = true } # <-- Required for custom entrypoints
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Helm values YAML equivalent
|
||||
ports:
|
||||
dns-udp:
|
||||
port: 5353
|
||||
exposedPort: 53
|
||||
protocol: UDP
|
||||
expose:
|
||||
default: true
|
||||
```
|
||||
|
||||
Note: The built-in `web` and `websecure` entrypoints have `expose.default = true` by
|
||||
default, but custom entrypoints do NOT.
|
||||
|
||||
### Fix 2: Enable cross-namespace CRD references
|
||||
|
||||
In the Helm values, add `allowCrossNamespace = true` to the kubernetesCRD provider:
|
||||
|
||||
```hcl
|
||||
# Terraform HCL
|
||||
providers = {
|
||||
kubernetesCRD = {
|
||||
enabled = true
|
||||
allowCrossNamespace = true # <-- Required for cross-namespace IngressRouteUDP
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Helm values YAML
|
||||
providers:
|
||||
kubernetesCRD:
|
||||
enabled: true
|
||||
allowCrossNamespace: true
|
||||
```
|
||||
|
||||
This is required whenever an `IngressRouteUDP` (or `IngressRouteTCP`, `IngressRoute`)
|
||||
references a Kubernetes Service in a different namespace.
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# 1. Verify the port appears in the Service
|
||||
kubectl get svc -n traefik traefik -o jsonpath='{.spec.ports[*].name}'
|
||||
# Should include your custom entrypoint name (e.g., "dns-udp")
|
||||
|
||||
# 2. Check Traefik logs for cross-namespace errors
|
||||
kubectl logs -n traefik -l app.kubernetes.io/name=traefik | grep "not in the parent resource namespace"
|
||||
# Should return nothing after the fix
|
||||
|
||||
# 3. Test the UDP service
|
||||
dig @<traefik-lb-ip> example.com
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
DNS forwarding through Traefik to Technitium DNS:
|
||||
- IngressRouteUDP in `traefik` namespace routes `dns-udp` entrypoint to
|
||||
`technitium-dns:53` in `technitium` namespace
|
||||
- Without Fix 1: port 53 never exposed on LoadBalancer — traffic can't reach Traefik
|
||||
- Without Fix 2: Traefik rejects the route — logs error every ~60 seconds
|
||||
- With both fixes: DNS queries to LoadBalancer IP:53 → Traefik → Technitium
|
||||
|
||||
## Notes
|
||||
|
||||
1. **Debugging order matters**: Fix 1 (expose) must come first. Without the port on the
|
||||
Service, you can't even test if the routing works. Fix 2 (cross-namespace) errors only
|
||||
appear in Traefik logs, not as user-visible failures.
|
||||
2. **`allowCrossNamespace` is a security consideration**: It allows any IngressRoute CRD
|
||||
to reference services in any namespace. If this is too broad, consider using
|
||||
`TraefikService` middleware or moving the IngressRouteUDP to the target namespace.
|
||||
3. **Rolling update**: Changing `allowCrossNamespace` triggers a Traefik pod restart
|
||||
(new CLI args). Changing `expose` only updates the Service (no pod restart needed).
|
||||
4. **This applies to TCP too**: `IngressRouteTCP` with cross-namespace services needs the
|
||||
same `allowCrossNamespace` setting.
|
||||
|
||||
## References
|
||||
- Traefik Helm chart ports configuration: https://github.com/traefik/traefik-helm-chart
|
||||
- Traefik v3 providers documentation: https://doc.traefik.io/traefik/providers/kubernetes-crd/
|
||||
|
||||
## See also
|
||||
- `traefik-http3-quic` — related Traefik Helm chart configuration skill
|
||||
Loading…
Add table
Add a link
Reference in a new issue