Centralized cloudflared tunnel running in-cluster in the ingress namespace, replacing the per-app tunnel pattern. Tunnel name: cirrus. Authenticates via a locally-generated credentials.json (locally-managed tunnel), not a dashboard-issued token.
ingresscloudflared, replicas: 2, hard podAntiAffinity on kubernetes.io/hostname so one pod always lands on each of Citra and RowanmaxSurge: 0, maxUnavailable: 1 (required — with only 2 nodes and hard anti-affinity, the default maxSurge: 1 deadlocks on rollout since a 3rd pod has nowhere to schedule)credentials.json created via cloudflared tunnel login + cloudflared tunnel create homelab-v2 on the Mac (browser OAuth step, not possible headlessly on the Windows nodes), stored as k8s Secret cloudflared-credentials in ingressconfig.yml stored as ConfigMap cloudflared-config in ingress, mounted alongside the credentials Secret as two separate volumeshttp2 via protocol: http2 in config.yml (see Known Issues below)tunnel: <TUNNEL_ID>
credentials-file: /etc/cloudflared/creds/credentials.json
protocol: http2
ingress:
- service: http_status:404
Adding a route means inserting a hostname rule above the catch-all, e.g.:
ingress:
- hostname: health.edisonwang.dev
service: http://yyc-pc-health-ping.apps.svc.cluster.local:8000
- service: http_status:404
DNS for each hostname is created via cloudflared tunnel route dns homelab-v2 <hostname> (auto-creates the CNAME to <TUNNEL-ID>.cfargotunnel.com).
kubectl create configmap cloudflared-config --from-file=config.yml -n ingress -o yaml --dry-run=client | kubectl apply -f -
kubectl rollout restart deployment cloudflared -n ingress
The restart is required — a mounted ConfigMap eventually syncs to the pod filesystem on its own, but cloudflared doesn't reliably watch the file for live changes, so a running pod can keep serving stale rules without it.
QUIC connectivity to the Cloudflare edge fails from both nodes (Failed to dial a quic connection: timeout: no recent network activity), while TCP/HTTP2 connectivity passes cleanly. This is consistent with a known WSL2 mirrored-networking-mode limitation, several Windows/WSL GitHub issues describe Windows periodically dropping outbound UDP for sustained/streaming flows (HTTP3/QUIC/WebTransport) specifically in mirrored mode, with no confirmed fix short of a reboot.