Cloudflare Tunnel Gateway Controller

Note: The Helm chart is published at cloudflare-tunnel-gateway-controller/chart subpath because Helm CLI doesn't support OCI Image Index with artifactType selection. Once helm/helm#31582 is resolved, the chart will be available at oci://ghcr.io/lexfrei/cloudflare-tunnel-gateway-controller. Available tags: VERSION, MAJOR.MINOR, MAJOR, latest.
Kubernetes controller implementing Gateway API for Cloudflare Tunnel.
Enables routing traffic through Cloudflare Tunnel using standard Gateway API resources (Gateway, HTTPRoute).
Features
- Standard Gateway API implementation (GatewayClass, Gateway, HTTPRoute)
- Hot reload of tunnel configuration (no cloudflared restart required)
- Optional cloudflared lifecycle management via Helm SDK
- Leader election for high availability deployments
- Multi-arch container images (amd64, arm64)
- Signed container images with cosign
Warning: The controller assumes exclusive ownership of the tunnel configuration. It will remove any ingress rules not managed by HTTPRoute resources. Do not use a tunnel that has manually configured routes or is shared with other systems.
Quick Start
# 1. Install Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard-install.yaml
# 2. Install the controller
helm install cloudflare-tunnel-gateway-controller \
oci://ghcr.io/lexfrei/cloudflare-tunnel-gateway-controller/chart \
--namespace cloudflare-tunnel-system \
--create-namespace \
--set config.tunnelID=YOUR_TUNNEL_ID \
--set config.apiToken=YOUR_API_TOKEN
# 3. Create HTTPRoute to expose your service
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app
spec:
parentRefs:
- name: cloudflare-tunnel
namespace: cloudflare-tunnel-system
hostnames:
- app.example.com
rules:
- backendRefs:
- name: my-service
port: 80
EOF
See Installation for detailed setup instructions.
Prerequisites
- Kubernetes cluster with Gateway API CRDs installed
- Cloudflare account with a pre-created Cloudflare Tunnel
- Cloudflare API token with tunnel permissions
Create Cloudflare Tunnel
Before deploying the controller, you must create a Cloudflare Tunnel:
- Go to Cloudflare Zero Trust Dashboard
- Navigate to Networks > Tunnels
- Click Create a tunnel
- Choose Cloudflared connector type
- Name your tunnel and save the Tunnel ID and Tunnel Token
The controller manages tunnel ingress configuration via API. You can either:
- Let the controller deploy cloudflared automatically (default behavior)
- Deploy cloudflared yourself using the tunnel token (
cloudflared.enabled: false in Helm values)
Cloudflare API Token Permissions
Create an API token at Cloudflare API Tokens with the following permissions:
| Scope |
Permission |
Access |
| Account |
Cloudflare Tunnel |
Edit |
Account ID is auto-detected from the API token when not explicitly provided (works if the token has access to a single account).
Installation
Helm is the only supported installation method. It handles CRD installation, RBAC setup, and provides a simple upgrade path.
helm install cloudflare-tunnel-gateway-controller \
oci://ghcr.io/lexfrei/cloudflare-tunnel-gateway-controller/chart \
--namespace cloudflare-tunnel-system \
--create-namespace \
--values values.yaml
See charts/cloudflare-tunnel-gateway-controller/README.md for all configuration options.
For manual installation without Helm, see Manual Installation.
Note: This controller uses cloudflare-tunnel Helm chart under the hood to deploy cloudflared. If you don't need Gateway API integration, you can use that chart directly.
Usage
Create standard Gateway API HTTPRoute resources referencing the cloudflare-tunnel Gateway. The controller automatically syncs routes to Cloudflare Tunnel configuration with hot reload (no cloudflared restart required).
See Gateway API documentation for supported features and examples.
External-DNS Integration
The controller sets status.addresses on the Gateway with the tunnel CNAME (TUNNEL_ID.cfargotunnel.com). If you have external-dns configured with Gateway API source, it will automatically create DNS records for your HTTPRoute hostnames.
All external-dns annotations (TTL, provider-specific settings, etc.) should be placed on HTTPRoute resources, not on Gateway. See the external-dns Gateway API documentation for details.
Documentation
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
Security
For security issues, please see SECURITY.md.
License
BSD 3-Clause License - see LICENSE for details.