Skip to main content

Configuration Guide

This guide covers the essential configuration options for deploying Cloudflared Tunnel using the Helm chart.

Basic Configuration

Image Configuration

image:
repository: cloudflare/cloudflared
tag: "" # Uses chart appVersion by default
pullPolicy: IfNotPresent

Replica Configuration

Choose between DaemonSet and Deployment modes:

replica:
allNodes: true # Use DaemonSet to deploy to all nodes
count: 1 # Number of replicas (used when allNodes: false)
tip

Use allNodes: true for high availability across all cluster nodes, or allNodes: false with count: N for specific replica count.

Update Strategy

Configure how updates are applied:

updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1

Tunnel Configuration

Basic Tunnel Settings

tunnelConfig:
name: "your-tunnel-name"
logLevel: "info" # info, warn, error, fatal, panic
protocol: "auto" # auto, http2, h2mux, quic
retries: 5
connectTimeout: "30s"
gracePeriod: "30s"

Advanced Tunnel Settings

tunnelConfig:
name: "your-tunnel-name"
logLevel: "info"
transportLogLevel: "warn" # debug, info, warn, error, fatal
protocol: "auto"
retries: 5
connectTimeout: "30s"
gracePeriod: "30s"
metricsUpdateFrequency: "5s"
autoUpdateFrequency: "24h"
noAutoUpdate: true
warpRouting: false
info
  • protocol: Choose between auto, http2, h2mux, or quic for connection protocol
  • logLevel: Set logging verbosity for the tunnel
  • transportLogLevel: Set logging verbosity for transport layer
  • warpRouting: Enable Cloudflare WARP routing features

Tunnel Secrets

Configure tunnel credentials and certificates:

tunnelSecrets:
base64EncodedConfigJsonFile: "base64-encoded-credentials-json"
base64EncodedPemFile: "base64-encoded-certificate-pem"
warning

These secrets are required and must be base64-encoded versions of your Cloudflare tunnel files.

Encoding Tunnel Files

Encode your tunnel files using these commands:

# Encode credentials JSON file
base64 -b 0 -i ~/.cloudflared/*.json

# Encode certificate PEM file
base64 -b 0 -i ~/.cloudflared/cert.pem

Ingress Configuration

Basic Ingress Rules

ingress:
- hostname: example.com
service: http://your-service.namespace.svc.cluster.local:80

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

- service: http_status:404

Advanced Ingress Rules

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

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

- path: "\\.(jpg|png|css|js)$"
service: http://static-service.default.svc.cluster.local:80

- service: http_status:404
tip

The last rule with http_status:404 is required to handle unmatched requests.

Resource Management

Resource Limits

resources:
limits:
cpu: "400m"
memory: "128Mi"
requests:
cpu: "100m"
memory: "64Mi"

For production deployments:

resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "200m"
memory: "128Mi"

Security Configuration

Pod Security Context

podSecurityContext:
fsGroup: 65532
fsGroupChangePolicy: "OnRootMismatch"
sysctls:
- name: net.ipv4.ping_group_range
value: "0 2147483647"

Container Security Context

securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_RAW
readOnlyRootFilesystem: true
runAsNonRoot: true
privileged: false
runAsUser: 65532
runAsGroup: 65532
info

The NET_RAW capability is required for Cloudflared to function properly.

Node Selection and Scheduling

Node Selector

nodeSelector:
kubernetes.io/os: linux
node-type: edge

Tolerations

tolerations:
- effect: NoSchedule
operator: Exists

Affinity Rules

affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- cloudflared
topologyKey: kubernetes.io/hostname

Service Account Configuration

serviceAccount:
create: true
automount: true
name: ""
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/cloudflared-role"

Pod Annotations and Labels

Pod Annotations

podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "2000"
prometheus.io/path: "/ready"
backup.kubernetes.io/enabled: "true"

Pod Labels

podLabels:
app.kubernetes.io/component: tunnel
environment: production

Termination Grace Period

terminationGracePeriodSeconds: 30

Complete Example

Here's a complete configuration example for a production deployment:

# Basic deployment
replica:
allNodes: true

# Image configuration
image:
repository: cloudflare/cloudflared
pullPolicy: IfNotPresent

# Update strategy
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1

# Tunnel configuration
tunnelConfig:
name: "production-tunnel"
logLevel: "info"
transportLogLevel: "warn"
protocol: "auto"
retries: 5
connectTimeout: "30s"
gracePeriod: "30s"
metricsUpdateFrequency: "5s"
autoUpdateFrequency: "24h"
noAutoUpdate: true
warpRouting: false

# Tunnel secrets (base64 encoded)
tunnelSecrets:
base64EncodedConfigJsonFile: "your-base64-encoded-credentials"
base64EncodedPemFile: "your-base64-encoded-certificate"

# Ingress rules
ingress:
- hostname: app.example.com
service: http://web-service.default.svc.cluster.local:80
originRequest:
connectTimeout: 10s
disableChunkedEncoding: true

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

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

- service: http_status:404

# Resources
resources:
limits:
cpu: "500m"
memory: "256Mi"
requests:
cpu: "200m"
memory: "128Mi"

# Security
podSecurityContext:
fsGroup: 65532
fsGroupChangePolicy: "OnRootMismatch"
sysctls:
- name: net.ipv4.ping_group_range
value: "0 2147483647"

securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
add:
- NET_RAW
readOnlyRootFilesystem: true
runAsNonRoot: true
privileged: false
runAsUser: 65532
runAsGroup: 65532

# Node selection
nodeSelector:
kubernetes.io/os: linux
node-type: edge

# Tolerations
tolerations:
- effect: NoSchedule
operator: Exists

# Service account
serviceAccount:
create: true
automount: true
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/cloudflared-role"

# Monitoring
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "2000"
prometheus.io/path: "/ready"

# Termination
terminationGracePeriodSeconds: 30

Environment Variables

The chart automatically sets these environment variables:

VariableDescriptionSource
TUNNEL_NAMETunnel nametunnelConfig.name
TUNNEL_PROTOCOLConnection protocoltunnelConfig.protocol
TUNNEL_LOGLEVELLogging leveltunnelConfig.logLevel
TUNNEL_TRANSPORT_LOGLEVELTransport loggingtunnelConfig.transportLogLevel
TUNNEL_RETRIESConnection retriestunnelConfig.retries
TUNNEL_CONNECT_TIMEOUTConnection timeouttunnelConfig.connectTimeout
TUNNEL_GRACE_PERIODGrace periodtunnelConfig.gracePeriod

Next Steps