Cloudflare Tunnel lets you expose services running in your cluster to the internet without configuring public IPs, opening firewall ports, or managing TLS certificates.
AI Prompts
Use the AI Assistant (
⌘+J) to build your Cloudflare Tunnel stack automatically.Why Cloudflare Tunnel?
| Traditional Ingress | Cloudflare Tunnel |
|---|---|
| Requires public IP or LoadBalancer | Works behind NAT, no public IP needed |
| Open firewall ports (80, 443) | No inbound ports required |
| Manage TLS certificates yourself | Automatic TLS from Cloudflare |
| DDoS protection costs extra | DDoS protection included |
| Complex DNS configuration | Automatic DNS via Cloudflare |
- Clusters running on-premises or in private networks
- Development and staging environments
- Services that need Cloudflare’s security features
- Teams that want zero-trust access controls
Prerequisites
Before you start:- A Cloudflare account with a domain added
- A cluster imported into Ankra with the agent connected
- The service you want to expose running in your cluster
Step 1: Create a Cloudflare Tunnel
1
Log into Cloudflare Dashboard
Go to dash.cloudflare.com and select your account.
2
Navigate to Zero Trust
Click Zero Trust in the sidebar, then Networks → Tunnels.
3
Create a Tunnel
Click Create a tunnel and select Cloudflared as the connector type.
4
Name Your Tunnel
Give it a descriptive name like
my-cluster-tunnel or prod-services.5
Copy the Tunnel Token
Cloudflare will show you a token. Copy it - you’ll need this for the Kubernetes deployment.The token looks like:
eyJhIjoiNjM...6
Skip the Connector Setup
Don’t install the connector yet. We’ll deploy it via Ankra instead. Click Next.
7
Configure Public Hostname
Add a public hostname for your service:
- Subdomain: e.g.,
apporapi - Domain: Select your Cloudflare domain
- Service:
http://your-service.namespace.svc.cluster.local:port
8
Save the Tunnel
Click Save tunnel. The tunnel will show as “Inactive” until we deploy the connector.
Step 2: Create the Stack in Ankra
1
Open Stack Builder
Navigate to your cluster → Stacks → Create Stack.
2
Name Your Stack
Name it
cloudflare-tunnel or similar.3
Add a Secret Manifest
Click + Add → Manifest and create a Secret for the tunnel token:Replace
YOUR_TUNNEL_TOKEN_HERE with the token from Cloudflare.4
Add a Namespace Manifest
Click + Add → Manifest for the namespace:
5
Add the Cloudflared Deployment
Click + Add → Manifest for the tunnel connector:
6
Connect Dependencies
In the Stack Builder canvas, connect:This ensures resources deploy in the correct order.
Step 3: Deploy and Verify
1
Save and Deploy
Click Save, then Deploy. Watch the deployment in Operations.
2
Check Cloudflare Dashboard
Go back to the Cloudflare Zero Trust dashboard. Your tunnel should now show as Healthy.
3
Test Your Service
Navigate to your configured hostname (e.g.,
https://app.yourdomain.com). Your service should be accessible.Configuring Routes
You configure which services are exposed in the Cloudflare dashboard, not in Kubernetes.Adding a New Route
- Go to Zero Trust → Networks → Tunnels
- Click your tunnel → Configure
- Go to Public Hostname tab
- Click Add a public hostname
- Configure:
- Subdomain: The subdomain to use
- Domain: Your Cloudflare domain
- Service: The internal Kubernetes service URL
Service URL Format
For Kubernetes services, use this format:http://nginx.default.svc.cluster.local:80http://api-server.backend.svc.cluster.local:3000http://grafana.monitoring.svc.cluster.local:3000
Multiple Services
One tunnel can expose multiple services. Add multiple public hostnames in Cloudflare:| Hostname | Service |
|---|---|
app.example.com | http://frontend.default.svc.cluster.local:80 |
api.example.com | http://backend.default.svc.cluster.local:3000 |
grafana.example.com | http://grafana.monitoring.svc.cluster.local:3000 |
High Availability
The example deployment runs 2 replicas for redundancy. For production:Encrypting Secrets with SOPS
If you’re using GitOps to store your Stack configuration, you should encrypt the tunnel token with SOPS to avoid committing secrets in plaintext.Enable SOPS Encryption
1
Initialize SOPS at Organisation Level
Go to Organisation Settings → Encryption and click Initialize Encryption. This generates an AGE key pair for your organisation.
2
Enable SOPS on Your Cluster
Navigate to your cluster → Settings → Encryption and toggle on Enable SOPS Decryption. This deploys the decryption key to ArgoCD.
3
Mark the Token for Encryption
When editing the Secret manifest in the Stack Builder, expand the Encrypted Keys (SOPS) section and add
token as an encrypted key.How It Works
- When you save the Stack, Ankra encrypts the
tokenfield using your organisation’s AGE public key - The encrypted manifest is stored in your Git repository (if GitOps is enabled)
- When ArgoCD deploys the Stack, helm-secrets automatically decrypts the value using the private key stored in the cluster
- Your tunnel token never appears in plaintext in Git
Example Encrypted Manifest
After encryption, the Secret looks like this in Git:ENC[...] value is the encrypted token. The sops metadata block contains the encryption parameters.
Learn more about SOPS encryption in the SOPS Encryption guide.
Access Controls
Cloudflare Tunnel integrates with Cloudflare Access for zero-trust security:- Go to Zero Trust → Access → Applications
- Click Add an application
- Select Self-hosted
- Configure the application URL (your tunnel hostname)
- Add access policies (e.g., require SSO, specific emails, IP ranges)
Troubleshooting
Tunnel Shows as Inactive
Tunnel Shows as Inactive
- Check the cloudflared pods are running:
- Check the logs for errors:
- Verify the token in the secret is correct
502 Bad Gateway
502 Bad Gateway
The tunnel is working but can’t reach the backend service:
- Verify the service URL in Cloudflare is correct
- Check the service exists and has endpoints:
- Test connectivity from cloudflared pod:
Connection Timeouts
Connection Timeouts
- Check if the service is responding slowly
- Increase timeout in Cloudflare tunnel settings
- Verify there are no NetworkPolicies blocking traffic
DNS Not Resolving
DNS Not Resolving
- DNS propagation can take a few minutes
- Verify the hostname is configured in the Cloudflare dashboard
- Check that your domain’s nameservers point to Cloudflare
AI Prompts
Press⌘+J to open the AI Assistant and use these prompts:
Basic Cloudflare Tunnel Stack
Basic Cloudflare Tunnel Stack
Expose an Existing Service
Expose an Existing Service
Production Tunnel Setup
Production Tunnel Setup
Troubleshoot Tunnel Issues
Troubleshoot Tunnel Issues