Ingress

Ingress is a Kubernetes resource that provides HTTP and HTTPS routing to Services based on hostnames, paths, and other HTTP attributes. Unlike Services that work at Layer 4 (TCP/UDP), Ingress operates at Layer 7 (HTTP/HTTPS) and provides features like SSL/TLS termination, path-based routing, and host-based routing. Think of Ingress as a smart traffic director—it reads the HTTP request (hostname, path) and routes it to the appropriate backend Service.

What is Ingress?

Ingress exposes HTTP and HTTPS routes from outside the cluster to Services within the cluster. It provides a single entry point for multiple Services, allowing you to route traffic based on the request’s hostname or path. Ingress requires an Ingress Controller to function—the controller watches for Ingress resources and configures a load balancer or reverse proxy accordingly.

graph TB A[Internet] --> B[Ingress Controller<br/>Load Balancer/Reverse Proxy] B --> C{Request Host/Path?} C -->|api.example.com| D[API Service] C -->|www.example.com| E[Web Service] C -->|blog.example.com/blog| F[Blog Service] D --> G[Backend Pods] E --> H[Backend Pods] F --> I[Backend Pods] style B fill:#e8f5e9 style D fill:#fff4e1 style E fill:#fff4e1 style F fill:#fff4e1

Ingress vs Services

Ingress and Services serve different purposes and work together:

graph TB subgraph services[Services - Layer 4] A[TCP/UDP Routing] B[Load Balancing] C[Service Discovery] D[Single IP per Service] end subgraph ingress[Ingress - Layer 7] E[HTTP/HTTPS Routing] F[Host-based Routing] G[Path-based Routing] H[SSL/TLS Termination] I[One IP for Many Services] end J[Internet] --> I I --> A style services fill:#fff4e1 style ingress fill:#e8f5e9

Services (Layer 4):

  • Work with TCP/UDP protocols
  • Route based on IP and port
  • One external IP per Service (with LoadBalancer)
  • Basic load balancing

Ingress (Layer 7):

  • Works with HTTP/HTTPS protocols
  • Routes based on hostname and path
  • One external IP for multiple Services
  • Advanced routing, SSL termination, rewrites

How Ingress Works

Ingress works in two parts:

  1. Ingress Resource - Defines routing rules (what you create)
  2. Ingress Controller - Implements the rules (watches and configures load balancer)
graph LR A[Ingress Resource Created] --> B[Ingress Controller Watches] B --> C[Controller Reads Rules] C --> D[Controller Configures Load Balancer] D --> E[Traffic Routes Based on Rules] style A fill:#e1f5ff style B fill:#fff4e1 style D fill:#e8f5e9 style E fill:#e8f5e9

Ingress Controller

An Ingress Controller is required for Ingress to work. It’s a pod that:

  • Watches for Ingress resources
  • Configures a load balancer or reverse proxy (NGINX, Traefik, etc.)
  • Handles SSL/TLS termination
  • Implements routing rules

Popular Ingress Controllers:

  • NGINX Ingress Controller - Most popular, based on NGINX
  • Traefik - Modern, cloud-native reverse proxy
  • HAProxy - High-performance load balancer
  • Istio Gateway - Part of Istio service mesh
  • Kong - API gateway with plugins
graph TB A[Ingress Resources] --> B[Ingress Controller] B --> C[NGINX] B --> D[Traefik] B --> E[HAProxy] B --> F[Other Controllers] C --> G[Load Balancer Configuration] D --> G E --> G F --> G style B fill:#e8f5e9 style G fill:#fff4e1

Basic Ingress Example

Here’s a simple Ingress that routes traffic to a Service:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  ingressClassName: nginx  # Specifies which controller handles this
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

This Ingress:

  • Routes example.com traffic to web-service
  • Uses the nginx Ingress Controller
  • Matches all paths (/)

Host-Based Routing

Ingress can route traffic based on the HTTP hostname:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: multi-host-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
  - host: www.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
graph TB A[api.example.com] --> B[Ingress] C[www.example.com] --> B B --> D[API Service] B --> E[Web Service] style B fill:#e8f5e9 style D fill:#fff4e1 style E fill:#fff4e1

Path-Based Routing

Ingress can route traffic based on the URL path:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: path-based-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 80
      - path: /blog
        pathType: Prefix
        backend:
          service:
            name: blog-service
            port:
              number: 80
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

