cloudflare-tunnel-gateway-controller

module
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 30, 2025 License: BSD-3-Clause

README

Cloudflare Tunnel Gateway Controller

Go Version License Release CI Docs

Kubernetes controller implementing Gateway API for Cloudflare Tunnel.

Enables routing traffic through Cloudflare Tunnel using standard Gateway API resources (Gateway, HTTPRoute, GRPCRoute).

Features

  • Standard Gateway API implementation (GatewayClass, Gateway, HTTPRoute, GRPCRoute)
  • Cross-namespace backend references with ReferenceGrant support
  • 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/GRPCRoute 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/charts/cloudflare-tunnel-gateway-controller \
  --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:

  1. Go to Cloudflare Zero Trust Dashboard
  2. Navigate to Networks > Tunnels
  3. Click Create a tunnel
  4. Choose Cloudflared connector type
  5. 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/charts/cloudflare-tunnel-gateway-controller \
  --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 or GRPCRoute resources referencing the cloudflare-tunnel Gateway. The controller automatically syncs routes to Cloudflare Tunnel configuration with hot reload (no cloudflared restart required).

Supported Gateway Fields

The controller processes Gateway resources but with important limitations due to Cloudflare Tunnel architecture:

Field Supported Notes
spec.gatewayClassName Must match controller's GatewayClass
spec.listeners ⚠️ Accepted but not used for routing
spec.listeners[].name Used for status reporting
spec.listeners[].protocol Ignored; Cloudflare handles TLS
spec.listeners[].port Ignored; Cloudflare uses 443/80
spec.listeners[].hostname Routes must have intersecting hostnames
spec.listeners[].tls Ignored; Cloudflare manages TLS
spec.listeners[].allowedRoutes Namespace (Same/All/Selector) and kind filtering
spec.addresses Ignored; tunnel CNAME set in status
spec.infrastructure Not implemented

Note: Cloudflare Tunnel terminates TLS at Cloudflare edge. The Gateway listeners configuration (ports, protocols, TLS settings) is accepted for compatibility but has no effect on routing. All routing is determined by HTTPRoute/GRPCRoute hostnames and paths.

Supported Route Fields

The controller supports a subset of Gateway API fields that map to Cloudflare Tunnel ingress rules:

HTTPRoute:

Field Supported Notes
spec.hostnames Wildcard * supported
spec.rules[].matches[].path PathPrefix and Exact types
spec.rules[].backendRefs Service name, namespace, port
spec.rules[].backendRefs[].namespace Cross-namespace refs require ReferenceGrant
spec.rules[].matches[].headers Cloudflare limitation
spec.rules[].matches[].queryParams Cloudflare limitation
spec.rules[].matches[].method Cloudflare limitation
spec.rules[].filters Cloudflare limitation
spec.rules[].backendRefs[].weight ⚠️ Highest weight backend used (#45)

GRPCRoute:

Field Supported Notes
spec.hostnames Wildcard * supported
spec.rules[].matches[].method.service Maps to /Service/* path
spec.rules[].matches[].method.method Maps to /Service/Method path
spec.rules[].backendRefs Service name, namespace, port
spec.rules[].backendRefs[].namespace Cross-namespace refs require ReferenceGrant
spec.rules[].matches[].headers Cloudflare limitation
spec.rules[].filters Cloudflare limitation
spec.rules[].backendRefs[].weight ⚠️ Highest weight backend used (#45)

Load Balancing: This controller does not implement traffic splitting between multiple backends. Cloudflare Tunnel accepts only a single service URL per ingress rule. If you need weighted routing or canary deployments, deploy a dedicated load balancer (Traefik, Envoy, Nginx) and point your HTTPRoute to it. See Limitations for details.

See Gateway API documentation for full details 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.

FAQ

Why do I get SSL certificate errors for multi-level subdomains?

Cloudflare's free Universal SSL certificates only cover root and first-level subdomains:

  • example.com, *.example.com
  • app.dev.example.com

For multi-level subdomains, you need Advanced Certificate Manager ($10/month) or a Business/Enterprise plan.

Documentation

Full documentation is available at cf.k8s.lex.la.

Section Description
Getting Started Prerequisites, installation, and quick start
Configuration Controller configuration and Helm values
Gateway API Supported resources, examples, and limitations
Guides AWG sidecar, external-dns, cross-namespace, monitoring
Operations Troubleshooting, metrics, manual installation
Development Development setup, architecture, contributing
Reference CRD reference, Helm chart, security policy

Roadmap

Planned features and improvements:

Issue Description Status
#45 Select backend with highest weight instead of first Planned
#44 Warning logs for partially ignored route configuration Planned
#40 TCPRoute and TLSRoute support (GRPCRoute done in v0.8.0) In Progress
#33 Auto-generate artifacthub.io/changes from git history Planned
#25 Increase unit test coverage for core packages Ongoing

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.

Directories

Path Synopsis
api
v1alpha1
Package v1alpha1 contains API Schema definitions for the cf.k8s.lex.la v1alpha1 API group.
Package v1alpha1 contains API Schema definitions for the cf.k8s.lex.la v1alpha1 API group.
cmd
controller command
internal
config
Package config provides configuration resolution from GatewayClassConfig CRD resources.
Package config provides configuration resolution from GatewayClassConfig CRD resources.
controller
Package controller implements Kubernetes controllers for Gateway API resources.
Package controller implements Kubernetes controllers for Gateway API resources.
dns
Package dns provides utilities for detecting Kubernetes DNS configuration.
Package dns provides utilities for detecting Kubernetes DNS configuration.
helm
Package helm provides Helm SDK integration for managing cloudflared deployment.
Package helm provides Helm SDK integration for managing cloudflared deployment.
ingress
Package ingress provides conversion from Gateway API HTTPRoute resources to Cloudflare Tunnel ingress configuration.
Package ingress provides conversion from Gateway API HTTPRoute resources to Cloudflare Tunnel ingress configuration.
logging
Package logging provides structured logging utilities with context propagation and OpenTelemetry trace integration.
Package logging provides structured logging utilities with context propagation and OpenTelemetry trace integration.
metrics
Package metrics provides Prometheus metrics instrumentation for the controller.
Package metrics provides Prometheus metrics instrumentation for the controller.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL