Skip to main content

Overview

Charts support two approaches for external traffic routing:
  • Traditional Ingress: Mature, widely supported
  • HTTPRoute (Gateway API): Modern, more expressive
Both can be configured through values.yaml and are mutually compatible.

Traditional Ingress

Basic Configuration

ingress:
  enabled: true
  className: nginx  # or traefik, alb, etc.
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix

Complete Example

ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: myapp-tls
      hosts:
        - myapp.example.com

Ingress Class

ingress:
  enabled: true
  className: nginx
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
Common annotations:
  • rewrite-target: URL rewriting
  • ssl-redirect: Force HTTPS
  • rate-limit: Request rate limiting
  • whitelist-source-range: IP whitelisting

TLS Configuration

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: myapp-tls-manual
      hosts:
        - myapp.example.com
Create the secret manually:
kubectl create secret tls myapp-tls-manual \
  --cert=path/to/cert.pem \
  --key=path/to/key.pem

Common Annotations

ingress:
  annotations:
    # Nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    
    # Traefik
    traefik.ingress.kubernetes.io/redirect-entry-point: https
    traefik.ingress.kubernetes.io/redirect-permanent: "true"
ingress:
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
    nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
ingress:
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "10"
    nginx.ingress.kubernetes.io/limit-connections: "5"
ingress:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
  hosts:
    - host: example.com
      paths:
        - path: /api(/|$)(.*)
          pathType: Prefix
ingress:
  annotations:
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"

HTTPRoute (Gateway API)

Basic Configuration

httpRoute:
  enabled: true
  gatewayRef:
    name: envoy-gateway-bundle
    namespace: envoy-gateway-system
  reuseIngressConfiguration: true  # Reuse ingress.hosts

Reusing Ingress Configuration

When reuseIngressConfiguration: true, HTTPRoute reads from ingress.hosts:
ingress:
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix

httpRoute:
  enabled: true
  gatewayRef:
    name: envoy-gateway-bundle
    namespace: envoy-gateway-system
  reuseIngressConfiguration: true
  # Automatically uses myapp.example.com

Standalone HTTPRoute

httpRoute:
  enabled: true
  gatewayRef:
    name: my-gateway
    namespace: gateway-system
  reuseIngressConfiguration: false
  hostnames:
    - myapp.example.com
    - api.example.com

Advanced Routing

httpRoute:
  enabled: true
  gatewayRef:
    name: envoy-gateway-bundle
    namespace: envoy-gateway-system
  reuseIngressConfiguration: false
  hostnames:
    - api.example.com
  extraPaths:
    - matches:
        - path:
            type: PathPrefix
            value: /v2
          headers:
            - name: X-API-Version
              value: "v2"
      backendRefs:
        - name: api-v2
          port: 8080

Gateway API Features

extraPaths:
  # Exact match
  - matches:
      - path:
          type: Exact
          value: /api/v1/users
    backendRefs:
      - name: users-api
        port: 8080
  
  # Prefix match
  - matches:
      - path:
          type: PathPrefix
          value: /api
    backendRefs:
      - name: api-gateway
        port: 8080
  
  # Regular expression (if supported by gateway)
  - matches:
      - path:
          type: RegularExpression
          value: "/api/v[0-9]+/.*"
    backendRefs:
      - name: api-versioned
        port: 8080

Rate Limiting with Gateway API

Example from the Dify chart:
httpRoute:
  enabled: true
  gatewayRef:
    name: envoy-gateway-bundle
    namespace: envoy-gateway-system
  hostnames:
    - api.example.com
  globalRateLimit:
    enabled: true
    rules:
      - clientSelectors:
          - path:
              type: PathPrefix
              value: /v1/
          - headers:
              - name: Authorization
                type: Distinct
        limit:
          requests: 120
          unit: Minute

Real-World Examples

Example 1: Production Web App (Nginx)

nginx-production.yaml
ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://example.com"
    nginx.ingress.kubernetes.io/limit-rps: "100"
  hosts:
    - host: www.example.com
      paths:
        - path: /
          pathType: Prefix
    - host: example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: example-com-tls
      hosts:
        - www.example.com
        - example.com

Example 2: Multi-Component App (Dify)

dify-values.yaml
global:
  host: dify.example.com
  enableTLS: true

ingress:
  enabled: true
  className: nginx
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/proxy-body-size: 100m
  tlsSecretName: dify-tls

# Automatically creates routes to:
# - Frontend (/)  
# - API (/api)
# - Console (/console)

Example 3: Gateway API with Envoy

envoy-gateway.yaml
ingress:
  enabled: false  # Using HTTPRoute instead

httpRoute:
  enabled: true
  gatewayRef:
    name: envoy-gateway
    namespace: envoy-gateway-system
  reuseIngressConfiguration: false
  hostnames:
    - api.example.com
  extraPaths:
    # Public API - rate limited
    - matches:
        - path:
            type: PathPrefix
            value: /v1/public
      backendRefs:
        - name: public-api
          port: 8080
    
    # Authenticated API - requires header
    - matches:
        - path:
            type: PathPrefix
            value: /v1/private
          headers:
            - name: Authorization
              type: RegularExpression
              value: "Bearer .*"
      backendRefs:
        - name: private-api
          port: 8080
    
    # Canary deployment - 90/10 split
    - matches:
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: app-stable
          port: 80
          weight: 90
        - name: app-canary
          port: 80
          weight: 10

Choosing Between Ingress and HTTPRoute

  • You need maximum compatibility
  • Using existing ingress controllers
  • Simple host/path routing is sufficient
  • Team is familiar with Ingress
  • Production stability is critical
Pros:
  • Mature and stable
  • Wide ecosystem support
  • Extensive documentation
  • Battle-tested in production

Troubleshooting

Ingress Not Working

# Check ingress resource
kubectl get ingress
kubectl describe ingress <ingress-name>

# Check ingress controller pods
kubectl get pods -n ingress-nginx
kubectl logs -n ingress-nginx <controller-pod>

# Check service endpoints
kubectl get endpoints <service-name>

# Test from ingress controller
kubectl exec -n ingress-nginx <controller-pod> -- curl http://<service>:<port>

TLS Certificate Issues

# Check certificate
kubectl get certificate
kubectl describe certificate <cert-name>

# Check secret
kubectl get secret <tls-secret-name>
kubectl describe secret <tls-secret-name>

# Check cert-manager logs
kubectl logs -n cert-manager deploy/cert-manager

HTTPRoute Not Working

# Check HTTPRoute resource
kubectl get httproute
kubectl describe httproute <httproute-name>

# Check Gateway
kubectl get gateway -A
kubectl describe gateway <gateway-name> -n <namespace>

# Check Gateway controller
kubectl get pods -n envoy-gateway-system
kubectl logs -n envoy-gateway-system <gateway-pod>

Next Steps

Values Configuration

Learn about values.yaml basics

Customization

Advanced customization techniques

Monitoring

Set up Prometheus monitoring

Chart Reference

Security best practices

Build docs developers (and LLMs) love