Path matching:

  • /api/*api-service
  • /blog/*blog-service
  • /*web-service (catch-all)
graph TB A[example.com/api/users] --> B[Ingress] C[example.com/blog/post] --> B D[example.com/] --> B B --> E[API Service] B --> F[Blog Service] B --> G[Web Service] style B fill:#e8f5e9 style E fill:#fff4e1 style F fill:#fff4e1 style G fill:#fff4e1

TLS/SSL Termination

Ingress can handle SSL/TLS termination:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-ingress
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - example.com
    secretName: example-tls  # Secret containing certificate
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80

The TLS secret contains the certificate and key:

kubectl create secret tls example-tls \
  --cert=path/to/cert.crt \
  --key=path/to/key.key

When to Use Ingress

Use Ingress when:

HTTP/HTTPS traffic - Routing web traffic (HTTP/HTTPS)
Multiple Services - Exposing multiple Services through one IP
Host-based routing - Different hostnames route to different Services
Path-based routing - Different URL paths route to different Services
SSL/TLS termination - Need to handle HTTPS certificates
Cost efficiency - One load balancer for many Services (vs LoadBalancer per Service)
Advanced routing - Need rewrites, redirects, or other HTTP features

Don’t use Ingress when:

  • You need TCP/UDP routing (use LoadBalancer Service)
  • Simple single-service exposure (LoadBalancer might be simpler)
  • Non-HTTP protocols
  • You don’t need advanced routing features

Ingress vs LoadBalancer

graph TB subgraph loadbalancer[LoadBalancer Service] A[One IP per Service] B[TCP/UDP Support] C[Simple Setup] D[Higher Cost] end subgraph ingress[Ingress] E[One IP for Many Services] F[HTTP/HTTPS Only] G[Advanced Routing] H[Lower Cost] end style loadbalancer fill:#fff4e1 style ingress fill:#e8f5e9

LoadBalancer:

  • ✅ Works with any protocol (TCP/UDP)
  • ✅ Simple, no controller needed
  • ❌ One IP per Service (costly)
  • ❌ No HTTP-level routing

Ingress:

  • ✅ One IP for many Services (cost-efficient)
  • ✅ HTTP/HTTPS routing features
  • ✅ SSL/TLS termination
  • ❌ HTTP/HTTPS only
  • ❌ Requires Ingress Controller

Ingress Class

Kubernetes supports multiple Ingress Controllers. The ingressClassName field specifies which controller should handle an Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  ingressClassName: nginx  # Uses NGINX controller
  # ... rules

You can have multiple controllers (e.g., NGINX and Traefik) and route different Ingress resources to different controllers.

Best Practices

  1. Use Ingress for HTTP/HTTPS - Standard approach for web traffic
  2. Choose the right controller - NGINX is most popular, but consider your needs
  3. Use TLS secrets - Store certificates in Kubernetes Secrets
  4. Use pathType correctly - Exact, Prefix, or ImplementationSpecific
  5. Monitor Ingress Controller - Ensure controller is running and healthy
  6. Use annotations - Controller-specific features via annotations
  7. Plan hostnames - Design hostname structure before creating Ingress
  8. Test routing - Verify routing rules work as expected
  9. Use cert-manager - Automate certificate management
  10. Document rules - Keep Ingress rules documented and organized

Troubleshooting

Ingress Not Working

  1. Check Ingress Controller: kubectl get pods -n ingress-nginx (or your controller namespace)
  2. Verify Ingress exists: kubectl get ingress
  3. Check Ingress status: kubectl describe ingress <name>
  4. Verify Service exists: kubectl get service <service-name>
  5. Check Endpoints: kubectl get endpoints <service-name>

Routing Not Working

  1. Verify hostname: Ensure DNS points to Ingress Controller IP
  2. Check path matching: Verify pathType and path are correct
  3. Test Service directly: Verify backend Service works
  4. Check controller logs: kubectl logs -n ingress-nginx <controller-pod>
  5. Review Ingress rules: kubectl get ingress <name> -o yaml

TLS Not Working

  1. Verify secret exists: kubectl get secret <secret-name>
  2. Check secret type: Should be kubernetes.io/tls
  3. Verify certificate: kubectl get secret <secret-name> -o yaml
  4. Check Ingress TLS config: Verify tls section in Ingress
  5. Test certificate: Use openssl or browser to verify

404 Errors

  1. Check path matching: Verify path and pathType are correct
  2. Verify backend Service: Ensure Service exists and has Endpoints
  3. Check pathType: Use Prefix for most cases
  4. Review controller logs: Check for routing errors
  5. Test Service directly: Bypass Ingress to test Service

Topics

See Also