Skip to main content

Ingress Configuration

This guide covers how to configure ingress rules for Cloudflare Tunnel to route traffic to your Kubernetes services.

Ingress Overview​

Cloudflare Tunnel ingress rules define how traffic is routed from the internet to your internal services. Unlike traditional Kubernetes ingress, tunnel ingress rules are processed by Cloudflared and can route traffic to any service within your cluster.

Basic Ingress Rules​

Simple Hostname Routing​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80

- hostname: api.example.com
service: http://api-service.default.svc.cluster.local:8080

- service: http_status:404
tip

The last rule with http_status:404 is required to handle unmatched requests and should always be included.

Wildcard Subdomain Routing​

ingress:
- hostname: "*.example.com"
service: http://wildcard-service.default.svc.cluster.local:80

- hostname: app.example.com
service: http://app-service.default.svc.cluster.local:3000

- service: http_status:404
info

Wildcard subdomains require a CNAME record for * in your DNS configuration.

Advanced Ingress Rules​

Path-Based Routing​

ingress:
- hostname: example.com
path: "/api/*"
service: http://api-service.default.svc.cluster.local:8080

- hostname: example.com
path: "/admin/*"
service: http://admin-service.default.svc.cluster.local:8080

- hostname: example.com
service: http://web-service.default.svc.cluster.local:80

- service: http_status:404

Static File Routing​

ingress:
- hostname: example.com
path: "\\.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|eot)$"
service: http://static-service.default.svc.cluster.local:80

- hostname: example.com
service: http://web-service.default.svc.cluster.local:80

- service: http_status:404

Multiple Services with Load Balancing​

ingress:
- hostname: example.com
service: http://web-service-1.default.svc.cluster.local:80
originRequest:
loadBalancer:
pool: web-pool

- hostname: example.com
service: http://web-service-2.default.svc.cluster.local:80
originRequest:
loadBalancer:
pool: web-pool

- service: http_status:404

Origin Request Configuration​

Connection Settings​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80
originRequest:
connectTimeout: 10s
readTimeout: 30s
keepAliveConnections: 100
keepAliveTimeout: 90s
disableChunkedEncoding: true
httpHostHeader: "internal.example.com"

TLS Settings​

ingress:
- hostname: example.com
service: https://secure-service.default.svc.cluster.local:443
originRequest:
noTLSVerify: true
caPool: /etc/ssl/certs/ca-certificates.crt
clientTLS:
cert: /etc/ssl/client.crt
key: /etc/ssl/client.key

HTTP Headers​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80
originRequest:
httpHostHeader: "internal.example.com"
noTLSVerify: true
headers:
- name: X-Forwarded-For
value: "{{ .ClientIP }}"
- name: X-Real-IP
value: "{{ .ClientIP }}"
- name: X-Forwarded-Proto
value: "{{ .Protocol }}"

Service Types​

HTTP Services​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80

HTTPS Services​

ingress:
- hostname: example.com
service: https://secure-service.default.svc.cluster.local:443
originRequest:
noTLSVerify: true

TCP Services​

ingress:
- hostname: example.com
service: tcp://database-service.default.svc.cluster.local:5432

Unix Socket Services​

ingress:
- hostname: example.com
service: unix:///var/run/myapp.sock

Error Handling​

Custom Error Responses​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80

- hostname: api.example.com
service: http://api-service.default.svc.cluster.local:8080

# Custom error responses
- service: http_status:404
- service: http_status:500
- service: http_status:503

Fallback Services​

ingress:
- hostname: example.com
service: http://primary-service.default.svc.cluster.local:80

- hostname: example.com
service: http://fallback-service.default.svc.cluster.local:80
originRequest:
connectTimeout: 5s

- service: http_status:404

Load Balancing and High Availability​

Multiple Backend Services​

ingress:
- hostname: example.com
service: http://web-service-1.default.svc.cluster.local:80

- hostname: example.com
service: http://web-service-2.default.svc.cluster.local:80

- hostname: example.com
service: http://web-service-3.default.svc.cluster.local:80

- service: http_status:404

Health Check Configuration​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80
originRequest:
connectTimeout: 10s
readTimeout: 30s
keepAliveConnections: 100
keepAliveTimeout: 90s

Security Configuration​

Access Control​

