| name | cloudflare |
| description | Cloudflare Tunnel and Access configuration for exposing K3s services externally. |
Cloudflare
Architecture
- Cloudflare Tunnel: runs as a pod in the cluster, exposes services externally
- Cloudflare Access: wildcard policy on
*.gkcluster.org — all subdomains protected
- Flow: Internet → Cloudflare edge → Tunnel pod → NGINX Ingress → Service
Exposed Services
Services exposed via tunnel: grafana, headlamp, open-webui, oauth2-proxy, argocd, echo, supabase (Studio + API)
Supabase Endpoints
supabase.gkcluster.org — Studio UI (behind OAuth)
supabase-api.gkcluster.org — Kong API gateway (x-brain-key auth, NOT behind OAuth)
Gotchas
- Tunnel hostname config is managed in Cloudflare dashboard — NOT in this repo
- DNS resolution: nodes use local DNS (
192.168.1.1), not Cloudflare DNS
- ws03 had
systemd-resolved overridden to 1.1.1.1 which broke node01.lan resolution
- Fix:
sudo resolvectl dns enp5s0 192.168.1.1
- Adding new services requires both: ingress in repo + tunnel hostname in Cloudflare dashboard
- Cloudflare tunnel sends
http:// redirect_uri — services behind the
tunnel with ssl_redirect: false generate http:// OAuth callbacks. Dex
static clients must list both http:// and https:// redirect URIs.
- Tunnel routes must go through the ingress — route all tunnel hostnames
to
http://ingress-ingress-nginx-controller.ingress-nginx.svc.cluster.local.
Direct-to-service routes (e.g. http://home.home.svc.cluster.local) bypass
the ingress controller and oauth2-proxy entirely, so auth headers like
X-Auth-Request-Email will be empty. Cloudflare Access still authenticates
(using Google identity), but oauth2-proxy features (email headers, sign-out)
won't work.
- Cloudflare Access uses Google identity — not GitHub. If you see a
Google OTP prompt, that's Cloudflare Access. The GitHub auth prompt comes
from oauth2-proxy (after traffic reaches the ingress).
- MCP / non-browser hosts need an Access bypass — services that
speak their own OAuth (open-brain-mcp, thoth's MCP endpoint) or use a
shared-key API (
supabase-api.gkcluster.org) cannot solve Google
SSO. Add a Cloudflare Access Application of type Bypass for that
hostname. Policy order matters: the bypass must evaluate
before the wildcard *.gkcluster.org Access app, otherwise the
wildcard wins and challenges every request. Confirm order in the
dashboard after adding. Reference precedent: brain.gkcluster.org.
Key Files
kubernetes-services/values.yaml — cloudflared toggle and config
kubernetes-services/additions/ingress/ — ingress definitions for tunneled services