ingress:
- hostname: admin.example.com
service: http://admin-service.default.svc.cluster.local:8080
originRequest:
headers:
- name: X-API-Key
value: "your-api-key"

IP Filtering​

ingress:
- hostname: internal.example.com
service: http://internal-service.default.svc.cluster.local:80
originRequest:
ipRules:
- prefix: "192.168.1.0/24"
allow: true
- prefix: "10.0.0.0/8"
allow: true
- prefix: "0.0.0.0/0"
allow: false

Monitoring and Logging​

Request Logging​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80
originRequest:
connectTimeout: 10s
readTimeout: 30s

Metrics Collection​

Enable metrics for monitoring:

tunnelConfig:
metricsUpdateFrequency: "5s"
logLevel: "info"
transportLogLevel: "warn"

Complete Examples​

Multi-Service Application​

ingress:
# Web application
- hostname: app.example.com
service: http://web-service.default.svc.cluster.local:80

# API service
- hostname: api.example.com
service: http://api-service.default.svc.cluster.local:8080
originRequest:
connectTimeout: 10s
readTimeout: 30s

# Admin panel
- hostname: admin.example.com
service: http://admin-service.default.svc.cluster.local:8080
originRequest:
headers:
- name: X-API-Key
value: "admin-key"

# Static assets
- hostname: app.example.com
path: "\\.(css|js|png|jpg|ico)$"
service: http://static-service.default.svc.cluster.local:80

# Health check
- hostname: health.example.com
service: http://health-service.default.svc.cluster.local:8080

# Default error response
- service: http_status:404

Microservices Architecture​

ingress:
# Frontend
- hostname: frontend.example.com
service: http://frontend-service.default.svc.cluster.local:3000

# User service
- hostname: users.example.com
service: http://user-service.default.svc.cluster.local:8080

# Product service
- hostname: products.example.com
service: http://product-service.default.svc.cluster.local:8080

# Order service
- hostname: orders.example.com
service: http://order-service.default.svc.cluster.local:8080

# Payment service
- hostname: payments.example.com
service: https://payment-service.default.svc.cluster.local:443
originRequest:
noTLSVerify: true

# Monitoring
- hostname: monitoring.example.com
service: http://monitoring-service.default.svc.cluster.local:9090

# Error handling
- service: http_status:404

Development Environment​

ingress:
# Development app
- hostname: dev.example.com
service: http://dev-service.default.svc.cluster.local:3000

# Development API
- hostname: dev-api.example.com
service: http://dev-api-service.default.svc.cluster.local:8080

# Development database (read-only)
- hostname: dev-db.example.com
service: tcp://dev-db-service.default.svc.cluster.local:5432

# Development tools
- hostname: dev-tools.example.com
service: http://dev-tools-service.default.svc.cluster.local:8080

# Error handling
- service: http_status:404

Best Practices​

1. Always Include Error Handler​

ingress:
# Your service rules here
- service: http_status:404 # Required

2. Use Specific Hostnames​

# Good
- hostname: api.example.com
service: http://api-service.default.svc.cluster.local:8080

# Avoid overly broad wildcards
- hostname: "*.example.com"
service: http://catch-all-service.default.svc.cluster.local:80

3. Configure Timeouts​

ingress:
- hostname: example.com
service: http://web-service.default.svc.cluster.local:80
originRequest:
connectTimeout: 10s
readTimeout: 30s

4. Use Health Checks​

ingress:
- hostname: health.example.com
service: http://health-service.default.svc.cluster.local:8080

5. Secure Sensitive Services​

ingress:
- hostname: admin.example.com
service: http://admin-service.default.svc.cluster.local:8080
originRequest:
headers:
- name: X-API-Key
value: "secure-key"

Troubleshooting​

Common Issues​

  1. Service Not Reachable

    • Verify service name and namespace
    • Check service port
    • Ensure service is running
  2. DNS Resolution Issues

    • Verify DNS records in Cloudflare
    • Check tunnel DNS configuration
  3. Timeout Issues

    • Increase connection and read timeouts
    • Check service health

Debug Commands​

# Check tunnel logs
kubectl logs -f deployment/my-cloudflared

# Test service connectivity
kubectl exec -it <pod-name> -- curl http://service-name.namespace.svc.cluster.local:port

# Check tunnel status
kubectl exec -it <pod-name> -- cloudflared tunnel info my-tunnel

Next Steps​